| 9 | |
| 10 | |
| 11 | class NB: |
| 12 | def fit(self, X, Y): |
| 13 | self.pyy = [] |
| 14 | self.tinfo = [] |
| 15 | N, D = X.shape |
| 16 | for c in (0, 1): |
| 17 | pyy_c = (1.0 + np.sum(Y == c)) / (N + 1.0 + 1.0) |
| 18 | self.pyy.append(pyy_c) |
| 19 | |
| 20 | # for each dimension, we need to store the data we need to calculate |
| 21 | # the posterior predictive distribution |
| 22 | # t-distribution with 3 params: df, center, scale |
| 23 | Xc = X[Y == c] |
| 24 | tinfo_c = [] |
| 25 | for d in xrange(D): |
| 26 | # first calculate the parameters of the normal gamma |
| 27 | xbar = Xc[:,d].mean() |
| 28 | mu = N*xbar / (1.0 + N) |
| 29 | precision = 1.0 + N |
| 30 | alpha = 1.0 + N/2.0 |
| 31 | beta = 1.0 + 0.5*Xc[:,d].var()*N + 0.5*N*(xbar*xbar)/precision |
| 32 | |
| 33 | tinfo_cd = { |
| 34 | 'df': 2*alpha, |
| 35 | 'center': mu, |
| 36 | 'scale': np.sqrt( beta*(precision + 1)/(alpha * precision) ), |
| 37 | } |
| 38 | tinfo_c.append(tinfo_cd) |
| 39 | self.tinfo.append(tinfo_c) |
| 40 | |
| 41 | def predict_proba(self, X): |
| 42 | N, D = X.shape |
| 43 | # P = np.zeros(N) |
| 44 | # for n in xrange(N): |
| 45 | # x = X[n] |
| 46 | |
| 47 | # pyx = [] |
| 48 | # for c in (0, 1): |
| 49 | # pycx = self.pyy[c] |
| 50 | # for d in xrange(D): |
| 51 | # tinfo_cd = self.tinfo[c][d] |
| 52 | # pdf_d = t.pdf(x[d], df=tinfo_cd['df'], loc=tinfo_cd['center'], scale=tinfo_cd['scale']) |
| 53 | # pycx *= pdf_d |
| 54 | # pyx.append(pycx) |
| 55 | |
| 56 | # py1x = pyx[1] / (pyx[0] + pyx[1]) |
| 57 | # # print "p(y=1|x):", py1x |
| 58 | # P[n] = py1x |
| 59 | |
| 60 | posteriors = np.zeros((N, 2)) |
| 61 | for c in (0, 1): |
| 62 | probability_matrix = np.zeros((N, D)) |
| 63 | for d in xrange(D): |
| 64 | tinfo_cd = self.tinfo[c][d] |
| 65 | pdf_d = t.pdf(X[:,d], df=tinfo_cd['df'], loc=tinfo_cd['center'], scale=tinfo_cd['scale']) |
| 66 | probability_matrix[:,d] = pdf_d |
| 67 | posteriors_c = np.prod(probability_matrix, axis=1)*self.pyy[c] |
| 68 | posteriors[:,c] = posteriors_c |