Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3e33cd7

Browse files
antmarakisnorvig
authored andcommitted
Knowledge: Version-Space Learning (aimacode#596)
* add version-space learner + small fix * add test for version-space learner + trivial example * Update README.md
1 parent 0db7063 commit 3e33cd7

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and
109109
| 18.24 | Back-Prop-Learning | `BackPropagationLearner` | [`learning.py`][learning] |
110110
| 18.34 | AdaBoost | `AdaBoost` | [`learning.py`][learning] |
111111
| 19.2 | Current-Best-Learning | `current_best_learning` | [`knowledge.py`](knowledge.py) |
112-
| 19.3 | Version-Space-Learning | |
112+
| 19.3 | Version-Space-Learning | `version_space_learning` | [`knowledge.py`](knowledge.py) |
113113
| 19.8 | Minimal-Consistent-Det | |
114114
| 19.12 | FOIL | |
115115
| 21.2 | Passive-ADP-Agent | `PassiveADPAgent` | [`rl.py`][rl] |

knowledge.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
117208
def check_all_consistency(examples, h):
118209
"""Check for the consistency of all examples under h"""
119210
for e in examples:

tests/test_knowledge.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,37 @@ def test_current_best_learning():
2323

2424
assert values == [True, True, True, False, False, False, True]
2525

26+
examples = trivial
27+
initial_h = [{'Pizza': 'Yes'}]
28+
h = current_best_learning(examples, initial_h)
29+
values = []
30+
for e in examples:
31+
values.append(guess_value(e, h))
32+
33+
assert values == [True, True, False]
34+
35+
36+
def test_version_space_learning():
37+
V = version_space_learning(trivial)
38+
results = []
39+
for e in trivial:
40+
guess = False
41+
for h in V:
42+
if guess_value(e, h):
43+
guess = True
44+
break
45+
46+
results.append(guess)
47+
48+
assert results == [True, True, False]
49+
assert [{'Pizza': 'Yes'}] in V
50+
51+
52+
trivial = [
53+
{'Pizza': 'Yes', 'Soda': 'No', 'GOAL': True},
54+
{'Pizza': 'Yes', 'Soda': 'Yes', 'GOAL': True},
55+
{'Pizza': 'No', 'Soda': 'No', 'GOAL': False}
56+
]
2657

2758
animals_umbrellas = [
2859
{'Species': 'Cat', 'Rain': 'Yes', 'Coat': 'No', 'GOAL': True},

0 commit comments

Comments
 (0)