案例10:基于朴素贝叶斯的商品评论分析
为什么写本博客
前人种树,后人乘凉。希望自己的学习笔记可以帮助到需要的人。
需要的基础
懂不懂原理不重要,本系列的目标是使用python实现机器学习。
必须会的东西:python基础、numpy、pandas、matplotlib和库的使用技巧。
说明
完整的代码在最后,另外之前案例中出现过的方法不会再讲解。
目录结构
1. 涉及的新方法:
模型
from sklearn.naive_bayes import MultinomialNB
# 构建⻉叶斯算法分类器
model = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参
# 训练数据
model.fit(x_train, y_train)
词频统计
# 导包
from sklearn.feature_extraction.text import CountVectorizer
# 创建对象
con = CountVectorizer()
# 使用方法
X = con.fit_transform(comment_list) # 它通过 fit_transform 函数计算各个词语出现的次
name = con.get_feature_names() # 通过 get_feature_names()可获取词袋中所有⽂本的关键
'''
参数:
stop_words : 设置停用词,设为english将使用内置的英语停用词,设为一个list可自定义停用词,设为None不使用停用词。
'''
jieba库简单使用
# 导包
import jieba
# 对data数据进行切分
list_data = jieba.cut(data, cut_all=False)
# 参数:参数默认为 False,所有使⽤ cut ⽅法时默认为精确模式
2. 数据集介绍与下载:
这次使用的数据集来自于网上黑马,数据量不大,就12条,分为三列,第一列为id,第二列评价,第三列为标签(是否为好评)。
另外,这里它也提供了一个停用词文件,名叫stopwords.txt
,我把这两个数据文件放在网盘中了:
链接:https://pan.baidu.com/s/1-ajwu9m58l955ENSPeKWmQ
提取码:6666
3. 数据处理:
加载数据
首先,我们加载相关数据:(注意,由于有中文,所以需要声明编码方式为gbk格式)
# 加载数据
data = pd.read_csv('data/NB_data/comments.csv',encoding='gbk')
print(data.shape) # (13, 3)
然后,我们取出评价内容:
# 获取评价内容
contents = data['内容']
print(contents.head())
# 获取标签值
labels = data['评价'].values
print(labels)
打印结果:
0 从编程小白的角度看,入门极佳。
1 很好的入门书,简洁全面,适合小白。
2 讲解全面,许多小细节都有顾及,三个小项目受益匪浅。
3 前半部分讲概念深入浅出,要言不烦,很赞
4 看了一遍还是不会写,有个概念而已
Name: 内容, dtype: object
['好评' '好评' '好评' '好评' '差评' '差评' '差评' '差评' '差评' '好评' '差评' '差评' '差评']
将标签中文修改为数字值
其次,我们需要把“好评 / 差评” 修改为数字值,这里很简单,就自己来编写代码:
# 将标签的中文转为数字值
data.loc[data.loc[:, '评价'] == "好评",'标签数字值'] = 1
data.loc[data.loc[:, '评价'] == "差评",'标签数字值'] = 0
print(data)
打印结果为:
Unnamed: 0 内容 评价 标签数字值
0 0 从编程小白的角度看,入门极佳。 好评 1.0
1 1 很好的入门书,简洁全面,适合小白。 好评 1.0
2 2 讲解全面,许多小细节都有顾及,三个小项目受益匪浅。 好评 1.0
3 3 前半部分讲概念深入浅出,要言不烦,很赞 好评 1.0
4 4 看了一遍还是不会写,有个概念而已 差评 0.0
5 5 中规中矩的教科书,零基础的看了依旧看不懂 差评 0.0
6 6 内容太浅显,个人认为不适合有其它语言编程基础的人 差评 0.0
7 7 破书一本 差评 0.0
8 8 适合完完全全的小白读,有其他语言经验的可以去看别的书 差评 0.0
9 9 基础知识写的挺好的! 好评 1.0
10 10 太基础 差评 0.0
11 11 略_嗦。。适合完全没有编程经验的小白 差评 0.0
12 12 真的真的不建议买 差评 0.0
jieba分词
接着,我们需要使用jieba库来对内容进行分词:
comment_list = []
for tmp in contents:
# 对⽂本数据进⾏切割
# cut_all 参数默认为 False,所有使⽤ cut ⽅法时默认为精确模式
seg_list = jieba.cut(tmp, cut_all=False)
seg_str = ','.join(seg_list) # 拼接字符串
comment_list.append(seg_str) # ⽬的是转化成列表形式
# print(comment_list) # 查看comment_list列表。
打印结果为:
[' ,从,编程,小白,的,角度看,,,入门,极佳,。', '很,好,的,入门,书,,,简洁,全面,,,适合,小白,。', '讲解,全面,,,许多,小,细节,都,有,顾及,,,三个,小,项目,受益匪浅,。', '前半部,分讲,概念,深入浅出,,,要言不烦,,,很赞', '看,了,一遍,还是,不会,写,,,有个,概念,而已', '中规中矩,的,教科书,,,零,基础,的,看,了,依旧,看不懂', '内容,太,浅显,,,个人,认为,不,适合,有,其它,语言,编程,基础,的,人', '破书,一本', '适合,完完全全,的,小白读,,,有,其他,语言,经验,的,可以,去,看,别的,书', '基础知识,写,的,挺,好,的,!', '太,基础', '略,_,嗦,。,。,适合,完全,没有,编程,经验,的,小白', '真的,真的,不,建议,买']
词频统计
这里,我们需要使用自己的停用词典(即一些没有意义的词,统计的时候忽略他们,可以节省时间),因此首先需要定义处自己的停用词典列表:
# 加载停⽤词
stopwords=[]
with open('./data/NB_data/stopwords.txt','r',encoding='utf-8') as f:
lines=f.readlines()
for tmp in lines:
line=tmp.strip()
stopwords.append(line)
print(len(stopwords)) # 1893
接着,按照上面的方法进行词频统计:
# 进⾏统计词个数
con = CountVectorizer(stop_words=stopwords) # 将⽂本中的词语转换为词频矩阵
# 进⾏词数统计
X = con.fit_transform(comment_list) # 它通过 fit_transform 函数计算各个词语出现的次
name = con.get_feature_names() # 通过 get_feature_names()可获取词袋中所有⽂本的关键
print(X.toarray()) # 通过 toarray()可看到词频矩阵的结果
print(name)
打印结果为:
# 部分
[....
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0
0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0
0]]
['一本', '一遍', '三个', '中规中矩', '依旧', '入门', '内容', '分讲', '前半部', '受益匪浅', '基础', '基础知识', '完完全全', '小白', '小白读', '建议', '很赞', '教科书', '有个', '极佳', '概念', '浅显', '深入浅出', '看不懂', '真的', '破书', '简洁', '细节', '经验', '编程', '要言不烦', '角度看', '讲解', '语言', '适合', '项目', '顾及']
4. 模型训练和评估:
虽然数据很少,但是我们还是要划分,这里划分就不需要使用train_test_split
的方法了,直接使用我们自己的代码来实现即可:
# 准备训练集 这⾥将⽂本前10⾏当做训练集 后3⾏当做测试集
x_train = X.toarray()[:10, :]
y_train = labels[:10]
# 准备测试集
x_text = X.toarray()[10:, :]
y_text = labels[10:]
模型创建和训练:
# 构建⻉叶斯算法分类器
model = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参
# 训练数据
model.fit(x_train, y_train)
最后,进行模型的评估:
# 预测数据
y_predict = model.predict(x_text)
#预测值与真实值展示
print('预测值:',y_predict)
print('真实值:',y_text)
print('准确率:',model.score(x_text, y_text))
结果:
预测值: ['差评' '差评' '差评']
真实值: ['差评' '差评' '差评']
准确率: 1.0
5. 总结:
虽然,上面的准确率为百分百,但是不代表这个模型很好,大概率只是因为数据量太少的原因。后面,可以考虑写一个爬虫,去爬虫书籍网站的评价,然后可以自己做一个大一点的数据集(后面有机会,我会尝试实现)。
完整代码
# author: baiCai
# 导包
import jieba
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
# 加载数据
data = pd.read_csv('data/NB_data/comments.csv',encoding='gbk')
# print(data.shape) # (13, 3)
# 获取评价内容
contents = data['内容']
# print(contents.head())
# 获取标签值
labels = data['评价'].values
# print(labels)
# 将标签的中文转为数字值
data.loc[data.loc[:, '评价'] == "好评",'标签数字值'] = 1
data.loc[data.loc[:, '评价'] == "差评",'标签数字值'] = 0
# print(data)
# 分词
comment_list = []
for tmp in contents:
# 对⽂本数据进⾏切割
# cut_all 参数默认为 False,所有使⽤ cut ⽅法时默认为精确模式
seg_list = jieba.cut(tmp, cut_all=False)
seg_str = ','.join(seg_list) # 拼接字符串
comment_list.append(seg_str) # ⽬的是转化成列表形式
# print(comment_list) # 查看comment_list列表。
# 加载停⽤词
stopwords=[]
with open('./data/NB_data/stopwords.txt','r',encoding='utf-8') as f:
lines=f.readlines()
for tmp in lines:
line=tmp.strip()
stopwords.append(line)
# print(len(stopwords))
# 进⾏统计词个数
con = CountVectorizer(stop_words=stopwords) # 将⽂本中的词语转换为词频矩阵
# 进⾏词数统计
X = con.fit_transform(comment_list) # 它通过 fit_transform 函数计算各个词语出现的次
name = con.get_feature_names() # 通过 get_feature_names()可获取词袋中所有⽂本的关键
# print(X.toarray()) # 通过 toarray()可看到词频矩阵的结果
# print(name)
# 准备训练集 这⾥将⽂本前10⾏当做训练集 后3⾏当做测试集
x_train = X.toarray()[:10, :]
y_train = labels[:10]
# 准备测试集
x_text = X.toarray()[10:, :]
y_text = labels[10:]
# 构建⻉叶斯算法分类器
model = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参
# 训练数据
model.fit(x_train, y_train)
# 预测数据
y_predict = model.predict(x_text)
#预测值与真实值展示
print('预测值:',y_predict)
print('真实值:',y_text)
print('准确率:',model.score(x_text, y_text))
6. 本系列结语:
这10个小案例,基本上把最常见的几个机器学习算法包含了,当然,这些案例很多地方并不完美,比如决策树、集成学习那两节。后面,我会补上一两节博客,关于前面文章的修改和探讨。
另外,建议大家还是多深入原理去探究,不要纠结于代码实现。如果你特别熟悉python,那么在你熟悉原理的情况下,可以在短短几天时间内,轻松掌握相关实现方法。
最后,在我自己编写代码和学习的过程中,我发现算法很重要,但是也要重视数据处理方法,比如归一化、标准化、降维等等,这些方法很大程度上帮我们提到了模型的效率和准确率。
祝大家学习顺利,加油,今天也是南方小年,小年快乐。