爱数课:idatacourse.cn
领域:消费
简介:商品评论可以帮助购买用户更加了解产品,做出更优的购买决策,也可以帮助商家获知商品的优缺点,获取消费者的喜好。本次实验我们将学习中文商品情感判定,通过构建SVM模型和高斯朴素贝叶斯模型对商品评论进行分类。
数据:
./dataset/data.csv
./dataset/stopwords.txt
前言
任何行业领域,用户对产品的评价都显得尤为重要。用户在电商平台上面发布的产品评价中包含着用户的偏好信息,通过用户评论,可以对用户情感倾向进行判定,获得用户的情感以及对产品属性的偏好。互联网的发展极大提高了每个人的参与度,人们可以通过网络购物,可以通过手机点外卖等,许多人买完东西都会去填写几句简单的评价,而消费者在购买商品时,也会着重考虑其他用户的评价。例如目前最为普遍的网购行为:对于用户来说,参考评论可以做出更优的购买决策,能够更全面的去了解商品;对于商家来说,对商品评论按照情感倾向进行分类,并通过文本聚类得到普遍提及的商品优缺点,可以进一步改良产品。与此同时可以进一步利用智能推荐系统向用户推荐他们更喜欢的产品,以增加用户的黏性,挖掘一些潜在的利润。本案例主要讨论如何对商品评论进行情感倾向判定。
下图为某电商平台上针对某款手机的评论:
代码语言:javascript复制import jieba
import numpy as np
import pandas as pd
import sklearn
import matplotlib
import matplotlib.pyplot as plt
import pyecharts.options as opts
from pyecharts.charts import WordCloud
from pyecharts.charts import Bar
import re
#logging
2. 数据读取
2.1 读取数据
这份某款手机的商品评论信息数据集,包含2个属性,共计8186个样本。数据集描述如下:
列名 | 说明 | 类型 | 示例 |
---|---|---|---|
Comment | 对该款手机的评论 | String | 客服特别不负责,明明备注了也不看,发错了东西。 |
Class | 该评论的情感倾向: -1 ------ 差评 0 ------ 中评 1 ------ 好评 | Int | -1 |
使用Pandas
库中的read_excel
函数读取xls
格式的数据集文件,结果会保存为一个DataFrame或Series对象,调用使用DataFrame或Series对象的head()
方法查看可以查看前n行数据,默认为5。查看数据可以了解各个字段取值的具体情况,字段的名称等等,对数据有一个基础的了解。
#读入数据集
data = pd.read_csv("./dataset/data.csv")
data.head(5)
2.2 查看数据基本信息
使用shape()
方法查看数据集的行数及列数,了解数据集的大小。使用info()
方法打印DataFrame对象的摘要,包括列的数据类型dtype、名称以及有无缺失值,占用的内存等信息。
# 数据集的大小
data.shape
代码语言:javascript复制(8186, 2)
代码语言:javascript复制# 数据集的基本信息
data.info()
数据集大小为8186行,2列。从数据集的基本信息可以看到Comment
列有缺失值,但缺失数量极少。在后续进行数据预处理时,需要考虑对缺失值进行填充。
3. 数据预处理
在中文文本分析和情感分析的工作中,数据预处理的内容主要是分词,去除停用词。英文分词比较简单,见到空格和标点符号就说明是一个词汇,而中文分词就是将一句话拆分成一些词语,在Python中有专门的中文分词库jieba
库,使用jieba
库的cut()
函数专门对指定的文本内容进行分词。
3.1 分词
首先,我们去除Comment
列文本中的标点符号、数字、字母。然后通过jieba
库,对文本进行中文分词。只有经过分词处理后的文本数据集才可以进行下一步的向量化操作,满足输入模型的条件。
def remove_url(src):
# 去除标点符号、数字、字母
vTEXT = re.sub('[a-zA-Z0-9’!"#$%&'()* ,-./:;<=>?@,。?★、…【】╮  ̄ ▽  ̄ ╭\~⊙%;①():《》?“”‘’![\]^_`{|}~s] ', "", src)
return vTEXT
代码语言:javascript复制# 对数据集的每个样本的文本进行中文分词,如遇到缺失值,使用“还行 一般吧”进行填充
cutted = []
for row in data.values:
try:
text = remove_url(str(row[0])) #去除文本中的标点符号、数字、字母
raw_words = (" ".join(jieba.cut(text)))#分词
cutted.append(raw_words)
except AttributeError:
cutted.append("还行 一般吧")
cutted_array = np.array(cutted)
# 生成新数据文件,Comment字段为分词后的内容
data_cutted = pd.DataFrame({
'Comment': cutted_array,
'Class': data['Class']
})
代码语言:javascript复制data_cutted.head()#查看分词后的数据集
data_cutted
为进行分词之后的数据集,可以看到每条评论哦读背
3.2 查看关键词
此步骤我们先读取停用词文件,查看前100个停用词。其次使用jieba.analyse
中的set_stop_words
函数设置停用词。使用jieba.analyse
中的extract_tags
函数,提取句子中的关键词,显示好评、中评、差评中前30个关键词,可以帮助我们对各类评论有更好的理解,更直观的显示各类评论用户的情感倾向。
with open('./dataset/stopwords.txt', 'r', encoding='utf-8') as f:#读停用词表
stopwords = [item.strip() for item in f]
for i in stopwords[:100]:#读前100个停用词
print(i,end='')
代码语言:javascript复制#设定停用词文件,在统计关键词的时候,过滤停用词
import jieba.analyse
jieba.analyse.set_stop_words('./dataset/stopwords.txt')
代码语言:javascript复制# 好评关键词
keywords_pos = jieba.analyse.extract_tags(''.join(data_cutted['Comment'][data_cutted['Class'] == 1]),withWeight = True,topK=30)
for item in keywords_pos:
print(item[0],end=' ')
代码语言:javascript复制#中评关键词
keywords_med = jieba.analyse.extract_tags(''.join(data_cutted['Comment'][data_cutted['Class'] == 0]),withWeight = True,topK=30)
for item in keywords_med:
print(item[0],end=' ')
代码语言:javascript复制#差评关键词
keywords_neg = jieba.analyse.extract_tags(''.join(data_cutted['Comment'][data_cutted['Class'] == -1]),withWeight = True,topK=30)
for item in keywords_neg:
print (item[0],end=' ')
4. 可视化分析
在本环节中,我们将通过Python中的绘图库如Pyecharts,利用一系列可视化的手段,通过绘制柱状图的方式展示各类评论的的取值分布,通过绘制词云图的方式展示好评、中评、差评的关键词。
4.1 好评、中评、差评数量柱状图
代码语言:javascript复制# 不同类别数据记录的统计
class_num = (
Bar()
.add_xaxis(data_cutted['Class'].value_counts().index.tolist())
.add_yaxis("", data_cutted['Class'].value_counts().tolist(),color=['#4c8dae'])
.set_global_opts(title_opts=opts.TitleOpts(title="好评、中评、差评数量柱状图"))
)
class_num.render_notebook()
从柱状图可以看出标签1为好评,共3042人,标签-1为差评,共2657人,标签0为中评,共2487人。好评人数最多,中评人数最少。数据集中好评、中评、差评的人数相差并不大,取值分布较为均衡。
4.2 好评关键词词云图
对好评中的关键词通过绘制词云图的方式进行展示,查看好评用户对商品的评价。
代码语言:javascript复制wordcloud_pos = (
WordCloud()
.add(series_name="", data_pair=keywords_pos[:], word_size_range=[10, 66])
.set_global_opts(
title_opts=opts.TitleOpts(
title="好评关键词词云图", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
),
tooltip_opts=opts.TooltipOpts(is_show=True))
)
wordcloud_pos.render_notebook()
总体来说好评用户感觉商品不错,对商品很满意,很喜欢。同时也对商品是正品,有赠品,很漂亮,手机流畅,快递速度较快等感到满意。其中好评用户最常提到的是感觉商品不错,和商品是正品。
4.3 中评关键词词云图
代码语言:javascript复制wordcloud_med = (
WordCloud()
.add(series_name="", data_pair=keywords_med[:], word_size_range=[10, 66])
.set_global_opts(
title_opts=opts.TitleOpts(
title="中评关键词词云图", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
),
tooltip_opts=opts.TooltipOpts(is_show=True))
)
wordcloud_med.render_notebook()
总体来说中评用户对商品的评价有好有坏,觉得商品不错,但同时商品存在发热和充电等问题。
4.4 差评关键词词云图
代码语言:javascript复制wordcloud_neg = (
WordCloud()
.add(series_name="", data_pair=keywords_neg[:], word_size_range=[10, 66])
.set_global_opts(
title_opts=opts.TitleOpts(
title="差评关键词词云图", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
),
tooltip_opts=opts.TooltipOpts(is_show=True))
)
wordcloud_neg.render_notebook()
差评用户主要对售后服务,退换货等感到不满意。同时也提到了充电等问题。
通过分析用户的评论,我们可以发现,对于网购来说,商品本身的质量是非常关键的,对于手机来说人们关注手机的发热问题、流畅性、以及充电问题等,但同时售后服务,快递速度等问题也是人们关心的重要问题。
5. 文本向量化
经过分词之后的文本数据集要先进行向量化之后才能输入到分类模型中进行运算。TF-IDF
算法是常用的文本向量化算法。
TF-IDF
是Term Frequency-Inverse Document Frequency
的缩写,即“词频-逆文本频率”。它由两部分组成,TF
和IDF
。TF-IDF
是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
词频某个词在文章中的出现次数文章总词数
逆文档频率文章总数包含该词的文章数(分母加1,为了避免分母为0)
我们使用sklearn
库中的TfidfVectorizer
实现tf-idf
文本向量化。
# 实现向量化方法
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(stop_words = stopwords, ngram_range=(1, 3))
data_transform = vectorizer.fit_transform(data_cutted['Comment'].values.tolist()) #将文本向量化后的数据赋给data_transform
6. 模型构建
6.1 数据集划分
使用sklearn.model_selection
模块的train_test_split()
函数划分训练集和测试集。训练集:80%;测试集:20%。训练集用于训练模型,测试集用于评估模型性能。
from sklearn.model_selection import train_test_split #数据集划分
X_train, X_test, y_train, y_test = train_test_split(data_transform, data_cutted['Class'], random_state=10,test_size=0.2)
6.2 构建SVM模型
从sklearn.svm
中导入SVC
类,使用SVC
类初始化一个模型对象,命名为svc
,对svc
调用fit方法,带入训练集X_train,y_train进行训练。
from sklearn.svm import SVC
svc = SVC(kernel='linear', gamma=10 ** -5, C=1)
clf = svc.fit(X_train,y_train)
训练模型后,可以使用模型在测试集X_test上作出预测。从sklearn.metrics
中导入classification_report
分类报告用于模型评估,可以通过分类报告查看模型对于各类别的分类精确率、召回率、f1-score等。
from sklearn.metrics import classification_report
代码语言:javascript复制clf_prelabel = clf.predict(X_test)
print(classification_report(y_true=y_test,y_pred=clf_prelabel))
从分类报告来看,差评的精确率为0.68,召回率为0.73,中评的精确率为0.58,召回率为0.58。好评的精确率为0.87,召回率为0.82。模型最终的准确率为0.71。从分类报告可以看出对于中评的分类效果较差。是由于人在评论时,除非有问题否则一般都会打好评,如果打了中评说明对产品有不满意之处,在情感的表达上就会趋向于负向情感,同时评论具有很大主观性,很多中评会将其归为差评,但数据集中却认为是中评。因此,将一条评论分类为好评、中评、差评是不够客观,中评与差评之间的边界很模糊,因此识别率较低。
6.3 构建高斯朴素贝叶斯模型
从sklearn.naive_bayes
中导入GaussianNB
类,使用GaussianNB
类初始化一个模型对象,命名为gnb
,对gnb
调用fit方法,带入训练集X_train,y_train进行训练。
from sklearn.naive_bayes import GaussianNB
代码语言:javascript复制gnb = GaussianNB()
gnb_model = gnb.fit(X_train.toarray(),y_train)
训练模型后,可以使用模型在测试集X_test上作出预测。输出模型的分类报告用于模型评估,可以通过分类报告查看模型对于各类别的分类精确率、召回率、f1-score等。
代码语言:javascript复制gnb_prelabel = gnb_model.predict(X_test.toarray())
print(classification_report(y_true=y_test,y_pred=gnb_prelabel))
从分类报告来看,差评的精确率为0.64,召回率为0.53,中评的精确率为0.49,召回率为0.45。好评的精确率为0.68,召回率为0.83。模型最终的准确率为0.61。通过将SVM模型与构建的高斯朴素贝叶斯模型分类结果比较,可以看出SVM在分类的精确率、召回率,以及模型的准确率上都优于高斯朴素贝叶斯模型,因此情感分析更推荐SVM模型。
通过本案例,我们掌握了词云图进行可视化的方法,学习了文本向量化的知识,并了解了通过构建SVM模型和高斯朴素贝叶斯模型进行预测的方法。在用户情感分析判定中,可以构建SVM模型,预测用户评价的情感倾向,挖掘产品在各个维度的优劣,从而明确如何改进产品,指导产品更新迭代。
爱数课(iDataCourse)是一个面向院校的大数据和人工智能课程和资源平台。平台提供权威的课程资源、数据资源、案例实验资源,助力院校大数据和人工智能专业建设,课程建设和师资能力建设。