-
Notifications
You must be signed in to change notification settings - Fork 0
/
Classifiers.py
127 lines (102 loc) · 3.72 KB
/
Classifiers.py
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
import numpy as np
class Classifier():
def __init__(self,
id=None,
skillModel=None,
skillPriorModel=None,
**kwargs):
self._id = id
self._skillModel = skillModel
self._skillPriorModel = skillPriorModel
self._skillPriors = None
self._skills = None
# TODO: Should classifier maintain a list of their annotations for computational efficiency?
def __eq__(self, other):
return self.id == other.id
def __hash__(self):
return hash(self.id)
@property
def id(self):
return self._id
@id.setter
def id(self, id):
self._id = id
@property
def skills(self):
if self._skills is None:
raise RuntimeError(
'Classifier skills have not been computed. Call computeSkills() first.'
)
return self._skills
@property
def skillPriors(self):
if self._skillPriors is None:
raise RuntimeError(
'Classifier skill priors have not been computed. Call computeSkillPriors() first.'
)
return self._skillPriors
@property
def skillModel(self):
return self._skillModel
@skillModel.setter
def skillModel(self, skillModel):
self._skillModel = skillModel
@property
def skillModel(self):
return self._skillModel
@skillModel.setter
def skillModel(self, skillModel):
self._skillModel = skillModel
def computeSkillPriors(self, subjects, initMode, **args):
self._skillPriors = self._skillPriorModel(
subjects, initMode=initMode, **args)
def computeSkills(self, subjects, initMode=False, **args):
if self._skillPriors is None:
self.computeSkillPriors(subjects, initMode=initMode, **args)
# print('self.skillPriors => {}'.format(self.skillPriors))
self._skills = self.skillModel(self, subjects, self.skillPriors,
initMode, **args)
def getSkill(self, trueLabel):
if self.skills is None:
raise RuntimeError(
'Classifier skills have not been computed. Call computeSkills() first.'
)
if trueLabel in self.skills:
return self.skills[trueLabel]
else:
# This can happen if a classifier has never annotated a
# subject with the specified label. Returning 0.5 indicates
# that success and failure are equally likely.
return 0.5
def __str__(self):
return '\n'.join(['-**Classifier**-'] + [
'{} => {}'.format(name[1:], value)
for name, value in vars(self).items()
] + ['-**Classifier**-'])
class Classifiers():
def __init__(self, classifiers=[]):
self._classifiers = [
classifier for classifier in classifiers
if isinstance(classifier, Classifier)
]
@property
def classifiers(self):
return self._classifiers
@classifiers.setter
def classifiers(self, classifiers):
self._classifiers = [
classifier for classifier in classifiers
if isinstance(classifier, Classifier)
]
def items(self):
for classifier in self.classifiers:
yield classifier
def append(self, classifier):
if isinstance(type(classifier), Classifier):
self.classifiers.append(classifier)
else:
raise TypeError(
'The classfier argument must an instance of type {}. Type {} passed.'.
format(type(Classifier), type(classifier)))
def __str__(self):
return '\n'.join(str(classifier) for classifier in self.classifiers)