@@ -114,6 +114,97 @@ def add_or(examples_so_far, h):
114114# ______________________________________________________________________________
115115
116116
117+ def version_space_learning (examples ):
118+ """ [Figure 19.3]
119+ The version space is a list of hypotheses, which in turn are a list
120+ of dictionaries/disjunctions."""
121+ V = all_hypotheses (examples )
122+ for e in examples :
123+ if V :
124+ V = version_space_update (V , e )
125+
126+ return V
127+
128+
129+ def version_space_update (V , e ):
130+ return [h for h in V if is_consistent (e , h )]
131+
132+
133+ def all_hypotheses (examples ):
134+ """Builds a list of all the possible hypotheses"""
135+ values = values_table (examples )
136+ h_powerset = powerset (values .keys ())
137+ hypotheses = []
138+ for s in h_powerset :
139+ hypotheses .extend (build_attr_combinations (s , values ))
140+
141+ hypotheses .extend (build_h_combinations (hypotheses ))
142+
143+ return hypotheses
144+
145+
146+ def values_table (examples ):
147+ """Builds a table with all the possible values for each attribute.
148+ Returns a dictionary with keys the attribute names and values a list
149+ with the possible values for the corresponding attribute."""
150+ values = defaultdict (lambda : [])
151+ for e in examples :
152+ for k , v in e .items ():
153+ if k == 'GOAL' :
154+ continue
155+
156+ mod = '!'
157+ if e ['GOAL' ]:
158+ mod = ''
159+
160+ if mod + v not in values [k ]:
161+ values [k ].append (mod + v )
162+
163+ values = dict (values )
164+ return values
165+
166+
167+ def build_attr_combinations (s , values ):
168+ """Given a set of attributes, builds all the combinations of values.
169+ If the set holds more than one attribute, recursively builds the
170+ combinations."""
171+ if len (s ) == 1 :
172+ # s holds just one attribute, return its list of values
173+ k = values [s [0 ]]
174+ h = [[{s [0 ]: v }] for v in values [s [0 ]]]
175+ return h
176+
177+ h = []
178+ for i , a in enumerate (s ):
179+ rest = build_attr_combinations (s [i + 1 :], values )
180+ for v in values [a ]:
181+ o = {a : v }
182+ for r in rest :
183+ t = o .copy ()
184+ for d in r :
185+ t .update (d )
186+ h .append ([t ])
187+
188+ return h
189+
190+
191+ def build_h_combinations (hypotheses ):
192+ """Given a set of hypotheses, builds and returns all the combinations of the
193+ hypotheses."""
194+ h = []
195+ h_powerset = powerset (range (len (hypotheses )))
196+
197+ for s in h_powerset :
198+ t = []
199+ for i in s :
200+ t .extend (hypotheses [i ])
201+ h .append (t )
202+
203+ return h
204+
205+ # ______________________________________________________________________________
206+
207+
117208def check_all_consistency (examples , h ):
118209 """Check for the consistency of all examples under h"""
119210 for e in examples :
0 commit comments