Skip to content

Commit ee5ef54

Browse files
yuxqiuKD-7
andauthored
refactor: update how Range works (#60)
* refactor: update how `Range` works * docs: fix typos * fix: RTD error --------- Co-authored-by: KD-7 <[email protected]>
1 parent 590b36f commit ee5ef54

16 files changed

+96
-93
lines changed

truelearn/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
# Follows Semantic Versioning 2.0.0
88
# https://semver.org/
9-
# Append '-dev' to version for development versions
9+
# Append '-dev' to a version for development versions
1010
__version__ = "1.0.0" + "-dev"

truelearn/_constraint.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Callable, List, Optional
1+
from typing import Any, Callable, Optional
22

33
from truelearn.base import BaseClassifier
44
from truelearn.errors import TrueLearnTypeError, TrueLearnValueError
@@ -72,7 +72,7 @@ def __init__(self, *value_constraints: Any, vtype: type = object):
7272
vtype:
7373
The type of the given values. Defaults to object.
7474
This is typically used if the type constraint of the parameter
75-
supports multuple types, and you only want to check the value
75+
supports multiple types, and you only want to check the value
7676
for one of the types listed in the type constraint.
7777
"""
7878
self.vtype = vtype
@@ -167,16 +167,16 @@ class Range:
167167

168168
def __init__(
169169
self,
170-
gt: Optional[List] = None,
171-
ge: Optional[List] = None,
172-
le: Optional[List] = None,
173-
lt: Optional[List] = None,
170+
gt: Optional[float] = None,
171+
ge: Optional[float] = None,
172+
le: Optional[float] = None,
173+
lt: Optional[float] = None,
174174
):
175175
"""Init a Range object."""
176-
self.greater = gt or []
177-
self.greater_or_equal = ge or []
178-
self.less_or_equal = le or []
179-
self.less = lt or []
176+
self.greater = gt
177+
self.greater_or_equal = ge
178+
self.less_or_equal = le
179+
self.less = lt
180180

181181
def __repr__(self) -> str:
182182
"""Get a description of the range object.
@@ -190,7 +190,7 @@ def __repr__(self) -> str:
190190
symbols,
191191
[self.greater_or_equal, self.greater, self.less_or_equal, self.less],
192192
):
193-
if not val:
193+
if val is None:
194194
continue
195195
fmt_strs.append(f"{symbol}{val}")
196196
return f"Range({', '.join(fmt_strs)})"
@@ -206,8 +206,8 @@ def __eq__(self, other):
206206
Whether the value is within the range.
207207
"""
208208
return (
209-
all(other > num for num in self.greater)
210-
and all(other >= num for num in self.greater_or_equal)
211-
and all(other <= num for num in self.less_or_equal)
212-
and all(other < num for num in self.less)
209+
(self.greater is None or other > self.greater)
210+
and (self.greater_or_equal is None or other >= self.greater_or_equal)
211+
and (self.less_or_equal is None or other <= self.less_or_equal)
212+
and (self.less is None or other < self.less)
213213
)

truelearn/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def get_params(self, deep: bool = True) -> Dict[str, Any]:
7171
Args:
7272
deep:
7373
If True, will return the parameters for this Classifier and
74-
contained sub-objects that inherits BaseClassifier class.
74+
contained sub-objects that inherit BaseClassifier class.
7575
7676
Returns:
7777
A dict mapping variable names to the corresponding objects.
@@ -113,9 +113,9 @@ def set_params(self, **args) -> Self:
113113
114114
Raises:
115115
TrueLearnTypeError:
116-
Types of parameters does not satisfy their constraints.
116+
Types of parameters do not satisfy their constraints.
117117
TrueLearnValueError:
118-
Values of parameters does not satisfy their constraints.
118+
Values of parameters do not satisfy their constraints.
119119
InvalidArgumentError:
120120
If the given argument name is not in the class.
121121
"""
@@ -175,9 +175,9 @@ def _validate_params(self) -> None:
175175
176176
Raises:
177177
TrueLearnTypeError:
178-
Types of parameters does not satisfy their constraints.
178+
Types of parameters do not satisfy their constraints.
179179
TrueLearnValueError:
180-
Values of parameters does not satisfy their constraints.
180+
Values of parameters do not satisfy their constraints.
181181
"""
182182
for (
183183
param_name,

truelearn/datasets/_peek.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def __call__(
8686

8787

8888
def __sanity_check(train_limit: Optional[int], test_limit: Optional[int]):
89-
"""Check if train_limit and test_limit is valid.
89+
"""Check if train_limit and test_limit are valid.
9090
9191
Args:
9292
train_limit:
@@ -211,7 +211,7 @@ def __restructure_data(
211211
212212
This function extracts the time, session (learner_id),
213213
topics, and label from the data, and constructs the appropriate
214-
the model for these data.
214+
model for this data.
215215
216216
Args:
217217
filepath:

truelearn/learning/_base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ class InterestNoveltyKnowledgeBaseClassifier(BaseClassifier):
149149
_parameter_constraints: Dict[str, Any] = {
150150
**BaseClassifier._parameter_constraints,
151151
"learner_model": TypeConstraint(LearnerModel),
152-
"threshold": [TypeConstraint(float), ValueConstraint(Range(ge=[0], le=[1]))],
152+
"threshold": [TypeConstraint(float), ValueConstraint(Range(ge=0, le=1))],
153153
"init_skill": TypeConstraint(float),
154154
"def_var": [
155155
TypeConstraint(float),
156-
ValueConstraint(Range(gt=[0])),
156+
ValueConstraint(Range(gt=0)),
157157
],
158158
"tau": TypeConstraint(float),
159159
"beta": TypeConstraint(float),
@@ -162,11 +162,11 @@ class InterestNoveltyKnowledgeBaseClassifier(BaseClassifier):
162162
"draw_proba_static": [
163163
TypeConstraint(float, type(None)),
164164
FuncConstraint(draw_proba_static_constraint),
165-
ValueConstraint(Range(ge=[0], le=[1]), vtype=float),
165+
ValueConstraint(Range(ge=0, le=1), vtype=float),
166166
],
167167
"draw_proba_factor": [
168168
TypeConstraint(float),
169-
ValueConstraint(Range(ge=[0])),
169+
ValueConstraint(Range(ge=0)),
170170
],
171171
}
172172

truelearn/learning/_engage_classifier.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77

88
class EngageClassifier(BaseClassifier):
9-
"""A Classifier that always makes positive prediction.
9+
"""A Classifier that always makes a positive prediction.
1010
1111
Examples:
1212
>>> from truelearn.learning import EngageClassifier
1313
>>> from truelearn.models import EventModel
1414
>>> engage = EngageClassifier()
1515
>>> engage
1616
EngageClassifier()
17-
>>> # prepare event model with empty knowledge
17+
>>> # prepare an event model with empty knowledge
1818
>>> event = EventModel()
1919
>>> engage.fit(event, False)
2020
EngageClassifier()

truelearn/learning/_ink_classifier.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class INKClassifier(BaseClassifier):
1818
During the training process, the meta-classifier individually trains
1919
the KnowledgeClassifier and the InterestClassifier. After that, the
2020
meta-classifier trains a set of weights by again using the ideas of team matching.
21-
One team consists of the weights of the knowledge, interest and bias and
21+
One team consists of the weights of the knowledge, interest and bias, and
2222
the other team consists of the threshold. Then, the meta-classifier
2323
uses the given label to adjust the weights accordingly.
2424
@@ -39,7 +39,7 @@ class INKClassifier(BaseClassifier):
3939
>>> meta_weights = LearnerMetaWeights(novelty_weights=weights)
4040
>>> ink_classifier = INKClassifier(learner_meta_weights=meta_weights)
4141
>>>
42-
>>> # prepare event model
42+
>>> # prepare an event model
4343
>>> knowledges = [
4444
... Knowledge({1: KnowledgeComponent(mean=0.15, variance=1e-9)}),
4545
... Knowledge({
@@ -115,15 +115,15 @@ def __init__(
115115
The dynamic factor of learner's learning process.
116116
It's used to avoid the halting of the learning process.
117117
greedy:
118-
A bool indicating whether the meta-learning should
118+
A bool indicating whether meta-learning should
119119
take the greedy approach. In the greedy approach,
120120
only incorrect predictions lead to the update of the weights.
121121
122122
Raises:
123123
TrueLearnTypeError:
124-
Types of parameters does not satisfy their constraints.
124+
Types of parameters do not satisfy their constraints.
125125
TrueLearnValueError:
126-
Values of parameters does not satisfy their constraints.
126+
Values of parameters do not satisfy their constraints.
127127
"""
128128
self._novelty_classifier = novelty_classifier or NoveltyClassifier()
129129
self._interest_classifier = interest_classifier or InterestClassifier()
@@ -219,12 +219,12 @@ def __update_weights(
219219
The predicted probability of the learner's engagement by using
220220
InterestClassifier.
221221
pred_actual:
222-
Whether the learner actually engage in the given event. This value is
222+
Whether the learner actually engages in the given event. This value is
223223
either 0 or 1.
224224
"""
225225
cur_pred = self.predict(x)
226226

227-
# if prediction is correct and greedy, don't train
227+
# if the prediction is correct and greedy, don't train
228228
if self._greedy and cur_pred == pred_actual:
229229
return
230230

@@ -251,7 +251,7 @@ def __update_weights(
251251
),
252252
)
253253

254-
if pred_actual: # weights need to be larger than threshold
254+
if pred_actual: # weights need to be larger than a threshold
255255
new_team_experts, _ = env.rate(
256256
[team_experts, team_threshold],
257257
weights=[(pred_novelty, pred_interest, 1), (1,)],

truelearn/learning/_interest_classifier.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class InterestClassifier(InterestNoveltyKnowledgeBaseClassifier):
2626
2727
During the training process, the classifier uses the idea of game matching
2828
established in TrueSkill. It represents the learning process as a game of two teams.
29-
One team consists of all the knowledge components from the learnable unit and
30-
the other consist of all the corresponding knowledge components from the learner.
29+
One team consists of all the knowledge components from the learnable unit, and
30+
the other consists of all the corresponding knowledge components from the learner.
3131
Then, the classifier uses the given label to update the knowledge components of
3232
the learner.
3333
@@ -37,7 +37,7 @@ class InterestClassifier(InterestNoveltyKnowledgeBaseClassifier):
3737
the learner wins the game.
3838
3939
During the prediction process, the classifier uses cumulative density function
40-
of normal distribution to calculate the probability that the learner engage in
40+
of normal distribution to calculate the probability that the learner engages in
4141
the learning event. It calculates the probability of getting x in a
4242
Normal Distribution N(0, std) where x is the difference between
4343
the learner's skill (mean) and the learnable unit's skill (mean) and
@@ -52,7 +52,7 @@ class InterestClassifier(InterestNoveltyKnowledgeBaseClassifier):
5252
>>> interest_classifier = InterestClassifier()
5353
>>> interest_classifier
5454
InterestClassifier()
55-
>>> # prepare event model
55+
>>> # prepare an event model
5656
>>> knowledges = [
5757
... Knowledge({1: KnowledgeComponent(mean=0.57, variance=1e-9)}),
5858
... Knowledge({
@@ -90,7 +90,7 @@ class InterestClassifier(InterestNoveltyKnowledgeBaseClassifier):
9090
"decay_func_type": ValueConstraint("short", "long"),
9191
"decay_func_factor": [
9292
TypeConstraint(float),
93-
ValueConstraint(Range(ge=[0])),
93+
ValueConstraint(Range(ge=0)),
9494
],
9595
}
9696

@@ -121,11 +121,11 @@ def __init__(
121121
init_skill:
122122
The initial mean of the learner's knowledge component.
123123
It will be used when the learner interacts with knowledge components
124-
at its first time.
124+
for the first time.
125125
def_var:
126126
The initial variance (>0) of the learner's knowledge component.
127127
It will be used when the learner interacts with knowledge components
128-
at its first time.
128+
for the first time.
129129
beta:
130130
The distance which guarantees about 76% chance of winning.
131131
The recommended value is sqrt(def_var) / 2.
@@ -150,13 +150,13 @@ def __init__(
150150
decay_func_factor:
151151
A factor (>=0) that will be used in both short and long
152152
interest decay function. Defaults to 0, which disables
153-
the interest decay function .
153+
the interest decay function.
154154
155155
Raises:
156156
TrueLearnTypeError:
157-
Types of parameters does not satisfy their constraints.
157+
Types of parameters do not satisfy their constraints.
158158
TrueLearnValueError:
159-
Values of parameters does not satisfy their constraints.
159+
Values of parameters do not satisfy their constraints.
160160
"""
161161
super().__init__(
162162
learner_model=learner_model,
@@ -165,7 +165,7 @@ def __init__(
165165
def_var=def_var,
166166
tau=tau,
167167
beta=beta,
168-
# learner always wins in interest classifier
168+
# learner always wins in interest classifier,
169169
# hence we should always update regardless of the actual label
170170
# positive_only should be disabled to ensure the update method
171171
# is always called
@@ -219,7 +219,7 @@ def _generate_ratings(
219219
event_time:
220220
An optional float representing the event time.
221221
_y:
222-
A bool indicating whether the learner engage in
222+
A bool indicating whether the learner engages in
223223
the learning event.
224224
225225
Returns:

truelearn/learning/_knowledge_classifier.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ class KnowledgeClassifier(InterestNoveltyKnowledgeBaseClassifier):
1616
1717
During the training process, the classifier uses the idea of game matching
1818
established in TrueSkill. It represents the learning process as a game of two teams.
19-
One team consists of all the knowledge components from the learnable unit and
20-
the other consist of all the corresponding knowledge components from the learner.
19+
One team consists of all the knowledge components from the learnable unit, and
20+
the other consists of all the corresponding knowledge components from the learner.
2121
Then, the classifier uses the given label to update the knowledge components
2222
of the learner.
2323
@@ -27,7 +27,7 @@ class KnowledgeClassifier(InterestNoveltyKnowledgeBaseClassifier):
2727
means that the learner wins the game.
2828
2929
During the prediction process, the classifier uses cumulative density function of
30-
normal distribution to calculate the probability that the learner engage
30+
normal distribution to calculate the probability that the learner engages
3131
in the learning event. It calculates the probability of getting x in a
3232
Normal Distribution N(0, std) where x is the difference between
3333
the learner's skill (mean) and the learnable unit's skill (mean) and
@@ -42,7 +42,7 @@ class KnowledgeClassifier(InterestNoveltyKnowledgeBaseClassifier):
4242
>>> knowledge_classifier = KnowledgeClassifier()
4343
>>> knowledge_classifier
4444
KnowledgeClassifier()
45-
>>> # prepare event model
45+
>>> # prepare an event model
4646
>>> knowledges = [
4747
... Knowledge({1: KnowledgeComponent(mean=0.57, variance=1e-9)}),
4848
... Knowledge({
@@ -101,11 +101,11 @@ def __init__(
101101
init_skill:
102102
The initial mean of the learner's knowledge component.
103103
It will be used when the learner interacts with knowledge components
104-
at its first time.
104+
for the first time.
105105
def_var:
106106
The initial variance (>0) of the learner's knowledge component.
107107
It will be used when the learner interacts with knowledge components
108-
at its first time.
108+
for the first time.
109109
beta:
110110
The distance which guarantees about 76% chance of winning.
111111
The recommended value is sqrt(def_var) / 2.
@@ -130,13 +130,13 @@ def __init__(
130130
131131
Raises:
132132
TrueLearnTypeError:
133-
Types of parameters does not satisfy their constraints.
133+
Types of parameters do not satisfy their constraints.
134134
TrueLearnValueError:
135-
Values of parameters does not satisfy their constraints.
135+
Values of parameters do not satisfy their constraints.
136136
"""
137137
# the knowledge classifier doesn't rely on the draw probability
138-
# it utilizes different assumptions
139-
# so, we set draw probability to a very small value to avoid its impact
138+
# it utilises different assumptions, so
139+
# we set draw probability to a very small value to avoid its impact
140140
super().__init__(
141141
learner_model=learner_model,
142142
threshold=threshold,

0 commit comments

Comments
 (0)