伯努利贝叶斯分类器的应用

伯努利贝叶斯分类器的应用

  用户对其购买的蚊帐进行评论,该数据集是通过爬虫的方式获得,一共包含10644条评论,数据集中的Type变量为评论者所对应的情绪。首先将爬虫获得的数据集读入Python中,并预览前几行数据,代码如下:

# 读入评论数据
evaluation = pd.read_excel('datasource/Contents.xlsx')

# 查看数据的前10行,见表1
evaluation.head(10)

图1:数据的前10行预览
图1: 数据的前10行预览
  如表1所示,数据集包含4个字段,分别为用户昵称、评价时间、评价内容和对应的评价情绪。从评价内容来看,会有一些“脏”文本在内,如数字、英文等,所以需要将这些“脏”文本删除,代码如下:

# 运用正则表达式,将评论中的数字和英文去除
evaluation.Content = evaluation.Content.str.replace('[0-9a-zA-Z]', '')
evaluation.head()

图2:文本数据清洗后的前5行预览
图2:文本数据清洗后的前5行预览
  经过数据的初步清洗后,下一步要做的就是对文本进行切词,但在切词前,通常需要引入用户自定义的词库和停止词。利用词典的目的是将无法正常切割的词实现正确切割(如“沙瑞金书记”会被切词为“沙”“瑞金”“书记”,为了避免这种情况,就需要将类似“沙瑞金”这样的词组合为词库),使用停止词的目的是将句子中的无意义的词语删除(如“的”“啊”“我们”等)。

# 导入第三方库
import jieba

# 加载自定义词库
jieba.load_userdict('datasource/all_words.txt')
# 读入停止词
with open ('datasource/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)
words[:5]
out:
0		想 卖家 给我发 错货 四个 连接 铁通 块钱 便宜 廉价 退货
1		垃圾 \n 钳子 摄细 装 \n 管子 很软 \n 评价         垃圾
2		我就 无语 难弄 .. 说明书 .. 过段 差评 ..
3		不满意 写 落地 差一截 垂度 ~ 夹子 夹 没有 超市 买 质量好 换季 卖得 价钱 便宜
4		标的 到达 快递 四天 蚊帐 底座 太小 管壁 太薄 蚊帐 也没 宣传 垂地 购物 失败
Name: Content, dtype: object

  如上结果所示,通过调入第三方包jieba实现中文的切词,并在切词过程中加入自定义词库和删除停止词。接下来利用如上的切词结果,构造文档词条矩阵,矩阵的每一行代表一个评论内容,矩阵的每一列代表切词后的词语,矩阵的元素为词语在文档中出现的频次。代码如下:

# 导入第三方包
from sklearn.feature_extraction.text import CountVectorizer

# 计算每个词在各评论内容中的次数, 忽略出现在少于1%的文档中的术语
counts = CountVectorizer(min_df=0.01)
# 文档词条矩阵
dtm_counts = counts.fit_transform(words).toarray()
# 矩阵的列名称
columns = counts.get_feature_names()
# 将矩阵转换为数据框, 即X变量
X = pd.DataFrame(data=dtm_counts, columns=columns)
# 情感标签变量
y = evaluation.Type
X.head()

图3:切词后构成的文档——词条矩阵
图3: 切词后构成的文档——词条矩阵
  如表3所示,将文档词条矩阵转换为数据框后得到一个庞大的稀疏矩阵,即数据框中的大部分值为0。为了避免数据框的列数过多,在构造文档词条矩阵时做了相应的限制条件,即下列代码:

# 计算每个词在各评论内容中的次数, 忽略出现在少于1%的文档中的术语
counts = CountVectorizer(min_df=0.01)

表示词语所对应的文档数目必须在所有文档中至少占1%的比例,最终得到表3所呈现的99个变量。有了如上的数据框,接下来要做的就是将数据集拆分为训练集和测试集,并利用训练集构建伯努利贝叶斯分类器,利用测试集对分类器的预测效果进行评估,具体代码如下:

# 导入sklearn所需的模块
from sklearn import model_selection
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.25, random_state=1)
# 导入伯努利贝叶斯模块
from sklearn.naive_bayes import BernoulliNB
# 构建伯努利贝叶斯分类器
bnb = BernoulliNB()
# 模型在训练数据集上的拟合
bnb.fit(X_train, y_train)
# 模型在测试数据集上的预测
bnb_pred = bnb.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(bnb_pred, y_test)
# 导入seaborn
import seaborn as sns
# 绘制混淆矩阵图
sns.heatmap(data=cm, annot=True, cmap='GnBu', fmt='d')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()

图4:混淆矩阵的可视化展现
图4: 混淆矩阵的可视化展现
模型的预测准确率代码如下:

from sklearn import metrics

# 模型的预测准确率
print('模型的准确率为: \n',metrics.accuracy_score(y_test, bnb_pred))
print('模型的评估报告: \n',metrics.classification_report(y_test, bnb_pred))
模型的准确率为: 
0.8467317806160781
模型的评估报告: 
          			 precision    recall  f1-score   support

Negative       			0.82      0.89      0.85      1341
Positive      	 		0.88      0.80      0.84      1321

accuracy       			                    0.85      2662
macro avg     		    0.85      0.85      0.85      2662
weighted avg      	    0.85      0.85      0.85      2662

  如上结果所示,从混淆矩阵图形来看,伯努利贝叶斯分类器在预测数据集上的效果还是非常棒的,绝大多数的样本都被预测正确(因为主对角线上的数据非常大),而且总的预测准确率接近85%;从模型的评估报告来看,预测为消极情绪的覆盖率0.89相比于积极情绪的覆盖率0.8要更高一些,但总体来说模型的预测效果还是不错的。同理,在绘制一下关于模型在测试数据集上的ROC曲线,代码如下:

# 计算正例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()

图5:伯努利贝叶斯分类器的ROC曲线
图5: 伯努利贝叶斯分类器的ROC曲线
  如图5所示,绘制的ROC曲线所对应的AUC值为0.92,同样是一个非常高的数值,再结合模型准确率、覆盖率等指标,可以认为该模型在测试数据集上的预测效果是非常理想的。

小结:

  本章主要介绍了伯努利贝叶斯分类器的应用,还有另外两种朴素贝叶斯分类器:高斯贝叶斯分类器和多项式贝叶斯分类器。这三种分类器的选择主要依赖于自变量X数据的类型。如果自变量X均为连续的数值型,则需要选择高斯贝叶斯分类器;如果自变量X均表示为离散的数据类型,则需要选择多项式贝叶斯分类器;如果自变量X为0-1二元值,则需要选择伯努利贝叶斯分类器。朴素贝叶斯分类器的核心假设为自变量之间是条件独立的,该假设的主要目的是为了提高算法的运算效率,如果实际数据集中的自变量不满足独立性假设时,分类器的预测结果往往会产生错误。

源文件及完整代码

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值