整个文章大纲html
若是你是理工科出身,对贝叶斯公式确定不会陌生。
贝叶斯常常用于文档分类上,在电子邮件的过滤等文本处理上效果至关不错,最近题主在学校作的一个参加挑战杯的项目,是基于LDA贝叶斯模型,可能有些同窗会有点迷糊,这里的LDA不是Linear Discriminant Analysis线性分类器,是隐含狄利克雷分布(Latent Dirichlet Allocation)python
上贝叶斯公式:
git
话很少说,咱们来首先来看一下贝叶斯是基于什么样的思想:github
新信息出现以后A的几率 = A的几率×新信息带来的调整web
我在知乎上找到的维恩图很好地表现了贝叶斯公式的背后思想
来自非数学语言解释贝叶斯定理算法
那么如今对于最基础的公式有了最直观的理解以后,那咱们就能够学习怎么把这个思想运用到分类上。
咱们用先验几率和类条件几率的乘积,代替后验几率去作比较:
其实很简单,我来举个例子
如今有2类硬币:
* 1元
* 0.5元
目前知道的有这两类硬币数量的比例,这是一个先验几率噢,好比说,为了简便,我取1:1,每一种类别的频率都为0.5
那么如今咱们想要根据测量硬币的重量来进一步预测这个硬币究竟是1元的仍是5角的
咱们就能够根据贝叶斯公式推算出未知硬币的分别属于哪一种硬币的几率,取几率大的为预测结果。
那你如今可能就会有问题了,后验几率怎么来的呢?
好问题,这也是贝叶斯的一个小bug,后验几率通常是根据数据得出,你能够看出其实这里不能作到彻底严谨。app
在通常应用中咱们假设这个特征在类内是服从正态分布的(实际上生活中不少特征都是这样的),正态分布由两个参数惟一决定,均值和方差。因此彻底能够用训练集中的特征的出现状况去估计这两个参数,从而获得类条件几率密度函数的模型。ide
以下图,若是类条件几率密度函数和先验几率的乘积图像是这样的,那么在交点处做为分类面,对于特征的值x取在分类面左边的样本预测为红色类别,右边的样本预测为绿色类别,总的错误率最小:
图中一半阴影便是把绿色类误判为红色类的状况,一半阴影是把红色类误判为绿色类的状况。只有分类面取在交点处时这个错误率之和才能最小。
若是不是取在交点处,不论是在左边仍是右边,能够看到错误的面积老是会比刚刚那种状况多出一块:
如此咱们能够获得:
以二分类问题为例,对于样本x的决策错误率:
更进一步获得:
决策函数:
讨论多分类问题:
若是认为样本的特征向量在类内服从多元正态分布:
类条件几率密度服从多元正态分布,带入,得:svg
码累了,下次补充函数
封装的算法是仿sklearn的风格。这里我用的accuracy_score直接调用sklearn的了,在后续的博客中(可能很慢,可是寒假来临后,会更新比较快,都是手码字,有些慢)
这段代码逻辑其实很清晰(某人自认为,不接受反驳!X^X)
import numpy as np from numpy.linalg import inv from sklearn.metrics import accuracy_score class BayesGN: def __init__(self, priors=None): """初始化Linear Regression模型""" self.priors = priors self._mean = None self._cov = None def fit(self, X_train, y_train): """ sorted_y 和priors对应的类别序号相对应 """ X_train = np.array(X_train) y_train = np.array(y_train) sorted_y = np.sort(np.unique(y_train)) if self.priors is None: c = Counter(y_train) _sum = sum(c.values()) self.priors = [c[y] / _sum for y in sorted_y] self._mean = [X_train[y_train == y].mean(axis=0) for y in sorted_y] self._cov = [np.cov(X_train[y_train == y].T) for y in sorted_y] return self def predict(self, X_predict): """给定带预测数据集X_predict,返回表示X_predict的结果向量""" y_predict = [self._predict(x) for x in X_predict] return np.array(y_predict) def _predict(self, Xi): return np.argsort(self._rvs_g(Xi))[0] def decision_function(self, X_test): b = [self._rvs_g(X_test[i])[0]-self._rvs_g(X_test[i])[1] for i in range(len(X_test))] return b def score(self, X_test, y_test): """根据数据集X_test,y_test计算准确度 分类准确度使用accuracy_score""" y_predict = self.predict(X_test) return accuracy_score(y_test, y_predict) def _rvs_g(self, Xi): if self._cov[0].ndim == 0: rvs_g = [(Xi - self._mean[i]) / self._cov[i] + np.log(self._cov[i]) - 2 * np.log(self.priors[i]) for i in range(len(self._mean))] else: rvs_g = [np.matmul(np.matmul((Xi - self._mean[i]), inv(self._cov[i])), (Xi - self._mean[i])) + np.log(np.linalg.det(self._cov[i])) - 2 * np.log(self.priors[i]) for i in range(len(self._mean))] return rvs_g