朴素贝叶斯:朴素贝叶斯(Naive Bayes)是一个很简单但实用性很强的分类模型。朴素贝叶斯分类器会单独考量每一纬度特征被分类的条件概率,进而综合这些概率并对其所在的特征向量作出预测。因此,这个模型的基本数学假设是:各个纬度上的特征被分类的条件概率之间是相互独立的。
1.条件概率:就是指在事件B发生的情况下,事件A发生的概率,用
来表示。
2.全概率公式:
3.贝叶斯推断:
4.朴素贝叶斯推断:
数据描述:朴素贝叶斯模型有着广泛的实际应用环境,特别是在文本分类的任务中间,包括互联网新闻的分类、垃圾邮件的筛选等。
在scikit-learn中,提供了3中朴素贝叶斯分类算法:
GaussianNB(高斯朴素贝叶斯)、MultinomialNB(多项式朴素贝叶斯)、BernoulliNB(伯努利朴素贝叶斯)
5.高斯朴素贝叶斯:主要处理连续型变量的数据,它的模型假设是每一个维度都符合高斯分布(正态分布) sklearn.naive_bayes.GaussianNB(priors=None)
①利用GaussianNB类建立简单模型
import numpy as np
from sklearn.naive_bayes import GaussianNB
X = np.array([[-1,-1],[-2,-2],[-3,-3],[-4,-4],[-5,-5],[1,1],[2,2],[3,3]])
y = np.array([1,1,1,1,1,2,2,2])
clf = GaussianNB()#默认priors=None
clf.fit(X,y)
Out[11]: GaussianNB(priors=None)
②经过训练集训练后,观察各个属性值
clf.set_params(priors=[0.625,0.375])#设置priors参数值
clf.priors#获取各个类标记对应的先验概率
clf.class_prior_#返回的是数组,上面的返回列表
clf.class_count_#获取各类标记对应的训练样本数
clf.theta_#获取各类标记在各个特征值上的均值
clf.sigma_#获取各个类标记在各个特征上的方差
③方法
clf.get_params(deep=True)#返回priors与其参数值组成字典
set_params(**params)#设置估计器priors参数
fit(X,y,sample_weight=None)#训练样本,X表示特征向量,sample_weight表示权重
clf.fit(X,y,np.array([0.05,0.05,0.1,0.1,0.1,0.2,0.2,0.2]))#设置样本不同的权重
"""对于不平衡样本,类标记1在特征1均值及方差计算过程:均值= ((-1*0.05)+(-2*0.05)+(-3*0.1)+(-4*0.1+(-5*0.1)))/(0.05+0.05+0.1+0.1+0.1)=-3.375方差=((-1+3.375)**2*0.05 +(-2+3.375)**2*0.05+(-3+3.375)**2*0.1+(-4+3.375)**2*0.1+(-5+3.375)**2*0.1)/(0.05+0.05+0.1+0.1+0.1)=1.73437501"""
"""增量式训练,当训练数据集数据量非常大,不能一次性全部载入内存时,可以将数据集划分若干份,重复调用partial_fit在线学习模型参数,在第一次调用partial_fit函数时,必须制定classes参数,在随后的调用可以忽略"""
import numpy as np
from sklearn.naive_bayes import GaussianNB
X = np.array([[-1,-1],[-2,-2],[-3,-3],[-4,-4],[-5,-5],[1,1],[2,2],[3,3]])
y = np.array([1,1,1,1,1,2,2,2])
clf = GaussianNB()#默认priors=None
clf.partial_fit(X,y,classes=[1,2],sample_weight=np.array([0.05,0.05,0.1,0.1,0.1,0.2,0.2,0.2]))
clf.class_prior_
Out[33]: array([0.4, 0.6])
clf.predict([[-6,-6],[4,5]])#直接输出测试集预测的类标记
Out[35]: array([1, 2])
clf.predict_proba([[-6,-6],[4,5]])#输出测试样本在各类标记预测概率值
Out[38]:
array([[1.00000000e+00, 4.21207358e-40],
[1.12585521e-12, 1.00000000e+00]])
clf.predict_log_proba([[-6,-6],[4,5]])##输出测试样本在各个类标记上预测概率值对应的对数值
Out[39]:
array([[ 0.00000000e+00, -9.06654487e+01],
[-2.75124782e+01, -1.12621024e-12]])
#返回测试集样本映射到指定分类标记上的得分(准确率)
clf.score([[-6,-6],[-4,-4],[-3,-3],[4,5]],[1,1,2,2],sample_weight=[0.3,0.2,0.4,0.1])
Out[41]: 0.6
6.多项式朴素贝叶斯:
sklearn.naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
主要用于离散特征分类,例如文本分类单词统计,以出现的次数作为特征值
参数说明:
alpha:浮点型,可选项,默认1.0,添加拉普拉修/Lidstone平滑参数
fit_prior:布尔型,可选项,默认True,表示是否学习先验概率,
参数为False表示所有类标记具有相同的先验概率
class_prior:类似数组,数组大小为(n_classes,),默认None,类先验概率
①利用MultinomialNB建立简单模型
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0)
clf.fit(X,y)
Out[42]: MultinomialNB(alpha=2.0, class_prior=None, fit_prior=True)
②经过训练后,观察各个属性值class_log_prior_:各类标记的平滑先验概率对数值,其取值会受fit_prior和class_prior参数的影响
a、若指定了class_prior参数,不管fit_prior为True或False,class_log_prior_取值是class_prior转换成log后的结果
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=True,class_prior=[0.3,0.1,0.3,0.2])
clf.fit(X,y)
print(clf.class_log_prior_)
print(np.log(0.3),np.log(0.1),np.log(0.3),np.log(0.2))
clf1 = MultinomialNB(alpha=2.0,fit_prior=False,class_prior=[0.3,0.1,0.3,0.2])
clf1.fit(X,y)
print(clf1.class_log_prior_)
b、若fit_prior参数为False,class_prior=None,则各类标记的先验概率相同等于类标记总个数N分之一
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=False)
clf.fit(X,y)
print(clf.class_log_prior_)
print(np.log(1/4))
c、若fit_prior参数为True,class_prior=None,则各类标记的先验概率相同等于各类标记个数除以各类标记个数之和
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=True)
clf.fit(X,y)
print(clf.class_log_prior_)#按类标记1、2、3、4的顺序输出
print(np.log(2/6),np.log(1/6),np.log(2/6),np.log(1/6))intercept_:将多项式朴素贝叶斯解释的class_log_prior_映射为线性模型,其值和class_log_prior相同
clf.class_log_prior_
Out[7]: array([-1.09861229, -1.79175947, -1.09861229, -1.79175947])
clf.intercept_
Out[8]: array([-1.09861229, -1.79175947, -1.09861229, -1.79175947])feature_log_prob_:指定类的各特征概率(条件概率)对数值,返回形状为(n_classes, n_features)数组
clf.feature_log_prob_
Out[9]:
array([[-2.01490302, -1.45528723, -1.2039728 , -1.09861229],
[-1.87180218, -1.31218639, -1.178655 , -1.31218639],
[-1.74919985, -1.43074612, -1.26369204, -1.18958407],
[-1.79175947, -1.38629436, -1.23214368, -1.23214368]])
特征条件概率计算过程,以类为1各个特征对应的条件概率为例
clf.feature_log_prob_
Out[9]:
array([[-2.01490302, -1.45528723, -1.2039728 , -1.09861229],
[-1.87180218, -1.31218639, -1.178655 , -1.31218639],
[-1.74919985, -1.43074612, -1.26369204, -1.18958407],
[-1.79175947, -1.38629436, -1.23214368, -1.23214368]])
print(np.log((1+1+2)/(1+2+3+4+1+3+4+4+4*2)),np.log((2+3+2)/(1+2+3+4+1+
...: 3+4+4+4*2)),np.log((3+4+2)/(1+2+3+4+1+3+4+4+4*2)),np.log((4+4+2)/
(1+2+3+4+1+3+4+4+4*2)))
-2.01490302054 -1.45528723261 -1.20397280433 -1.09861228867
特征的条件概率=(指定类下指定特征出现的次数+alpha)/(指定类下所有特征出现次数之和+类的可能取值个数*alpha)coef_:将多项式朴素贝叶斯解释feature_log_prob_映射成线性模型,其值和feature_log_prob相同
clf.coef_
Out[11]:
array([[-2.01490302, -1.45528723, -1.2039728 , -1.09861229],
[-1.87180218, -1.31218639, -1.178655 , -1.31218639],
[-1.74919985, -1.43074612, -1.26369204, -1.18958407],
[-1.79175947, -1.38629436, -1.23214368, -1.23214368]])class_count_:训练样本中各类别对应的样本数,按类的顺序排序输出
clf.class_count_
Out[12]: array([ 2., 1., 2., 1.])feature_count_:各类别各个特征出现的次数,返回形状为(n_classes, n_features)数组
clf.feature_count_
Out[13]:
array([[ 2., 5., 7., 8.],
[ 2., 5., 6., 5.],
[ 6., 9., 11., 12.],
[ 2., 4., 5., 5.]])
③方法fit(X, y, sample_weight=None):根据X、y训练模型
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=True)
clf.fit(X,y)
Out[53]: MultinomialNB(alpha=2.0, class_prior=None, fit_prior=True)get_params(deep=True):获取分类器的参数,以各参数字典形式返回
clf.get_params(True)
Out[16]: {'alpha': 2.0, 'class_prior': None, 'fit_prior': True}partial_fit(X, y, classes=None, sample_weight=None):对于数据量大时,提供增量式训练,在线学习模型参数,参数X可以是类似数组或稀疏矩阵,在第一次调用函数,必须制定classes参数,随后调用时可以忽略
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=True)
clf.partial_fit(X,y,classes=[1,2])
clf.partial_fit(X,y)
Out[18]: MultinomialNB(alpha=2.0, class_prior=None, fit_prior=True)predict(X):在测试集X上预测,输出X对应目标值
clf.predict([[1,3,5,6],[3,4,5,4]])
Out[19]: array([1, 1])predict_log_proba(X):测试样本划分到各个类的概率对数值
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=True)
clf.fit(X,y) ...:
clf.predict_log_proba([[3,4,5,4],[1,3,5,6]])
Out[23]:
array([[-1.27396027, -1.69310891, -1.04116963, -1.69668527],
[-0.78041614, -2.05601551, -1.28551649, -1.98548389]])predict_proba(X):输出测试样本划分到各个类别的概率值
import numpy as np
from sklearn.naive_bayes import MultinomialNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[2,5,6,5],[3,4,5,6],[3,5,6,
6]])
y = np.array([1,1,4,2,3,3])
clf = MultinomialNB(alpha=2.0,fit_prior=True)
clf.fit(X,y)
clf.predict_proba([[3,4,5,4],[1,3,5,6]])
Out[2]:
array([[ 0.27972165, 0.18394676, 0.35304151, 0.18329008],
[ 0.45821529, 0.12796282, 0.27650773, 0.13731415]])score(X, y, sample_weight=None):输出对测试样本的预测准确率的平均值
clf.score([[3,4,5,4],[1,3,5,6]],[1,1])set_params(**params):设置估计器的参数
clf.set_params(alpha=1.0)
Out[4]: MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
7.伯努利朴素贝叶斯:sklearn.naive_bayes.BernoulliNB(alpha=1.0, binarize=0.0,
fit_prior=True,class_prior=None)类似于多项式朴素贝叶斯,也主要用户离散特征分类,和MultinomialNB的区别是:MultinomialNB以出现的次数为特征值,BernoulliNB为二进制或布尔型特性
参数说明:
binarize:将数据特征二值化的阈值
①利用BernoulliNB建立简单模型
import numpy as np
from sklearn.naive_bayes import BernoulliNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5]])
y = np.array([1,1,2])
clf = BernoulliNB(alpha=2.0,binarize = 3.0,fit_prior=True)
clf.fit(X,y)
Out[5]: BernoulliNB(alpha=2.0, binarize=3.0, class_prior=None, fit_prior=True)
经过binarize = 3.0二值化处理,相当于输入的X数组为
X = np.array([[0,0,0,1],[0,0,1,1],[0,1,1,1]])
②训练后查看各属性值class_log_prior_:类先验概率对数值,类先验概率等于各类的个数/类的总个数
clf.class_log_prior_feature_log_prob_ :指定类的各特征概率(条件概率)对数值,返回形状为(n_classes, n_features)数组
clf.feature_log_prob_
上述结果计算过程:
假设X对应的四个特征为A1、A2、A3、A4,类别为y1,y2,类别为y1时,特征A1的概率为:P(A1|y=y1) = P(A1=0|y=y1)*A1+P(A1=1|y=y1)*A1
import numpy as np
from sklearn.naive_bayes import BernoulliNB
X = np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5]])
y = np.array([1,1,2])
clf = BernoulliNB(alpha=2.0,binarize = 3.0,fit_prior=True)
clf.fit(X,y)
print(clf.feature_log_prob_)
print([np.log((2+2)/(2+2*2))*0+np.log((0+2)/(2+2*2))*1,np.log((2+2)/(2
+2*2))*0+np.log((0+2)/(2+2*2))*1,np.log((1+2)/(2+2*2))*0+np.log((1+2)/
(2+2*2))*1,np.log((0+2)/(2+2*2))*0+np.log((2+2)/(2+2*2))*1])class_count_:按类别顺序输出其对应的个数
clf.class_count_feature_count_:各类别各特征值之和,按类的顺序输出,返回形状为[n_classes, n_features] 的数组
clf.feature_count_
③方法:同MultinomialNB的方法类似
8. 默认参数下的多项式贝叶斯分类模型实例
##读取20类文本的数据细节
from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(subset='all')
#查验数据规模和细节
print(len(news.data))
print(news.data[0])
##20类新闻文本数据分割
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25,random_state=33) ##使用朴素贝叶斯分类器对新闻类文本进行类别预测
##将文本特征转化为向量化
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer()
X_train = vec.fit_transform(X_train)
X_test = vec.transform(X_test)
##初始化默认参数的贝叶斯模型
from sklearn.naive_bayes import MultinomialNB
mnb = MultinomialNB()
mnb.fit(X_train,y_train)
y_predict = mnb.predict(X_test)
##对贝叶斯分类器在新闻文本上的分类表现性能进行评估
from sklearn.metrics import classification_report
print('The accuracy of Naive Bayes classifier is',mnb.score(X_test,y_test))
print(classification_report(y_test,y_predict,target_names=news.target_names))
特点分析:朴素贝叶斯被广泛应用于海量互联网文本分类任务。由于其较强的特征条件独立假设,使得模型预测所需要估计的参数规模从幂指数级向线性量级减少,极大的节约了内存消耗和计算时间。但是正是由于这种强假设的限制,模型训练时无法将各个特征之间的联系考量在内,使得该模型在其他数据特征关联性较强的分类任务上的性能表现不佳。