简介
贝叶斯分类器主要思想是基于贝叶斯定理,是机器学习中重要的分类算法,适用于高维度的大数据集,速度快,准确率高,一个经典的应用场景是识别垃圾邮件。
首先需要知道一些概率论的知识:
- 先验概率 根据经验和分析得到的概率。
- 条件概率 事件B发生的前提下,事件A发生的概率。
- 后验概率 结果发生之后,推测原因的概率。
比如箱子里有4个小球,3个蓝色1个红色,且分别标有数字0和1:
那么我们很容易知道先验概率:
P(红)=
,P(蓝)=
P(0)=
,P(1)=
相应的条件概率:
P(1|蓝)=
,P(0|蓝)=
P(1|红)=
,P(0|红)=
比如P(1|蓝)表示抽中蓝色球的前提下,数字是1的概率。也就是3个蓝球中有两个为1。
往往困难的是后验概率的计算,比如知道结果是数字0,那导致结果(数字0)的条件(颜色)概率怎么计算?即P(蓝|0)和P(红|0)。
虽然这个例子的后验概率也能一眼看出,那假设不知道,又如何通过先验概率和条件概率进行求解呢?这就是贝叶斯定理解决的问题。
贝叶斯公式如下:
带入公式:
对应验证图中两个数字0的球中,1个蓝色,1个红色。
贝叶斯模型
设特征向量
有
个属性,即
,标签
有
个类,记为
,在训练样本中用极大似然法统计频率,从而学习到先验分布
,同样也可以学习到条件分布
。
对于新的测试数据
,利用贝叶斯公式,就可求得属于第
个类别
的概率:
最后比较属于各个类别的概率
,将概率最大的作为预测类别。
朴素贝叶斯
但是上述模型中存在一个头疼的问题:
很难求出,比如有50个特征,每个特征只有2个属性,那么特征排列组合得到的计算量都有
这么大。
为此朴素贝叶斯(naive bayes)采用了“属性条件独立性假设”,也就是考虑特征属性的取值互不干扰,是独立的。如果X和Y是相互独立的,那么由条件独立公式:
,得到朴素贝叶斯模型:
对于一个测试数据
,计算它在不同类别的概率,由于最后只需要比较大小,取概率最大的类,所以简化掉相同分母,得到表达式:
最后,在计算先验概率时,需要考虑不同的分布假设,比如离散值和连续值的参数求解是不一样的。包括高斯朴素贝叶斯、多项式朴素贝叶斯和伯努利朴素贝叶斯三种。
高斯朴素贝叶斯
高斯朴素贝叶斯的特征变量是连续型变量,样本符合高斯分布或正态分布。如人的身高。
使用正态分布的概率密度函数来算概率:
表示类别为
的样本中,特征
的均值;
表示类别为
的样本中,特征
的标准差;
使用sklearn库中GaussianNB()
创建高斯朴素贝叶斯模型:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.colors import ListedColormap
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import classification_report
import seaborn as sns
def plot_boundary(model, axis): # 画边界
x0, x1 = np.meshgrid(
np.linspace(axis[0], axis[1], int((axis[1] - axis[0]) * 100)).reshape(-1, 1),
np.linspace(axis[2], axis[3], int((axis[3] - axis[2]) * 100)).reshape(-1, 1),
)
X_new = np.c_[x0.ravel(), x1.ravel()]
y_predict = model.predict(X_new)
zz = y_predict.reshape(x0.shape)
custom_cmap = ListedColormap(['#A1FFA1', '#FFE9C5', '#FFB3E2', '#C6C6C6'])
plt.contourf(x0, x1, zz, cmap=custom_cmap)
# 创建数据:400个样本,2个特征,4个类别,方差3
X, y = make_blobs(400, 2, centers=4, cluster_std=3, center_box=(10, 30), random_state=20221026)
x_train, x_test, y_train, y_test = train_test_split(X, y) # 划分训练集测试集
gnb = GaussianNB() # 高斯朴素贝叶斯
gnb.fit(x_train, y_train) # 训练
y_pred = gnb.predict(x_test) # 测试
# 结果和相关参数
print('先验概率:', gnb.class_prior_)
print('标签:', gnb.classes_)
print('均值:', gnb.theta_)
print('方差:', gnb.sigma_)
print('预测概率:', gnb.predict_proba(x_test))
# 评估
print(classification_report(y_test, y_pred))
# 可视化
plot_boundary(gnb, axis=[4, 31, 4, 36]) # 边界
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='Accent') # 数据点
#cm = pd.crosstab(y_pred, y_test) # 混淆矩阵
#sns.heatmap(data=cm, annot=True, cmap='GnBu', fmt='d')
#plt.xlabel('Real')
#plt.ylabel('Predict')
plt.show()
多项式朴素贝叶斯
多项式朴素贝叶斯的特征变量是离散型变量,样本符合多项分布。如掷色子。
特征值不能是负数。
表示平滑系数;
表示属于类别
所有的样本数;
表示第
个特征中,属于类别
的样本数;
表示特征数量。
(
插播反爬信息)博主CSDN地址:https://wzlodq.blog.csdn.net/
使用sklearn库中MultinomialNB()
创建多项式朴素贝叶斯模型:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.colors import ListedColormap
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report
import seaborn as sns
def plot_boundary(model, axis): # 画边界
x0, x1 = np.meshgrid(
np.linspace(axis[0], axis[1], int((axis[1] - axis[0]) * 100)).reshape(-1, 1),
np.linspace(axis[2], axis[3], int((axis[3] - axis[2]) * 100)).reshape(-1, 1),
)
X_new = np.c_[x0.ravel(), x1.ravel()]
y_predict = model.predict(X_new)
zz = y_predict.reshape(x0.shape)
custom_cmap = ListedColormap(['#A1FFA1', '#FFE9C5', '#FFB3E2', '#C6C6C6'])
plt.contourf(x0, x1, zz, cmap=custom_cmap)
# 创建数据:400个样本,2个特征,4个类别,方差3
X, y = make_blobs(400, 2, centers=4, cluster_std=3, center_box=(10, 30), random_state=20221026)
x_train, x_test, y_train, y_test = train_test_split(X, y) # 划分训练集测试集
mnb = MultinomialNB() # 多项式朴素贝叶斯
mnb.fit(x_train, y_train) # 训练
y_pred = mnb.predict(x_test) # 测试
# 结果和相关参数
print('标签:', mnb.classes_)
print('预测概率:', mnb.predict_proba(x_test))
# 评估
print(classification_report(y_test, y_pred))
# 可视化
plot_boundary(mnb, axis=[4, 31, 4, 36]) # 边界
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='Accent') # 数据点
#cm = pd.crosstab(y_pred, y_test) # 混淆矩阵
#sns.heatmap(data=cm, annot=True, cmap='GnBu', fmt='d')
#plt.xlabel('Real')
#plt.ylabel('Predict')
plt.show()
伯努利朴素贝叶斯
伯努利朴素贝叶斯的特征变量是布尔型变量,样本符合二项分布或0-1分布。如抛硬币、特征词是否在文本中出现。
特征值只有两个结果0和1,如果不是的话,需要进行二值化处理。
表示平滑系数;
表示属于类别
所有的样本数;
表示第
个特征中,属于类别
的样本数。
使用sklearn库中BernoulliNB()
创建伯努利朴素贝叶斯模型。
由于特征属性要二值化处理,前面的数据不利于展示其特长,以文本分类为例介绍(涉及TF-IDF算法可我参考这篇博客)
代码语言:javascript复制import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import classification_report
import seaborn as sns
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
news = fetch_20newsgroups() # 读数据
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target,) # 划分训练集测试集
transfer = TfidfVectorizer() # TF-IDF抽取文本特征
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
print("抽取特征:n", transfer.get_feature_names_out())
bnb = BernoulliNB() # 伯努利朴素贝叶斯
bnb.fit(x_train, y_train) # 训练
y_pred = bnb.predict(x_test) # 测试
# 结果和相关参数
print('标签:', bnb.classes_)
print('预测概率:', bnb.predict_proba(x_test))
# 评估
print(classification_report(y_test, y_pred))
# 可视化
cm = pd.crosstab(y_pred, y_test) # 混淆矩阵
sns.heatmap(data=cm, annot=True, cmap='GnBu', fmt='d')
plt.xlabel('Real')
plt.ylabel('Predict')
plt.title('Bernoulli Naive Bayes')
plt.show()
也可以用多项式朴素贝叶斯,都是离散值。
小结
高斯NB用于连续值;多项式NB用于离散的多值;伯努利NB用于离散的二值。
贝叶斯分类器先对联合概率P(X|Y)建模,然后再由此得到P(Y|X),属于「生成式模型」。而通过训练属性X直接建模P(Y|X)的模型成为「判别式模型」,如支持向量机、决策树、感知机等都是判别式模型。
本文介绍了贝叶斯分类器中最常用的朴素贝叶斯,更多的,还有半朴素贝叶斯、贝叶斯网等,感兴趣可深究。
原创不易,请勿转载(
本不富裕的访问量雪上加霜) 博主首页:https://wzlodq.blog.csdn.net/ 来都来了,不评论两句吗