-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMondrianExample.hs
211 lines (190 loc) · 6.57 KB
/
MondrianExample.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
{-# LANGUAGE BangPatterns #-}
module MondrianExample where
import LazyPPL
import LazyPPL.Distributions
import LazyPPL.Distributions.Mondrian
import Helpers
import Graphics.Matplotlib
import Data.Map (Map,empty,lookup,insert,size,keys,findWithDefault,fromList,(!))
import qualified Data.List
import System.IO.Unsafe
-- | __Mondrian Process examples:__
mond :: Prob (Mondrian Double)
mond = randomMondrian uniform 5 [(0, 1), (0, 1)]
mond1 :: Mondrian Double
mond1 = fst $ head $ unsafePerformIO $ mh 0.2 (sample mond)
plotMond :: Matplotlib
plotMond = plotMondrian2D mond1
paintingPietMondrian1921 :: Mondrian Double
paintingPietMondrian1921 =
let red = 0.9
yellow = 0.2
blue = 0.5
gray = 0.3
black = 0.7
in mondrianFromCuts
[(0, 1), (0, 1)]
cutTree
( fromList
[ ([(0.9, 1), (0, 0.3)], red),
([(0, 0.2), (0, 0.3)], yellow),
([(0.7, 0.9), (0.05, 0.3)], blue),
([(0.4, 0.7), (0.05, 0.2)], black),
([(0.2, 0.7), (0.4, 0.85)], red),
([(0.7, 0.9), (0.85, 1)], yellow),
([(0.7, 0.9), (0.6, 0.85)], yellow),
([(0.2, 0.4), (0.3, 0.4)], black)
]
)
gray
where
cutTree =
Node
(0, 0.9)
( Node
(1, 0.3)
( Node
(0, 0.2)
Leaf
( Node
(0, 0.4)
(Node (1, 0.2) Leaf Leaf)
( Node
(1, 0.05)
Leaf
( Node
(0, 0.7)
(Node (1, 0.2) Leaf Leaf)
Leaf
)
)
)
)
( Node
(1, 0.85)
( Node
(0, 0.2)
Leaf
( Node
(0, 0.7)
( Node
(1, 0.4)
(Node (0, 0.4) Leaf Leaf)
Leaf
)
( Node
(1, 0.6)
( Node
(1, 0.4)
Leaf
(Node (0, 0.8) Leaf Leaf)
)
Leaf
)
)
)
( Node
(0, 0.3)
Leaf
(Node (0, 0.7) Leaf Leaf)
)
)
)
(Node (1, 0.3) Leaf Leaf)
plotPietMondrian :: Matplotlib
plotPietMondrian = plotMondrian2D paintingPietMondrian1921
datasetMapRelations :: IO [Map (Double, Double) Bool]
datasetMapRelations = do
rels' <- mh 0.2 $ sample
$ sampleMapRelationFromMondrian2D paintingPietMondrian1921 20
let rels = map fst $ take 100 $ every 10 rels'
return rels
-- plotPietPlusRelation :: Matplotlib
-- plotPietPlusRelation = plotMapRelation plotPietMondrian (head $ unsafePerformIO datasetMapRelations)
datasetMatrixRelations :: IO [Matrix]
datasetMatrixRelations = do
rels' <- mh 0.2 $ sample
$ sampleMatrixRelationFromMondrian2D paintingPietMondrian1921
let rels = map fst $ take 100 $ every 10 rels'
return rels
-- | Statistical model 1: infers the hyperparameters of a Mondrian by observing
-- Map relations generated from it.
inferMondrianMap ::
Foldable t => t (Map (Double, Double) Bool) ->
Prob Double -> Double -> [(Double, Double)] ->
Meas (Mondrian Double)
inferMondrianMap dataset base budget intervals = do
mondrian <- sample $ randomMondrian base budget intervals
let scoreRel rel =
mapM
(\(r, c) -> score $ likelihoodFromMondrian2D mondrian r c (rel ! (r, c)))
(keys rel)
mapM_ scoreRel dataset
return mondrian
-- | Statistical model 2: infers the hyperparameters of a Mondrian by observing
-- Boolean matrices (relations) generated from it.
inferMondrianMatrix :: Foldable t => Int -> t Matrix
-> Prob Double -> Double -> [(Double, Double)]
-> Meas (Mondrian Double)
inferMondrianMatrix size dataset base budget intervals = do
mondrian <- sample $ randomMondrian base budget intervals
rs <- sample $ iid uniform
cs <- sample $ iid uniform
let xrs = zip rs [0 .. size]
let ycs = zip cs [0 .. size]
let scoreRel (Matrix rel) =
mapM (\(x, r) ->
mapM (\(y, c) -> score
(likelihoodFromMondrian2D mondrian x y (rel !! r !! c))
) ycs) xrs
mapM_ scoreRel dataset
return mondrian
mhInferenceMap :: IO Matplotlib
mhInferenceMap = do
dataset <- datasetMapRelations
mws' <- mh 0.2 $ inferMondrianMap dataset uniform 3 [(0, 1), (0, 1)]
mws <- takeWithProgress 5000 $ every 100 $ drop 100 mws'
let maxw = maximum $ map snd mws
let (Just m) = Data.List.lookup maxw $ map (\(m, w) -> (w, m)) mws
return $ plotMondrian2D m
mhInferenceMatrix :: Int -> IO Matplotlib
mhInferenceMatrix size = do
dataset <- datasetMatrixRelations
mws' <- mh (1/40) $ inferMondrianMatrix size dataset uniform 3 [(0, 1), (0, 1)]
mws <- takeWithProgress 5000 $ every 1000 $ drop 1000 mws'
let maxw = maximum $ map snd mws
let (Just m) = Data.List.lookup maxw $ map (\(m, w) -> (w, m)) mws
return $ plotMondrian2D m
-- mh1Inference :: IO Matplotlib
-- mh1Inference = do
-- dataset <- datasetRelations
-- mws' <- mh1 $ inferMondrian dataset uniform 4 [(0, 1), (0, 1)]
-- let mws = take 500 $ every 1000 $ drop 10000 mws'
-- let maxw = maximum $ map snd mws
-- let (Just m) = Data.List.lookup maxw $ map (\(m, w) -> (w, m)) mws
-- return $ plotMondrian2D m
lwisInference :: IO Matplotlib
lwisInference = do
dataset <- datasetMapRelations
mws' <- weightedsamples $ inferMondrianMap dataset uniform 4 [(0, 1), (0, 1)]
let mws = take 1000 mws'
let maxw = maximum $ map snd mws
let (Just m) = Data.List.lookup maxw $ map (\(m, w) -> (w, m)) mws
return $ plotMondrian2D m
mhResultMap :: Matplotlib
mhResultMap = unsafePerformIO mhInferenceMap
main :: IO ()
main = do
putStrLn "Plotting..."
-- -- Map relations inference
-- dataRel <- datasetMapRelations
-- file "pietMondrian-plus-relation.svg" $ plotMapRelation plotPietMondrian $ head dataRel
-- testInf <- mhInferenceMap
-- -- testInf <- lwisInference
-- file "mondrian-relation-map.svg" testInf
-- Matrix relations inference
dataRel <- datasetMatrixRelations
file "pietMondrian.svg" plotPietMondrian
testInf <- mhInferenceMatrix 20
file "mondrian-relation-matrix.svg" testInf
putStrLn "Done."