朴素贝叶斯python代码_朴素贝叶斯模型及python实现
1 朴素贝叶斯模型
朴素贝叶斯法是一种建立在贝叶斯定理和属性独立性假设基础上的分类模型。在预测阶段,在给定输入x的情况下,通过确定与输入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=c_k)等于联合概率P(X{(1)}=x{(1)}, …, X{(n)}=x{(n)})在Y=c_k条件下的值,并对k取值为1到K的所有情况成立
其中,输入数据 X 维度为nnn.
输出:测试数据的后验概率
根据 后验=似然∗先验/归一化后验 = 似然*先验/归一化后验=似然∗先验/归一化, 有:
此概率值可表示为应用贝叶斯定理计算得出的条件概率之比
NB分类器即为:
f(x)=y等于在所有k中找到使得P\left(Y={c}_{k}\right)\prod _{j}P\left({X}^{\left(j\right)}={x}^{\left(j\right)|Y={c}_{k}\right)最大的那个{c}_{k}值,并将其对应的分子值作为结果。
其中,
分子部分为各个{X}^{\left(j\right)}在给定类{c}_{k}情况下的联合概率与类先验概率的乘积,
分母则是所有类别的相同计算结果之总和。
因此,
y=f(x)= \frac{\arg \max _{c_{k}} \prod _{k}\sum _{} }{}
其中,分母是归一化因子,可以忽略。
该分类方法可划分为高斯型、多项式型以及伯努利型等不同类型的朴素贝叶斯算法
2 朴素贝叶斯的参数估计
朴素贝叶斯模型需要计算先验几率P(Y=c_k) 和条件几率P\left(X^{(j)}=x^{(j)} | Y=c_k\right)。其中仅针对离散属性的情形进行分析。
2.1 极大似然法(MLE)
使用极大似然法估计(Maximum Likehood Estimation)先验概率:
The probability that Y equals ck is equal to the sum of indicators divided by N for each k from 1 to 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}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贝叶斯详解及代码; 2. .关于朴素贝叶斯法; 3. 黄海广 GitHub代码; 4. wepon大神blog; 5. Bayes 课件 Utdallas.edu; 6. Bayes MLE MAP 区别 cmu; 7. MLE 解释 英文; 8. sklearn Naive Bayes;
