Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {-|
- > ```
- Consider a simple model for whether a person has the flu or not. Let F=1
- indicate that a person has the flu and F=0 indicate that they don't have the
- flu. Let C=1 indicate that the person has a cough and C=0 indicate that they
- don't have a cough. Let M=1 indicate that the person has muscle pain and M=0
- indicate that they don't have muscle pain. Assume that C and M are conditionally
- independent given F so that the probability model is
- P(C=c,M=m,F=f)=P(C=c|F=f)P(M=m|F=f)P(F=f).
- Suppose that we ask two different doctors to supply probabilities for this model
- and we obtain the following results:
- Doctor 1:
- P(F=1)=0.4
- P(C=1|F=0)=0.2, P(C=1|F=1)=0.8
- P(M=1|F=0)=0.3, P(M=1|F=1)=0.9
- Doctor 2:
- P(F=1)=0.5
- P(C=1|F=0)=0.1, P(C=1|F=1)=0.7
- P(M=1|F=0)=0.2, P(M=1|F=1)=0.8
- Suppose we also have access to 10 patient records recording both the symptoms
- and whether each patient was diagnosed with flu or not as shown below:
- Patient C M F
- 1 1 0 0
- 2 1 1 1
- 3 1 1 1
- 4 0 1 0
- 5 0 1 1
- 6 1 0 1
- 7 0 0 0
- 8 1 0 0
- 9 0 0 0
- 10 1 1 1
- ```
- -}
- import Html exposing (text)
- {-| There are three different types of events that can happen
- -}
- type EventType = C | M | F
- {-| An event is a fact about what happened with a certain patient.
- -}
- type Event a = Event EventType a
- {-| A patient is a a combination of three events: C, M, and F
- We represent it as a List, instead of a record, so that we have the
- types C M and F represent event types throughout.
- -}
- type alias Patient = List (Event Int)
- {-| Checks if an event happened for a patient.
- -}
- event_happened : Patient -> Event Int -> Bool
- event_happened patient event =
- List.member event patient
- {-| A known probability
- A marginal probability
- P(C=True) = 0.8
- can be written as
- MarginalProb (C True) 0.8
- A Conditional probability
- P(C=True|A=False) = 0.5
- can be written as
- ConditionalProb (C True) (A False) 0.5
- -}
- type EventProb a
- = MarginalProb (Event a) Float
- | ConditionalProb (Event a) (Event a) Float
- {-|
- A combination of statements about the world.
- P(C=c|F=f)P(M=m|F=f)P(F=f)
- -}
- type alias Model a = List (EventProb a)
- type alias Doctor = Model Int
- {-|
- Given some known probabilities about the world,
- return the probability of each of the patients, assuming they are independent
- -}
- likelihood_patients : Doctor -> List Patient -> Float
- likelihood_patients m ps =
- ps
- |> List.map (likelihood_patient m)
- |> List.product
- {-|
- Given some known probabilities about the world,
- return the probability of the patient.
- -}
- likelihood_patient : Doctor -> Patient -> Float
- likelihood_patient model patient =
- let
- happened = event_happened patient
- event_prob event prob = if (happened event) then prob else 1 - prob
- in
- Debug.log ("patient: " ++ (toString patient))
- model
- |> Debug.log "model: "
- -- remove all conditional events where the condition isnt true
- |> List.filter
- (\ep -> case ep of
- MarginalProb _ _ -> True
- ConditionalProb _ given _ -> happened given
- )
- |> Debug.log "filtered: "
- -- give the probability of the event, if it happened
- -- and 1 - probability if it didnt happen
- |> List.map
- (\ep -> case ep of
- MarginalProb event prob -> event_prob event prob
- ConditionalProb event _ prob -> event_prob event prob
- )
- |> Debug.log "mapped: "
- |> List.product
- main : Html.Html
- main =
- let
- doctor1 : Doctor
- doctor1 =
- [ MarginalProb (Event F 1) 0.4
- , ConditionalProb (Event C 1) (Event F 0) 0.2
- , ConditionalProb (Event C 1) (Event F 1) 0.8
- , ConditionalProb (Event M 1) (Event F 0) 0.3
- , ConditionalProb (Event M 1) (Event F 1) 0.9
- ]
- patients : List Patient
- patients =
- [ [1, 0, 0]
- , [1, 1, 1]
- , [1, 1, 1]
- , [0, 1, 0]
- , [0, 1, 1]
- , [1, 0, 1]
- , [0, 0, 0]
- , [1, 0, 0]
- , [0, 0, 0]
- , [1, 1, 1]
- ]
- |> List.map
- (\l -> case l of
- c :: m :: f :: [] ->
- [ Event C c
- , Event M m
- , Event F f
- ]
- _ ->
- Debug.crash ""
- )
- prob_patients_doctor1 = likelihood_patients doctor1 patients
- doctor2 : Doctor
- doctor2 =
- [ MarginalProb (Event F 1) 0.5
- , ConditionalProb (Event C 1) (Event F 0) 0.1
- , ConditionalProb (Event C 1) (Event F 1) 0.7
- , ConditionalProb (Event M 1) (Event F 0) 0.2
- , ConditionalProb (Event M 1) (Event F 1) 0.8
- ]
- prob_patients_doctor2 = likelihood_patients doctor2 patients
- doctorTest =
- [ MarginalProb (Event F 1) 1
- , ConditionalProb (Event C 1) (Event F 0) 1
- , ConditionalProb (Event C 1) (Event F 1) 1
- , ConditionalProb (Event M 1) (Event F 0) 1
- , ConditionalProb (Event M 1) (Event F 1) 1
- ]
- test_prob = likelihood_patients doctorTest [[Event C 1, Event M 1, Event F 1]]
- test_prob_2 = likelihood_patients doctorTest [[Event C 0, Event M 0, Event F 0]]
- in
- text
- ( "doctor1: "
- ++ (toString prob_patients_doctor1)
- ++ " doctor2: "
- ++ (toString prob_patients_doctor2)
- --++ "test1: " ++ (toString test_prob)
- --++ "test2: " ++ (toString test_prob_2)
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement