Untitled
unknown
plain_text
a year ago
2.8 kB
13
Indexable
from scipy.stats import multivariate_normal
class BayesianClassifier:
def __init__(self, shared_cov=True, cond_ind=True):
self.shared_cov=shared_cov
self.cond_ind=cond_ind
def fit(self, x, y):
self.classes_, class_counts = np.unique(y, return_counts=True)
self.n_ , self.p_ = x.shape
self.k_ = len(self.classes_)
self.cond_means_ = np.zeros(shape=(self.k_, self.p_))
self.cond_covs_ = np.zeros(shape=(self.k_, self.p_, self.p_))
self.class_priors_ = class_counts/len(y)
for c in range(self.k_):
c_rows = y==c
self.cond_means_[c, :] = x[c_rows].mean(axis=0)
if self.cond_ind:
np.fill_diagonal(self.cond_covs_[c, :, :], x[c_rows].var(axis=0))
else:
self.cond_covs_[c, :, :] = np.cov(x[c_rows].T, bias=True)
if self.shared_cov:
shared_cov = np.moveaxis(self.cond_covs_, 0, -1).dot(self.class_priors_)
self.cond_covs_[:] = shared_cov
return self
def predict_proba(self, x):
m, _ = x.shape
cond_probs = np.zeros(shape=(m, self.k_))
for c in range(self.k_):
# find p(x | c_k)
# singular covariance matrices could happen (e.g., through inaccurate estimation)
cond_probs[:, c] = multivariate_normal.pdf(x,
mean=self.cond_means_[c], # YOUR CODE HERE
cov=self.cond_covs_[c],# YOUR CODE HERE
allow_singular=True)
# find marginal probabilities p(x) by summing all the conditionals weighted by the priors
marginal_probs = np.dot(cond_probs, self.class_priors_)# YOUR CODE HERE
# find probability vector (p(c1 | x), ..., p(ck | x)) via p(ci | x)=p(x | ci) / p(x)
# however, p(x) might have been rounded to 0
# thus, compute via case distinction
probs = np.divide((cond_probs*self.class_priors_).T,
marginal_probs,
where=marginal_probs>0, out=np.zeros(shape=(self.k_, m))).T
return probs
def predict(self, x):
return np.argmax(self.predict_proba(x), axis=1)
def decision_function(self, x):
probs = self.predict_proba(x)
if self.k_ == 2:
return np.log(probs[:, 1]/probs[:, 0])
else:
res = np.zeros(len(x), self.k_)
for c in range(self.k_):
res[:, c]=np.log(probs[:, c]/(1-probs[:, c]))
return res
def generate(self, n, c, random_state=None):
return multivariate_normal.rvs(self.cond_means_[c], self.cond_covs_[c], size=n, random_state=random_state)Editor is loading...
Leave a Comment