1 朴素贝叶斯模型
朴素贝叶斯法是基于贝叶斯定理、特征条件独立假设的分类方法。在预测时,对输入x,找出对应后验概率最大的 y 作为预测。
NB模型:
输入:
先验概率分布:P(Y=ck),k=1,2,⋯,KP\left(Y=c_{k}\right), \quad k=1,2, \cdots, KP(Y=ck),k=1,2,⋯,K
条件概率分布:P(X=x∣Y=ck)=P(X(1)=x(1),⋯,X(n)=x(n)∣Y=ck),k=1,2,⋯,KP\left(X=x | Y=c_{k}\right)=P\left(X^{(1)}=x^{(1)}, \cdots, X^{(n)}=x^{(n)} | Y=c_{k}\right), \quad k=1,2, \cdots, KP(X=x∣Y=ck)=P(X(1)=x(1),⋯,X(n)=x(n)∣Y=ck),k=1,2,⋯,K
其中,输入数据 X 维度为nnn.
输出:测试数据的后验概率
根据 后验=似然∗先验/归一化后验 = 似然*先验/归一化后验=似然∗先验/归一化, 有:
P(Y=ck∣X=x)=P(X=x∣Y=ck)P(Y=ck)∑kP(X=x∣Y=ck)P(Y=ck)P\left(Y=c_{k} | X=x\right)=\frac{P\left(X=x | Y=c_{k}\right) P\left(Y=c_{k}\right)}{\sum_{k} P\left(X=x | Y=c_{k}\right) P\left(Y=c_{k}\right)}P(Y=ck∣X=x)=∑kP(X=x∣Y=ck)P(Y=ck)P(X=x∣Y=ck)P(Y=ck)
NB分类器即为:
y=f(x)=argmaxckP(Y=ck)∏jP(X(j)=x(j)∣Y=ck)∑kP(Y=ck)∏jP(X(j)=x(j)∣Y=ck)y=f(x)=\arg \max _{c_{k}} \frac{P\left(Y=c_{k}\right) \prod_{j} P\left(X^{(j)}=x^{(j)} | Y=c_{k}\right)}{\sum_{k} P\left(Y=c_{k}\right) \prod_{j} P\left(X^{(j)}=x^{(j)} | Y=c_{k}\right)}y=f(x)=argmaxck∑kP(Y=ck)∏jP(X(j)=x(j)∣Y=ck)P(Y=ck)∏jP(X(j)=x(j)∣Y=ck)
其中,分母是归一化因子,可以忽略。
朴素贝叶斯可以分为高斯朴素贝叶斯、多项式朴素贝叶斯、贝努利朴素贝叶斯等多种。
2 朴素贝叶斯的参数估计
朴素贝叶斯需要估计先验概率P(Y=ck)P\left(Y=c_{k}\right)P(Y=ck) 和条件概率P(X(j)=x(j)∣Y=ck)P\left(X^{(j)}=x^{(j)} | Y=c_{k}\right)P(X(j)=x(j)∣Y=ck).以下只考虑离散属性情形。
2.1 极大似然法(MLE)
使用极大似然法估计(Maximum Likehood Estimation)先验概率:
P(Y=ck)=∑i=1NI(yi=ck)N,k=1,2,⋯,KP\left(Y=c_{k}\right)=\frac{\sum_{i=1}^{N} I\left(y_{i}=c_{k}\right)}{N}, \quad k=1,2, \cdots, KP(Y=ck)=N∑i=1NI(yi=ck),k=1,2,⋯,K
条件概率:
&P\left(X^{(j)}=a_{jl} | Y=c_{k}\right)=\frac{\sum_{i=1}^{N} I\left(x_{i}^{j}=a_{j l}, y_{i}=c_{k}\right)}{\sum_{i=1}^{N} I\left(y_{i}=c_{k}\right)}\\ &j=1,2, \cdots, n ; \quad l=1,2, \cdots, S_{j}; \quad k=1,2, \cdots, K \end{aligned}$$ #### 2.2 贝叶斯估计 极大似然法可能出现概率值为 0 情况,贝叶斯估计使用了拉普拉斯平滑. 先验概率的贝叶斯估计为: $$P_{\lambda}\left(Y=c_{k}\right)=\frac{\sum_{i=1}^{N} I\left(y_{i}=c_{k}\right)+\lambda}{N+K \lambda}$$ 条件概率的贝叶斯估计为: $$P_{\lambda}\left(X^{(j)}=a_{j l} | Y=c_{k}\right)=\frac{\sum_{l=1}^{N} I\left(x_{i}^{(j)}=a_{j l} ,y_{i}=c_{k}\right)+\lambda}{\sum_{i=1}^{N} I\left(y_{i}=c_{k}\right)+S_{j} \lambda}$$ Q1:这里极大似然估计和贝叶斯估计感觉描述没什么区别? A1:《机器学习》书中,没有提拉普拉斯平滑当作贝叶斯估计,还是有点疑问。 ### 3 朴素贝叶斯实现 #### 3.1 高斯朴素贝叶斯实现 高斯朴素贝叶斯用于连续数据的预测,原理是假设训练集各个特征满足高斯分布,获得不同类别数据集对应不同特征的高斯分布均值和方差,然后计算测试样本各个特征属于相应高斯分布的概率,从而获得其属于某个类别的概率,并把概率最大的标签作为这个样本的标签。 ```python import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import load_iris import pandas as pd from sklearn.model_selection import train_test_split import math sqrt, exp, pi = np.sqrt, np.exp, np.pi def createData(): iris = load_iris() df = pd.DataFrame(iris.data, columns = iris.feature_names) df['label'] = iris.target df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label'] return df.iloc[:,:-1],df.iloc[:,-1] X,y = createData() Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size = 0.5, random_state = 1028) class GaussianNaiveBayes(object): ''' 高斯朴素贝叶斯,用于处理连续数据,输入使用numpy.array. ''' def __init__(self): self.model = None @staticmethod def mean(x): ''' 求array类型的特征(列)平均值 ''' return sum(x)/float(len(x)) def var(self, x): ''' 求特征的方差 ''' return sum(pow(x-self.mean(x),2)*1.0/len(x)) def gaussianProba(self, x, mean, var): ''' 使用高斯概率密度,求测试集属于某个特征的值 ''' return 1/(sqrt(2*pi*var))*exp(-pow(x-mean,2)/(2.0*var)) def summarize(self, data): ''' 返回训练集每个特征的平均值,方差。 ''' data = np.array(data) return [self.mean(data),self.var(data)] def fit(self, x, y): ''' 获得训练集每个标签对应每个特征的平均值,方差。 ''' labels = np.unique(y) data = {label:[] for label in labels} for f, label in zip(x, y): data[label].append(f.tolist()) self.model = {label: self.summarize(value) for label, value in data.items()} return data,self.model def calculateProba(self, data): ''' 计算测试集对应在每个类别的概率。 ''' prob = {} data = data.transpose() for label, value in self.model.items(): prob[label] = 1 for i in range(len(data)): prob[label] *= self.gaussianProba(data[i], value[0][i], value[1][i]) return prob def predict(self, data): ''' 把概率最高的值作为样本的标签。 ''' res = [] for label, value in self.calculateProba(data).items(): res.append(value) res = np.array(res) return np.argmax(res, axis = 0) def score(self, x, y): ''' 计算预测的准确率。 ''' score = 0 label = self.predict(x) for i in range(len(label)): if label[i] ==y[i]: score+=1 return score*1.0/len(label) if __name__ == '__main__': model = GaussianNaiveBayes() data, m1 = model.fit(Xtrain.values, Ytrain.values) prob = model.calculateProba(Xtest.values) label = model.predict(Xtest.values) score = model.score(Xtest.values, Ytest.values) print('accuary', score) ``` 结果:`accuary 0.9466666666666667` #### 3.2 多项式朴素贝叶斯MultinomialNB 多项式朴素贝叶斯可以用于离散数据的分类中。 调用sklearn API: ```python import numpy as np rng = np.random.RandomState(1) X = rng.randint(5, size=(6, 100)) y = np.array([1, 2, 3, 4, 5, 6]) from sklearn.naive_bayes import MultinomialNB clf = MultinomialNB() clf.fit(X, y) print(clf.predict(X[2:3])) ``` ### 4. 拓展:极大似然估计与贝叶斯估计的区别 贝叶斯是**假定模型参数服从某种分布**,然后对模型参数分布进行估计。这和极大似然法非常不同(极大似然法假设参数是某个值,只是对参数估计,属于点估计范围)。 贝叶斯估计应用分为两种,对离散数据的估计及对连续数据的估计,其实差别不大,只是参数分布假设不同,连续数据时模型参数多假设为高斯分布。 --- 参考: 1. [GitHub贝叶斯详解及代码](https://github.com/endymecy/spark-ml-source-analysis/blob/master/%E5%88%86%E7%B1%BB%E5%92%8C%E5%9B%9E%E5%BD%92/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF/nb.md); 2. [CSDN.关于朴素贝叶斯法](http://blog.csdn.net/u012162613/article/details/48323777); 3. [黄海广 GitHub代码](https://github.com/fengdu78/lihang-code/blob/master/code/%E7%AC%AC4%E7%AB%A0%20%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF(NaiveBayes)/GaussianNB.ipynb); 4. [wepon大神blog](https://blog.csdn.net/u012162613/article/details/48323777); 5. [Bayes 课件 Utdallas.edu](http://www.utdallas.edu/~nrr150130/cs7301/2016fa/lects/Lecture_14_Bayes.pdf); 6. [Bayes MLE MAP 区别 cmu](http://www.cs.cmu.edu/~aarti/Class/10701_Spring14/slides/MLE_MAP_Part1.pdf); 7. [MLE 解释 英文](https://newonlinecourses.science.psu.edu/stat414/node/191/); 8. [sklearn Naive Bayes](https://scikit-learn.org/stable/modules/naive_bayes.html);