-
2021-02-05 17:40:36
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);
更多相关内容 -
朴素贝叶斯模型及案例(Python)
2022-04-15 14:13:49朴素贝叶斯是贝叶斯模型当中最简单的一种,其算法核心为如下所示的贝叶斯公式。 其中P(A)为事件A发生的概率,P(B)为事件B发生的概率,P(A|B)表示在事件B发生的条件下事件A发生的概率,同理P(B|A)则表示...目录
1 朴素贝叶斯的算法原理
贝叶斯分类是机器学习中应用极为广泛的分类算法之一。
朴素贝叶斯是贝叶斯模型当中最简单的一种,其算法核心为如下所示的贝叶斯公式。
其中P(A)为事件A发生的概率,P(B)为事件B发生的概率,P(A|B)表示在事件B发生的条件下事件A发生的概率,同理P(B|A)则表示在事件A发生的条件下事件B发生的概率。
举一个简单的例子:已知冬季一个人感冒(事件A)的概率P(A)为40%,一个人打喷嚏(事件B)的概率P(B)为80%,一个人感冒时打喷嚏的概率P(B|A)为100%,那么如果一个人开始打喷嚏,他感冒的概率P(A|B)为多少?求解过程如下。
2 一维特征变量下的贝叶斯模型
以一个详细的例子来说:如何判断一个人是否感冒。假设已经有5组样本数据,见下表。
只选取了一个特征变量“打喷嚏(X1)”,其值为1表示打喷嚏,为0表示不打喷嚏;目标变量是“感冒(Y)”,其值为1表示感冒,为0表示未感冒。
现在要根据上述数据,利用贝叶斯公式预测一个人是否感冒。
例如,一个人打喷嚏了(X1=1),那么他是否感冒了呢?这个问题实际上是要预测他感冒的概率P(Y|X1)。将特征变量和目标变量代入贝叶斯公式,可获得如下所示的计算公式。
根据上述数据,可以计算在打喷嚏(X1=1)的条件下,感冒(Y=1)的概率,计算过程如下。
其中P(X1=1|Y=1)为在感冒的条件下打喷嚏的概率,这里感冒的4个样本中有3个样本打喷嚏,所以该概率为3/4;P(Y=1)为所有样本中感冒的概率,这里5个样本中有4个样本感冒,所以该概率为4/5;P(X1=1)为所有样本中打喷嚏的概率,这里5个样本中有4个样本打喷嚏,所以该概率为4/5。
同理,在打喷嚏(X1=1)的条件下,未感冒(Y=0)的概率的计算过程如下。
其中P(X1=1|Y=0)为在未感冒的条件下打喷嚏的概率,为1;P(Y=0)为所有样本中未感冒的概率,为1/5;P(X1=1)为所有样本中打喷嚏的概率,为4/5。
因为3/4大于1/4,所以在打喷嚏的条件下感冒的概率要高于未感冒的概率。
3 二维特征变量下的贝叶斯模型
在上边的一个特征变量的基础上加入另一个特征变量——头痛(X2),其值为1表示头痛,为0表示不头痛;目标变量仍为感冒(Y)。样本数据见下表。
根据上述数据,仍利用贝叶斯公式来预测一个人是否感冒。例如,一个人打喷嚏且头痛(X1=1,X2=1),那么他是否感冒了呢?这个问题实际上是要预测他感冒的概率P(Y|X1,X2)。将特征变量和目标变量代入贝叶斯公式,可获得如下所示的计算公式。
现在要计算并比较P(Y=1|X1,X2)与P(Y=0|X1,X2)的大小,由上述公式可知,两者的分母P(X1,X2)是相同的,所以直接计算并比较两者的分子P(X1,X2|Y)P(Y)的大小即可。
在计算之前,需要先引入朴素贝叶斯模型的独立性假设:朴素贝叶斯模型中的各个特征之间相互独立,即P(X1,X2|Y)=P(X1|Y)P(X2|Y)。因此,分子的计算公式可以转换为如下形式。
在独立性假设的前提下,计算打喷嚏且头痛(X1=1,X2=1)的条件下感冒(Y=1)的概率P(Y=1|X1=1,X2=1),就转化为计算P(X1=1|Y=1)P(X2=1|Y=1)P(Y=1)的值,计算过程如下。
同理,计算打喷嚏且头痛(X1=1,X2=1)的条件下未感冒(Y=0)的概率P(Y=0|X1=1,X2=1),即转化为计算P(X1=1|Y=0)P(X2=1|Y=0)P(Y=0)的值,计算过程如下。
因为9/20大于1/5,所以在打喷嚏且头痛的条件下感冒的概率要高于未感冒的概率。
4 n维特征变量下的贝叶斯模型
在2个特征变量的基础上将贝叶斯公式推广至n个特征变量X1,X2,…,Xn,公式如下。
朴素贝叶斯模型假设给定目标值后各个特征之间相互独立,分子的计算公式可以写成如下形式。
其中P(X1|Y)、P(X2|Y)、P(Y)等数据都是已知的,由此可以计算在n个特征变量取不同的值的条件下,目标变量取某个值的概率,并且选择概率更高者对样本进行分类。
5 朴素贝叶斯模型的sklearn实现
# 这里用的是高斯贝叶斯模型 from sklearn.naive_bayes import GaussianNB X = [[1,2],[3,4],[5,6],[7,8],[9,10]] y = [0,0,0,1,1] model = GaussianNB() model.fit(X,y) model.predict([[5,5]]) # 输出结果 # array([0])
6 案例:肿瘤预测模型
以一个医疗行业较为经典的肿瘤预测模型为例,讲解如何在实战中应用朴素贝叶斯模型来预测肿瘤为良性肿瘤还是恶性肿瘤。
肿瘤性质的判断影响着患者的治疗方式和痊愈速度。传统的做法是医生根据数十个指标来判断肿瘤的性质,预测效果依赖于医生的个人经验而且效率较低,而通过机器学习,我们有望能快速预测肿瘤的性质。
6.1 读取数据与划分
6.1.1 读取数据
首先通过如下代码导入某医院乳腺肿瘤患者的6个特征维度及肿瘤性质的数据。共569个患者,其中良性肿瘤358例、恶性肿瘤211例。
其中6个特征变量分别为“最大周长”“最大凹陷度”“平均凹陷度”“最大面积”“最大半径”“平均灰度值”。
目标变量为“肿瘤性质”,0代表肿瘤为恶性,1代表肿瘤为良性。
6.1.2 划分特征变量和目标变量
6.2 模型的搭建与使用
6.2.1 划分训练集和测试集
6.2.2 模型搭建
6.2.3 模型预测与评估
使用训练集拟合的模型对测试集进行预测。
利用创建DataFrame的相关知识点,汇总预测结果y_pred和测试集中的实际值y_test,代码如下。
注意:y_pred为一维数组,y_test为Series对象,需要统一类型
可以看到,前5项的预测准确度为80%。
通过如下代码可以查看所有测试集数据的预测准确度。
朴素贝叶斯模型属于分类模型,所以也可以利用ROC曲线来评估其预测效果。
from sklearn.metrics import roc_curve fpr,tpr,thres = roc_curve(y_test,y_pred_proba[:,1]) import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] #设置正常显示中文 plt.plot(fpr,tpr) plt.xlabel('假警报率') plt.ylabel('命中率') plt.title('ROC曲线') plt.show()
总结来说,朴素贝叶斯模型是一种非常经典的机器学习模型,它主要基于贝叶斯公式,在应用过程中会把数据集中的特征看成是相互独立的,而不需考虑特征间的关联关系,因此运算速度较快。相比于其他经典的机器学习模型,朴素贝叶斯模型的泛化能力稍弱,不过当样本及特征的数量增加时,其预测效果也是不错的。
参考书籍
《Python大数据分析与机器学习商业案例实战》
-
朴素贝叶斯+Python3实现高斯朴素贝叶斯
2020-08-25 17:54:421. 什么是朴素贝叶斯法 朴素贝叶斯(naive Bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布;然后基于此模型,对给定的输入x,...1. 什么是朴素贝叶斯法
朴素贝叶斯(naive Bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布;然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。朴素贝叶斯法实现简单,学习与预测的效率都很高,是一种常用的方法。
先举个例子来了解贝叶斯原理
一个袋子里有10个球,其中6个黑球,4个白球;那么随机抓取一个黑球的概率是0.6
这种情况下我们是站在上帝的视角,即知道事情的全貌再做判断(有多少个黑球,白球)在现实生活中,其实我们很难知道事情的全貌。贝叶斯则从实际场景出发,提了一个问题:
如果我们事先不知道白球和黑球的比例而是通过我们摸出来的球的颜色,能判断判断出袋子里面黑白球的比例么?
贝叶斯原理就是在我们不了解所有客观事实的情况下,同样可以先估计一个值,然后根据实际结果不断进行改正。
再来了解几个概率论理论后面会用到
先验概率:
通过经验判断实际发生的概率,比如说“佝偻病”的发病率是万分之一,就是先验概率。
后验概率:
后验概率就是发生结果之后,推测原因的概率。比如说某人查出来患有“佝偻病”,那么患病的原因可能是A, B 或 C。患有“佝偻病”的原因A的概率就是后验概率
条件概率:
事件A 在另外一个事件B已经发生条件下的发生概率,表示P(A|B)
1.1 基本方法
设输入空间X ⊆ \subseteq ⊆ R n R^n Rn 为 n 维向量的集合,输出空间为类标记集合 y = {c1, c2, ·········,ck,}。
输入特征向量 x ∈ \in ∈ X, 输出为类标记(class label)y ∈ \in ∈ Y。X是定义在输入空间 X 上的随机向量,y 是定义在输出空间 Y 上的随机变量。P(X,Y)是 X 和 Y的联合概率分布。训练数据集
T = { (x1,y1), (x2,y2),…,(xN,yN)}
由 P(X , Y) 独立同分布产生。
朴素贝叶斯法通过训练数据集学习联合概率分布 P( X, Y)。具体的,学习以先验概率分布及条件概率分布。先验概率分布
P( Y = ck ),k = 1,2,…,K
条件概率分布
P ( X = x | Y = ck) = P( X(1) = x(1),…,X(n) = xn|Y = ck) , k = 1,2,… ,K
于是学习到联合概率分布P(X,Y)。
条件概率分布 P (X = x|Y = ck) 有指数级数量的参数,其估计实际是不可行的。
事实上,假设x(j) 可取之有Sj 个,j = 1,2,…,n, Y可取值有 K 个,那么参数个数为 K ∏ j = 1 n S j \prod_{j=1}^n Sj ∏j=1nSj。
朴素贝叶斯法对条件概率分布作了条件独立性的假设。由于这是一个较强的假设,朴素贝叶斯法也由此得名。具体的,条件独立性假设是
P ( X = x | Y = ck) = P( X(1) = x(1),…,X(n) = xn|Y = ck) = ∏ j = 1 n \prod_{j=1}^n ∏j=1nP( X( j ) = x( j )|Y = ck)
朴素贝叶斯法实际上学习到生成数据的机制,所以属于生成模型。条件独立建设等于是说实例的各个特征之间互不影响。这一假设是朴素贝叶斯法变得简单,但有时会牺牲一定的分类准确率。
朴素贝叶斯分类时,对给定的输入 x, 通过学习到的模型计算后验概率分布P( Y = ck | X = x) , 将后验概率最大的类作为 x 的类输出。后验概率计算根据贝叶斯定理进行:
这是朴素贝叶斯法分类的基本公式。于是,朴素贝叶斯分类器可表示为
注意到,在上式中分母对所有ck 都是相同的,所以,
1.2 后验概率最大化的含义
朴素贝叶斯法将实例分到后验概率最大的类中。这等价于期望风险最小化。假设选择0-1损失函数:
式中 f( X ) 是分类决策函数。这时,期望风险函数为
Rexp( f ) = E [ L ( Y, f ( X ) ) ]
期望是对联合分布P(X,Y)取的。由此取条件期望
这样一来,根据期望风险最小化准则就得到了后验概率最大化准则:
即朴素贝叶斯法所采用的原理
2. 朴素贝叶斯的参数估计
2.1.1 极大似然估计
在朴素贝叶斯法中,学习意味着估计 P(Y = ck) 和 P( X(j) = x(j) | Y = ck)。可以应用极大似然估计法估计相应的概率。先验概率P( Y = ck)的极大似然估计是
设第 j 个特征 x(j) 可能取值的集合为 {aj1,aj2,…,ajsj},条件概率P( X(j) = ajl | Y = ck)的极大似然估计是
式中,xij 是第 i 个样本的第 j 个特征;ajl 是第 j 个特征可能取的第 l 个值;I 为指示函数。
2.1.2 学习与分类算法
下面给出朴素贝叶斯法的学习与分类算法
朴素贝叶斯算法(naive Bayes algorithm)
输入:训练数据 T = { (x1,y1), (x2,y2),…,(xN,yN)} ,其中 xi = (xi1,xi2,…,xin)T,xij 是第 i 个样本的第 j 个特征,xij ∈ \in ∈{ aj1,aj2,…,ajSj},ajl是第 j 个特征可能取的第 l 个值,j = 1,2,…,n,l = 1,2,… ,Sj,yi ∈ \in ∈{ c1, c2,…, ck};实例x;
输出:实例 x 的分类。
(1) 计算先验概率及条件概率
贝叶斯估计
用极大似然估计可能会出现所要估计的概率值为 0 的情况。这时会影响到后验概率的计算结果,使分类产生偏差。解决这一问题的方法是采用贝叶斯估计。具体地,条件概率的贝叶斯估计是
式中 λ \lambda λ >=0。等价于在随机变量各个取值的频数上赋予一个正数 λ \lambda λ > 0 。当 λ \lambda λ = 0时就是极大似然估计。常取 λ \lambda λ = 1,这时称为拉普拉斯平滑(Laplacian smoothing)。Sj为特征值可能取值的个数。显然,对任何 l = 1,2,…,Sj,k = 1,2,…,K,有
所以先验概率的贝叶斯估计是
3. GaussianNB 高斯朴素贝叶斯+Python实现
特征的可能性假设为高斯
概率密度函数:
数学期望(mean):u
方差:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from collections import Counter import math class NaiveBayes: def __init__(self): self.model = None # 数学期望,踩坑,mean函数里不能加self,因为mean函数是静态方法 @staticmethod def mean(X): return sum(X) / float(len(X)) # 标准差 def stdev(self, x): avg = self.mean(x) return math.sqrt(sum([math.pow(i - avg, 2) for i in x]) / len(x)) # 高斯概密度函数 def gaussian_probability(self, x, mean, stdev): ex = math.exp(-(pow(x - mean, 2) / (2 * pow(stdev, 2)))) return (1 / math.sqrt(2 * math.pi * pow(stdev, 2))) * ex # 处理 X_train def summarize(self, train_data): summaries = [(self.mean(i), self.stdev(i)) for i in zip(*train_data)] return summaries # 分别求出数学期望和标准差 def fit(self, x, y): # 利用集合不重复的特点,求出y可能的取值 labels = list(set(y)) data = {label: [] for label in labels} for f, label in zip(x, y): data[label].append(f) #print(data.items()) self.model = {label: self.summarize(value) for label, value in data.items()} return "ok" # 计算概率 def calculate_probabilities(self, input_data): # summaries:{0.0: [(5.0, 0.37),(3.42, 0.40)], 1.0: [(5.8, 0.449),(2.7, 0.27)]} # input_data:[1.1, 2.2] probabilities = {} for label, value in self.model.items(): probabilities[label] = 1 for i in range(len(value)): mean, stdev = value[i] probabilities[label] *= self.gaussian_probability(input_data[i], mean, stdev) return probabilities # 类别 def predict(self, x_test): # 将预测数据在所有类别中的概率进行排序,并取概率最高的类别 label = sorted(self.calculate_probabilities(x_test).items(), key=lambda x: x[-1])[-1][0] return label # 准确率 def score(self, x_test, y_test): right = 0 for x, y in zip(x_test, y_test): if self.predict(x) == y: right += 1 return right / float(len(x_test)) if __name__ == '__main__': # data def create_data(): 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'] data = np.array(df.iloc[:100, :]) # print(data) return data[:, :-1], data[:, -1] X, y = create_data() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3) model = NaiveBayes() model.fit(X_train, y_train) print(model.predict([4.4, 3.2, 1.3, 0.2])) print(model.score(X_test, y_test))
4. 总结
- 朴素贝叶斯法是典型的生成学习方法。生成方法由训练、数据学习联合概率分布
P(X, Y) 然后求得后验概率分布 P(YIX) 。具体来说,利用训练数据学习 P(XIY)
P(Y) 的估计,得到联合概率分布:
P(X, Y) = P(Y)P(XIY)
概率估计方法可以是极大似然估计或贝叶斯估计
- 朴素贝叶斯法的基本假设是条件独立性,
这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝
叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。其缺点是分类
的性能不一定很高。
- 朴素贝叶斯法利用贝叶斯定理与学到的联合概率模型进行分类预测。
将输入 x 分到后验概率最大的类 y。
后验概率最大等价于0-1 损失函数时的期望风险最小化。
如果你觉得这篇文章有收获就给我点个赞吧!
下期预告:决策树
-
机器学习 朴素贝叶斯模型(Python实现)
2019-06-15 16:31:50在数据集中我们能够通过统计得出的是,P(x|C)即分类为C的属性取值为x的概率,要将P(x|C)转换为P(c|X),我们就要用到贝叶斯公式,这也是该分类方法名字的由来。 贝叶斯公式如下: 接下来,我们来实现一下...我们是否可以通过计算样例分类的概率来对样例进行分类呢,即一个样例分为正例的概率为0.9,分为反例的概率为0.5,那么我们将该样例分为正例。
那么我们的目标就是求P(正)和P(反)。
每一个样例都是由多个属性组成的,我们根据属性的取值来计算概率,这是明显的条件概率P(正|X),P(反|X)。X表示各个属性组成的属性向量(x1, x2, x3,......,xn)
若各个属性之间是独立的,即各个属性独立的对分类结果产生影响,那么P(正|X)或P(反|X)的计算式为(C表示分类标签)
在数据集中我们能够通过统计得出的是,P(x|C)即分类为C的属性取值为x的概率,要将P(x|C)转换为P(c|X),我们就要用到贝叶斯公式,这也是该分类方法名字的由来。
贝叶斯公式如下:
接下来,我们来实现一下:
数据集:
编号 色泽 根蒂 敲击 纹理 脐部 触感 好瓜 0 青绿 蜷缩 浊响 清晰 凹陷 硬滑 是 1 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 是 2 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 是 3 青绿 蜷缩 沉闷 清晰 凹陷 硬滑 是 4 浅白 蜷缩 浊响 清晰 凹陷 硬滑 是 5 青绿 稍蜷 浊响 清晰 稍凹 软粘 是 6 乌黑 稍蜷 浊响 稍糊 稍凹 软粘 是 7 乌黑 稍蜷 浊响 清晰 稍凹 硬滑 是 8 乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑 否 9 青绿 硬挺 清脆 清晰 平坦 软粘 否 10 浅白 硬挺 清脆 模糊 平坦 硬滑 否 11 浅白 蜷缩 浊响 模糊 平坦 软粘 否 12 青绿 稍蜷 浊响 稍糊 凹陷 硬滑 否 13 浅白 稍蜷 沉闷 稍糊 凹陷 硬滑 否 14 乌黑 稍蜷 浊响 清晰 稍凹 软粘 否 15 浅白 蜷缩 浊响 模糊 平坦 硬滑 否 16 青绿 蜷缩 沉闷 稍糊 稍凹 硬滑 否
我们训练和测试都使用它。
读入数据:
def loaddataset(Filename): fp = open(Filename) a = fp.readlines() fp.close() dataset = [] for i in a[1:]: b = i.strip().split() dataset.append(b[1:]) #返回数据和属性标签 return dataset, a[0].strip().split()[1:]
dataset显示如下:
分类标签显示如下:
['色泽', '根蒂', '敲击', '纹理', '脐部', '触感', '好瓜']
统计各个属性取值的正例个数比例和反例个数比例:
def statistics(dataset, n): #记录统计结果 count = {} for i in dataset: if i[n] not in count: #列表第一个位置为正例个数,第二个位置是反例个数 if i[-1] == '是': count[i[n]] = [1, 0] else: count[i[n]] = [0, 1] else: if i[-1] == '是': count[i[n]][0] += 1 else: count[i[n]][1] += 1 #计算各个属性取值为正例的概率和反例的概率 for i in count: n = count[i][0] + count[i][1] count[i][0] = count[i][0] / n count[i][1] = count[i][1] / n return count
该函数每次只统计一个属性的情况,我们以色泽为例 ,其统计结果为
{'青绿': [0.5, 0.5], '乌黑': [0.6666666666666666, 0.3333333333333333], '浅白': [0.2, 0.8]}
我使用列表保存所有属性的统计情况:
count_sum = [] for i in range(len(dataset[0])-1): count_sum.append(statistics(dataset, i))
统计数据集中正反例的个数:
a = list(np.array(dataset)[:,-1]) y = a.count('是') n = a.count('否')
预测:
#记录正确预测的个数 rightcount = 0 for i in range(len(dataset)): #记录分为正类的概率 py = 1 #记录分为反类的概率 pn = 1 for j in range(len(dataset[i])-1): b = count_sum[j] py *= b[dataset[i][j]][0] pn *= b[dataset[i][j]][1] py *= y / (y + n) pn *= n / (y + n) if py >= pn: flag = '是' else: flag = '否' if flag == a[i]: rightcount += 1 print('%s %s'%(flag, a[i])) print("正确率为%s"%(rightcount / len(dataset)))
预测结果如下:
是 是 是 是 是 是 是 是 是 是 是 是 否 是 是 是 否 否 否 否 否 否 否 否 否 否 否 否 是 否 否 否 否 否 正确率为0.8823529411764706 [Finished in 0.4s]
完整代码如下,数据集和原文件已上传至我的资源https://download.csdn.net/download/qq_41398808/11242762:
import numpy as np def loaddataset(Filename): fp = open(Filename) a = fp.readlines() fp.close() dataset = [] for i in a[1:]: b = i.strip().split() dataset.append(b[1:]) #返回数据和属性标签 return dataset, a[0].strip().split()[1:] def statistics(dataset, n): #记录统计结果 count = {} for i in dataset: if i[n] not in count: #列表第一个位置为正例个数,第二个位置是反例个数 if i[-1] == '是': count[i[n]] = [1, 0] else: count[i[n]] = [0, 1] else: if i[-1] == '是': count[i[n]][0] += 1 else: count[i[n]][1] += 1 #计算各个属性取值为正例的概率和反例的概率 for i in count: n = count[i][0] + count[i][1] count[i][0] = count[i][0] / n count[i][1] = count[i][1] / n return count if __name__ == '__main__': dataset, labelset = loaddataset('watermelon2.0.data') count_sum = [] for i in range(len(dataset[0])-1): count_sum.append(statistics(dataset, i)) a = list(np.array(dataset)[:,-1]) y = a.count('是') n = a.count('否') #记录正确预测的个数 rightcount = 0 for i in range(len(dataset)): #记录分为正类的概率 py = 1 #记录分为反类的概率 pn = 1 for j in range(len(dataset[i])-1): b = count_sum[j] py *= b[dataset[i][j]][0] pn *= b[dataset[i][j]][1] py *= y / (y + n) pn *= n / (y + n) if py >= pn: flag = '是' else: flag = '否' if flag == a[i]: rightcount += 1 print('%s %s'%(flag, a[i])) print("正确率为%s"%(rightcount / len(dataset)))
-
Python 分类问题研究-朴素贝叶斯模型
2022-04-24 20:01:481.掌握常见机器学习分类模型思想、算法,包括Fisher线性判别、KNN、朴素贝叶斯、Logistic回归、决策树等; 2.掌握Python编程实现分类问题,模型评价指标、计时功能、保存模型。 【实验要求】 理解Python在分类... -
python实现基于朴素贝叶斯的垃圾分类算法
2020-09-19 03:09:10主要为大家详细介绍了python实现基于朴素贝叶斯的垃圾分类算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
python实现朴素贝叶斯分类器
2020-12-31 17:09:37用的模型也是最简单的,就是用贝叶斯定理P(A|B) = P(B|A)*P(A)/P(B),计算每个类别在样本中概率(代码中是pLabel变量) 以及每个类下每个特征的概率(代码中是pNum变量)。 写得比较粗糙,对于某个类下没有此特征的... -
朴素贝叶斯分类模型完整代码
2020-03-12 12:16:13从读取文件、去除重用词、正则化、到词向量、再到预测分类。最后ROC曲线评估,一整套(带数据集),下载即运行。如果好用,还请给个好评 -
python编写朴素贝叶斯用于文本分类
2020-12-24 12:00:49朴素贝叶斯估计 朴素贝叶斯是基于贝叶斯定理与特征条件独立分布假设的分类方法。首先根据特征条件独立的假设学习输入/输出的联合概率分布,然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。... -
机器学习——朴素贝叶斯模型:Python实现
2020-11-09 16:45:37机器学习——朴素贝叶斯模型:Python实现1 朴素贝叶斯模型的代码实现2 案例实战:肿瘤预测模型2.1 读取数据2.2 划分特征变量和目标变量2.3 模型搭建2.3.1 划分训练集和测试集2.3.2 朴素贝叶斯模型 1 朴素贝叶斯模型... -
朴素贝叶斯分类(python实现)
2022-03-15 14:20:00算法优劣 参考刘建平老师的博客:朴素贝叶斯算法原理小结 ...但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比 -
python实现朴素贝叶斯算法
2020-09-19 22:28:48主要为大家详细介绍了Python实现朴素贝叶斯算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
python基于朴素贝叶斯模型的预测概率和标签信息可视化ROC曲线
2022-04-08 21:06:47python基于朴素贝叶斯模型的预测概率和标签信息可视化ROC曲线 -
使用 Python 进行朴素贝叶斯分类
2022-01-04 17:03:04朴素贝叶斯分类器使用的特征模型做出了很强的独立性假设。这意味着一个类的特定特征的存在与其他所有特征的存在是独立的或无关的。 独立事件的定义: 两个事件 E 和 F 是独立的,如果 E 和 F 都有正概率并且如果 P... -
朴素贝叶斯Python实例及解析
2020-09-19 22:56:00主要为大家详细介绍了朴素贝叶斯Python算法实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
机器学习:多项式模型朴素贝叶斯分类器(原理+python实现)
2021-01-20 11:21:52多项式朴素贝叶斯也是多用于文本处理,其原理和计算的流程和伯努利朴素贝叶斯基本一致,唯一的区别在于单词的计数方式,由《伯努利朴素贝叶斯》一文可知,在文本处理的环节中,我们将单词是否出现在词组作为特征,但... -
朴素贝叶斯算法的python实现方法
2020-12-07 11:39:09本文实例讲述了朴素贝叶斯算法的python实现方法。分享给大家供大家参考。具体实现方法如下:朴素贝叶斯算法优缺点优点:在数据较少的情况下依然有效,可以处理多类别问题缺点:对输入数据的准备方式敏感适用数据类型... -
【机器学习】朴素贝叶斯Python实现
2021-03-26 20:21:24机器学习这门课第三周的作业,手写朴素贝叶斯算法。 -
Python手工实现朴素贝叶斯分类及预测
2022-03-23 21:00:24朴素贝叶斯的基本原理、 朴素贝叶斯是基于1、最大后验概率和 2、特征条件独立假设 的分类方法,其分类原理是根据某对象的先验概率和类概率计算出其后验概率,然后选择具有最大后验概率的类作为该对象所属的类别。... -
Python实现朴素贝叶斯(Naive Bayesian algorithm)
2022-01-05 21:05:54本文使用Python实现了Naive Bayesian分类算法,但只适用于连续性特征值,以后有时间再将离散型的进行补充。此外,对于连续性特征值,本文处理的方式是假设这些特征值服从正态分布,计算每一列特征值的均值和方差,... -
机器学习模型3 朴素贝叶斯-基于Python sklearn的实现
2020-12-05 17:19:181、模型原理1、原理:基于概率论的方法,计算一个样本x属于某个类别c的概率最大,即计算P(c│x)的最大值,即样本x分到类别c中的概率最大1-1.png。2、计算步骤:第一步,通过条件概率,可以转化为1-2.png。但由于很多... -
python实现高斯朴素贝叶斯分类器
2021-02-12 06:39:15在这篇文章中,我们将使用我最喜欢的机器学习库scikit-learn在Python中实现朴素贝叶斯分类器。接下来,我们将使用经过训练的朴素贝叶斯(监督分类法)模型来预测人口收入。在朴素贝叶斯分类器的文章中我们讨论了贝叶斯... -
机器学习:伯努利朴素贝叶斯分类器(原理+python实现)
2021-01-06 21:29:19伯努利朴素贝叶斯分类器主要用于文本分类,下面我们以一个具体的例子,来讲述下伯努利朴素贝叶斯的原理和实现逻辑。 具体例子: 已知我们有八个句子以及每个句子对应的类别,即中性或侮辱性。那么再给出一个句子,... -
【python机器学习:朴素贝叶斯分类算法】
2022-04-02 16:01:03python机器学习:朴素贝叶斯分类算法 -
朴素贝叶斯的详细讲解及其Python实现
2020-10-23 20:19:32朴素贝叶斯概述 朴素贝叶斯法基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布,然后基于此模型,对给定的输入 X, 利用贝叶斯定理求出后验... -
朴素贝叶斯算法原理与Python实现
2021-06-05 17:24:35最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM)。和决策树模型相比,朴素贝叶斯分类器(Naive Bayes Classifier 或 NBC)发源于古典数学理论,有着坚实的... -
论文研究-基于粒子群的加权朴素贝叶斯入侵检测模型.pdf
2019-09-13 05:11:00针对传统朴素贝叶斯算法对高维复杂的入侵行为检测效率低下的状况,提出一种基于粒子群的加权朴素贝叶斯入侵检测模型。模型首先用粗糙集理论对样本属性特征集进行约简,再利用改进的粒子群算法优化加权朴素贝叶斯算法... -
python机器学习基础04——sklearn之朴素贝叶斯
2022-02-15 21:30:28文章目录朴素贝叶斯算法高斯模型多项式模型 朴素贝叶斯算法 相关重点处:https://blog.csdn.net/xiaoyoupei/article/details/122641753 贝叶斯思想,其实就是计算出条件概率(也就是某条件情况下,导致的结果的概率,...