Python大数据分析——朴素贝叶斯模型
- 数学方面
- 思路
- 理论基础
- 高斯贝叶斯分类器
- 多项式贝叶斯分类器
- 伯努利贝叶斯分类器
- 代码部分
- 高斯贝叶斯——皮肤识别
- 多项式贝叶斯——毒蘑菇识别
- 伯努利贝叶斯——情感分析
数学方面
思路
该分类器的实现思想非常简单,即通过已知类别的训练数据集,计算样本的先验概率,然后利用贝叶斯概率公式测算未知类别样本属于某个类别的后验概率,最终以最大后验概率所对应的类别作为样本的预测值。
理论基础
比如在已知收入X的情况下,Ci是购买还是不购买的概率
P(buy|X)=? P(not buy|X)=?
高斯贝叶斯分类器
如果数据集中的自变量X均为连续的数值型,则在计算P(X I Ci)时会假设自变量X服从高斯正态分布,所以自变量X的条件概率可以表示成:
μ平均值;σ标准差;exp是根号;
假设某金融公司是否愿意给客户放贷会优先考虑两个因素,分别是年龄和收入。现在根据已知的数据信息考察一位新客户,他的年龄为24岁,并且收入为8500元,请问该公司是否愿意给客户放贷?
数据如图所示:
我们通过数学的方式计算一下:
被预测为不经过上面的计算可知,当客户的年龄为24岁,并且收入为8500时,放贷的概率是4.8079x10-8,放贷的概率为2.1479x10-6,所以根据argmax P(Ci)P(X I Ci)的原则,最终该金融公司决定给客户放贷。
多项式贝叶斯分类器
例子:
假设影响女孩是否参加相亲活动的重要因素有三个,分别是男孩的职业、受教育水平和收入状况;如果女孩参加相亲活动,则对应的Meet变量为1,否则为0。请问在给定的信息下,对于高收入的公务员,并且其学历为硕士的男生来说,女孩是否愿意参与他的相亲?
加了平滑系数α=1,在这里面n的样本类别为2.
经计算发现,当男生为高收入的公务员,并且受教育水平也很高时,女生愿意见面的概率约为0.0703不愿意见面的概率约为0.0056。
所以根据argmaxP(Ci)P(XICi)的原则,最终女生会选择参加这位男生的相亲。
伯努利贝叶斯分类器
例子:
假设对10条评论数据做分词处理后,矩阵中含有5个词语和1个表示情感的结果,其中类别为0表示正面情绪,1表示负面情绪。如果一个用户的评论中仅包含“还行”一词,请问该用户的评论属于哪种情绪?
结果所示,当用户的评论中只含有“还行”一词时,计算该评论为正面情绪的概率约为0.015,评论为负面情绪的概率约为0.00073,故根据贝叶斯后验概率最大原则将该评论预判为正面情绪。
代码部分
高斯贝叶斯——皮肤识别
- 导入数据并做处理
# 导入第三方包
import pandas as pd
# 读入数据
skin = pd.read_excel(r'D:\pythonProject\data\Skin_Segment.xlsx')
# 设置正例和负例
skin.y = skin.y.map({2:0,1:1}) # 做了一个映射表示,将2映射到0;1映射到1
skin.y.value_counts()
输出:
y
0 194198
1 50859
Name: count, dtype: int64
# 导入第三方模块
from sklearn import model_selection
# 样本拆分
X_train,X_test,y_train,y_test = model_selection.train_test_split(skin.iloc[:,:3], skin.y, test_size = 0.25, random_state=1234)
- 进行预测
# 导入第三方模块
from sklearn import naive_bayes
# 调用高斯朴素贝叶斯分类器的“类”
gnb = naive_bayes.GaussianNB()
# 模型拟合
gnb.fit(X_train, y_train)
# 模型在测试数据集上的预测
gnb_pred = gnb.predict(X_test)
# 各类别的预测数量
pd.Series(gnb_pred).value_counts()
输出:
0 50630
1 10635
Name: count, dtype: int64
预测0是5w个;1是1w个
- 查看下评估结果
# 导入第三方包
from sklearn import metrics
import matplotlib.pyplot as plt
import seaborn as sns
# 构建混淆矩阵
cm = pd.crosstab(gnb_pred,y_test)
# 绘制混淆矩阵图
sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()
print('模型的准确率为:\n',metrics.accuracy_score(y_test, gnb_pred))
print('模型的评估报告:\n',metrics.classification_report(y_test, gnb_pred))
输出:
发现模型评估结果还是比较高的。
也可以坐下ROC曲线
# 计算正例的预测概率,用于生成ROC曲线的数据
y_score = gnb.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
输出:
大于0.8,认为我们的模型是合理的
多项式贝叶斯——毒蘑菇识别
MultinomialNB(alpha =1.0, fit_prior = True, class_prior = None)
alpha: 用于指定平滑系数a的值,默认为1.0
fit_prior: bool类型参数,是否以数据集中各类别的比例作为P(Ci)的先验概率,默认为True
class_prior:用于人工指定各类别的先验概率P(Ci),如果指定该参数,则参数fit_prior不再有效
- 查看数据
# 导入第三方包
import pandas as pd
# 读取数据
mushrooms = pd.read_csv(r'D:\pythonProject\data\mushrooms.csv')
# 数据的前5行
mushrooms.head()
输出:
我们发现蘑菇有21个x,并且都是字符型的离散型变量,所以给选择多项式模型,我们需要转化成数字类型变量
- 数据处理
# 将字符型数据作因子化处理,将其转换为整数型数据
columns = mushrooms.columns[1:]
for column in columns:
mushrooms[column] = pd.factorize(mushrooms[column])[0]
mushrooms.head()
输出:
from sklearn import model_selection
# 将数据集拆分为训练集合测试集
Predictors = mushrooms.columns[1:]
X_train,X_test,y_train,y_test = model_selection.train_test_split(mushrooms[Predictors], mushrooms['type'], test_size = 0.25, random_state = 10)
- 预测结果
from sklearn import naive_bayes
from sklearn import metrics
import seaborn as sns
import matplotlib.pyplot as plt
# 构建多项式贝叶斯分类器的“类”
mnb = naive_bayes.MultinomialNB()
# 基于训练数据集的拟合
mnb.fit(X_train, y_train)
# 基于测试数据集的预测
mnb_pred = mnb.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(mnb_pred,y_test)
# 绘制混淆矩阵图
sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()
# 模型的预测准确率
print('模型的准确率为:\n',metrics.accuracy_score(y_test, mnb_pred))
print('模型的评估报告:\n',metrics.classification_report(y_test, mnb_pred))
from sklearn import metrics
# 计算正例的预测概率,用于生成ROC曲线的数据
y_score = mnb.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test.map({'edible':0,'poisonous':1}), y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
伯努利贝叶斯——情感分析
BernoulliNB (alpha =1.0, binarize=0.0, fit prior = True, class prior = None)
alpha: 用于指定平滑系数a的值,默认为1.0
binarize: 如果该参数为浮点型数值,则将以该值为界限,当自变量的值大于该值时,自变量的值将被转换为1,否则被转换为0;如果该参数为None时,则默认训练数据集的自变量均为0-1值
fit prior: bool类型参数,是否以数据集中各类别的比例作为P(Ci)的先验概率,默认为True
class prior: 用于人工指定各类别的先验概率P(Ci),如果指定该参数,则参数fit prior不再有效
- 查看数据
import pandas as pd
# 读入评论数据
evaluation = pd.read_excel(r'D:\pythonProject\data\Contents.xlsx',sheet_name=0)
# 查看数据前10行
evaluation.head(10)
输出:
- 数据处理
# 运用正则表达式,将评论中的数字和英文去除
evaluation.Content = evaluation.Content.str.replace('[0-9a-zA-Z]','')
evaluation.head()
# 导入第三方包(切词的功能包)
import jieba
# 加载自定义词库(通过自定义词库更好的切词)
jieba.load_userdict(r'D:\pythonProject\data\all_words.txt')
# 读入停止词(比如虚词,感叹词等)
with open(r'D:\pythonProject\data\mystopwords.txt', encoding='UTF-8') as words:
stop_words = [i.strip() for i in words.readlines()]
# 构造切词的自定义函数,并在切词过程中删除停止词
def cut_word(sentence):
words = [i for i in jieba.lcut(sentence) if i not in stop_words]
# 切完的词用空格隔开
result = ' '.join(words)
return(result)
# 对评论内容进行批量切词
words = evaluation.Content.apply(cut_word)
# 前5行内容的切词效果
words[:5]
- 做文档词条矩阵
# 导入第三方包
from sklearn.feature_extraction.text import CountVectorizer
# 计算每个词在各评论内容中的次数,并将稀疏度为99%以上的词删除(就是该词在99%的文档都没出现过的我们直接舍弃不要)
counts = CountVectorizer(min_df = 0.01)
# 文档词条矩阵
dtm_counts = counts.fit_transform(words).toarray()
# 矩阵的列名称
columns = counts.get_feature_names_out()
# 将矩阵转换为数据框--即X变量
X = pd.DataFrame(dtm_counts, columns=columns)
# 情感标签变量
y = evaluation.Type
X.head()
- 准确度
from sklearn import model_selection
from sklearn import naive_bayes
from sklearn import metrics
import matplotlib.pyplot as plt
import seaborn as sns
# 将数据集拆分为训练集和测试集
X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.25, random_state=1)
# 构建伯努利贝叶斯分类器
bnb = naive_bayes.BernoulliNB()
# 模型在训练数据集上的拟合
bnb.fit(X_train,y_train)
# 模型在测试数据集上的预测
bnb_pred = bnb.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(bnb_pred,y_test)
# 绘制混淆矩阵图
sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()
# 模型的预测准确率
print('模型的准确率为:\n',metrics.accuracy_score(y_test, bnb_pred))
print('模型的评估报告:\n',metrics.classification_report(y_test, bnb_pred))
# 计算正例Positive所对应的概率,用于生成ROC曲线的数据
y_score = bnb.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test.map({'Negative':0,'Positive':1}), y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()