1
2
3
4
5
6 """ code for dealing with Bayesian composite models
7
8 For a model to be useable here, it should support the following API:
9
10 - _ClassifyExample(example)_, returns a classification
11
12 Other compatibility notes:
13
14 1) To use _Composite.Grow_ there must be some kind of builder
15 functionality which returns a 2-tuple containing (model,percent accuracy).
16
17 2) The models should be pickleable
18
19 3) It would be very happy if the models support the __cmp__ method so that
20 membership tests used to make sure models are unique work.
21
22
23
24 """
25 from __future__ import print_function
26
27 import numpy
28
29 from rdkit.ML.Composite import Composite
30
31
33 """a composite model using Bayesian statistics in the Decision Proxy
34
35
36 **Notes**
37
38 - typical usage:
39
40 1) grow the composite with AddModel until happy with it
41
42 2) call AverageErrors to calculate the average error values
43
44 3) call SortModels to put things in order by either error or count
45
46 4) call Train to update the Bayesian stats.
47
48 """
49
50 - def Train(self, data, verbose=0):
51
52 nModels = len(self)
53 nResults = self.nPossibleVals[-1]
54 self.resultProbs = numpy.zeros(nResults, numpy.float)
55 self.condProbs = [None] * nModels
56
57 for i in range(nModels):
58 self.condProbs[i] = numpy.zeros((nResults, nResults), numpy.float)
59
60 for example in data:
61 act = self.QuantizeActivity(example)[-1]
62 self.resultProbs[int(act)] += 1
63
64 for example in data:
65 if self._mapOrder is not None:
66 example = self._RemapInput(example)
67 if self.GetActivityQuantBounds():
68 example = self.QuantizeActivity(example)
69 if self.quantBounds is not None and 1 in self.quantizationRequirements:
70 quantExample = self.QuantizeExample(example, self.quantBounds)
71 else:
72 quantExample = []
73
74 trueRes = int(example[-1])
75
76 votes = self.CollectVotes(example, quantExample)
77
78 for i in range(nModels):
79 self.condProbs[i][votes[i], trueRes] += 1
80
81
82 for i in range(nModels):
83 for j in range(nResults):
84 self.condProbs[i][j] /= sum(self.condProbs[i][j])
85
86
87 self.resultProbs /= sum(self.resultProbs)
88
89 if verbose:
90 print('**** Bayesian Results')
91 print('Result probabilities')
92 print('\t', self.resultProbs)
93 print('Model by model breakdown of conditional probs')
94 for mat in self.condProbs:
95 for row in mat:
96 print('\t', row)
97 print()
98
99 - def ClassifyExample(self, example, threshold=0, verbose=0, appendExample=0):
100 """ classifies the given example using the entire composite
101
102 **Arguments**
103
104 - example: the data to be classified
105
106 - threshold: if this is a number greater than zero, then a
107 classification will only be returned if the confidence is
108 above _threshold_. Anything lower is returned as -1.
109
110 **Returns**
111
112 a (result,confidence) tuple
113
114 """
115 if self._mapOrder is not None:
116 example = self._RemapInput(example)
117 if self.GetActivityQuantBounds():
118 example = self.QuantizeActivity(example)
119 if self.quantBounds is not None and 1 in self.quantizationRequirements:
120 quantExample = self.QuantizeExample(example, self.quantBounds)
121 else:
122 quantExample = []
123 self.modelVotes = self.CollectVotes(example, quantExample, appendExample=appendExample)
124
125 nPossibleRes = self.nPossibleVals[-1]
126 votes = [0.] * nPossibleRes
127 for i in range(len(self)):
128 predict = self.modelVotes[i]
129 for j in range(nPossibleRes):
130 votes[j] += self.condProbs[i][predict, j]
131
132
133 res = numpy.argmax(votes)
134 conf = votes[res] / len(self)
135 if verbose:
136 print(votes, conf, example[-1])
137 if conf > threshold:
138 return res, conf
139 else:
140 return -1, conf
141
146
147
149 """ converts a Composite to a BayesComposite
150
151 if _obj_ is already a BayesComposite or if it is not a _Composite.Composite_ ,
152 nothing will be done.
153
154 """
155 if obj.__class__ == BayesComposite:
156 return
157 elif obj.__class__ == Composite.Composite:
158 obj.__class__ = BayesComposite
159 obj.resultProbs = None
160 obj.condProbs = None
161
162
164 """ converts a BayesComposite to a Composite.Composite
165
166 """
167 if obj.__class__ == Composite.Composite:
168 return
169 elif obj.__class__ == BayesComposite:
170 obj.__class__ = Composite.Composite
171 obj.resultProbs = None
172 obj.condProbs = None
173