手机评论文本挖掘与数据分析(Python)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手机评论文本挖掘与数据分析(Python)相关的知识,希望对你有一定的参考价值。
参考技术A 目的各大电商竞争越来激烈,为了提升客户服务质量,除了打价格战外,了解客户的需求点,对消费者的文本评论进行数据挖掘,倾听客户的心声越来越重要。
工具
1、贝壳采集器
2、Google浏览器
3、Python3.7 + Pycharm
数据采集
①本文对京东平台的手机进行爬虫,首先进入京东商城,选择一款手机,这里以华为Mate 30 Pro 5G为例
②在采集平台输入网址,点击贝壳采集开始配置信息
③因为是采集评论所以还需要进行下预操作配置切换页面:点击预操作按钮-->添加点击元素按钮-->左键点击流程图中添加元素按钮(悬浮显示操作键)-->点击悬浮显示操作键<选择按钮> -->点击网页商品评论TAB页切换按钮 -->点击保存
④没有识别出评论信息,手工操作下:清空字段-->更改页面类型为手工识别列表 --> 选中两个一样元素(这里两个用户名称) -->下一页未自动识别成功-->更改分页类型为手动点击下一页-->配置完成-->开始采集
数据预处理
当我们通过爬虫获取到我们想要的数据之后,进行简单的观察,可以发现评论的一些特点:
文本短,基本上大量的评论就是一句话.
情感倾向明显:明显的词汇如”好” “可以”
语言不规范:会出现一些网络用词,符号,数字等
重复性大:一句话出现词语重复
数据量大.
故我们需要对这些数据进行数据预处理
数据预处理包括:去重、分词等
下面我们将进行数据清洗
import jieba
#评论内容进行去重
def quchong(infile, outfile):
infopen = open(infile, 'r', encoding='utf-8')
outopen = open(outfile, 'w', encoding='utf-8')
lines = infopen.readlines()
list_1 = []
for line in lines:
if line not in list_1:
list_1.append(line)
outopen.write(line)
infopen.close()
outopen.close()
quchong("E:/comments/华为P30.txt", "E:/comments/P30去重.txt")
# jieba.load_userdict('userdict.txt')
#创建停用词list
def stopwordslist(filepath):
stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
return stopwords
#对评论内容进行分词
def seg_sentence(sentence):
sentence_seged = jieba.cut(sentence.strip())
stopwords = stopwordslist('stopwords.txt') #这里加载停用词的路径
outstr = ''
for word in sentence_seged:
if word not in stopwords:
if word != '\t':
outstr += word
outstr += " "
return outstr
inputs = open('E:/comments/P30去重.txt', 'r', encoding='utf-8')
outputs = open('E:/comments/P30分词.txt', 'w')
for line in inputs:
line_seg = seg_sentence(line) #这里的返回值是字符串
outputs.write(line_seg + '\n')
outputs.close()
inputs.close()
print('分词完毕')
数据分析
上面我们已经通过去重和jieba分词将爬取的内容进行了预处理,接下来就开始对处理过的数据进行分析,包括词频统计、关键词提取以及词云的生成等
#词频统计
import jieba.analyse
from collections import Counter #词频统计
with open('E:/comments/P30分词.txt', 'r', encoding='utf-8') as fr:
data = jieba.cut(fr.read())
data = dict(Counter(data))
with open('E:/comments/P30词频.txt', 'w', encoding='utf-8') as fw: # 读入存储wordcount的文件路径
for k, v in data.items():
fw.write('%s, %d\n' % (k, v))
import jieba.analyse
import matplotlib.pyplot as plt
from wordcloud import WordCloud
#生成词云
with open('E:/comments/P30词频.txt') as f:
#提取关键词
data = f.read()
keyword = jieba.analyse.extract_tags(data, topK=50, withWeight=False)
wl = " ".join(keyword)
#设置词云
wc = WordCloud(
#设置背景颜色
background_color = "white",
#设置最大显示的词云数
max_words=2000,
#这种字体都在电脑字体中,一般路径
font_path='C:/Windows/Fonts/simfang.ttf',
height=1200,
width=1600,
#设置字体最大值
max_font_size=100,
#设置有多少种随机生成状态,即有多少种配色方案
random_state=30,
)
myword = wc.generate(wl) #生成词云
#展示词云图
plt.imshow(myword)
plt.axis("off")
plt.show()
wc.to_file('E:/comments/P30.png') #把词云保存下
Python——用户评论情绪分析
介绍
在该节中我们将对用户产生的真实评论数据进行情绪分析。
知识点
- 文本分词
- Word2Vec 方法
- 决策树分类
本文所涉及到情绪分析,又称为文本情绪分析,这是自然语言处理和文本挖掘过程中涉及到的一块内容。简而言之,我们通过算法去判断一段文本、评论的情绪偏向,从而快速地了解表达这段文本的原作者的主观情绪。
现实中,当我们在陈述一段内容时,可能会出现的情绪有:高兴、兴奋、激动、没感觉、失落、压抑、紧张、疑惑等。而在自然语言处理的世界里,我们尚且达不到如此细小的分类。所以,往往在针对文本进行情绪分析时,只处理两种情绪状态:积极和消极。
当然,上面提到的计算机无法处理更细分的情绪类别其实并不准确。因为,算法原则上是能够区分更多的情绪类别,关键在于我们需要提供一个人工标注过的复杂情绪训练集,而这是非常难做到的。所以,目前我们在进行情绪分析时,只处理积极和消极两种状态。
基于词典的方法
目前,针对文本情绪分析的方法有两种,一种基于词典,另一种基于机器学习方法。首先,我们来叙述一下基于词典的文本情绪分析原理。
基于词典的情绪分析是非常简单和易于理解的一种方法。概括来讲,我们首先有一个人工标注好的词典。词典中的每一个此都对应这消极或积极的标签。词典举例如下:
词语 | 标签 |
---|---|
很好 | 积极 |
不好 | 消极 |
高兴 | 积极 |
难受 | 消极 |
爱你 | 积极 |
讨厌 | 消极 |
…… | …… |
然后,这个词典可能有上万条或者几十万条,当然是越多越好。有了词典之后,我们就可以开始进行文本情绪分析了。
现在,我们收到一条用户评论:
这门课程很好啊!
然后,我们可以对这句话进行分词。分词结果如下:
[‘这门‘, ‘课程‘, ‘很‘, ‘好‘, ‘啊‘, ‘!‘]
接下来,我们拿分好的词依次去匹配词典。匹配的方法很简单:
- 如果词典中存在该词且为积极标签,那么我们记 +1+1;
- 如果词典中存在该词且为消极标签,那么我们记 -1?1;
- 如果词典中不存在该词,我们记 00。
匹配完一个句子之后,我们就可以计算整个句子的得分。总得分 >0>0 表示该句子情绪为积极,总得分小于零代表该句子为消极,总得分 =0=0 表示无法判断情绪。通过词典进行情绪分析的方法很简单,但缺点也很明显。我们往往需要一个很大的词典,且不断更新。这对人力物力都是极大的考验。
除此之外,该方法还有无法通过扩充词典解决的情绪判断问题。例如,当我们人类在判断一句话的清晰时,我们会往往更偏向于从整体把握(语言环境),尤其是在乎一些语气助词对情绪的影响。而基于词典进行情绪分析的方法就做不到这一点,将句子拆成词,就会影响句子的整体情绪表达。
目前,针对中文做情绪标注的词典少之又少。比较常用的有:
- 台湾大学 NTUSD 情绪词典。
- 《知网》情绪分析用 词语集。
以《知网》情绪词典举例,它包含有 5 个文件,分别列述了正面与负面的情绪词语以及程度词汇。
- “正面情感”词语,如:爱,赞赏,快乐,感同身受,好奇,喝彩,魂牵梦萦,嘉许 ...
- “负面情感”词语,如:哀伤,半信半疑,鄙视,不满意,不是滋味儿,后悔,大失所望 ...
- “正面评价”词语,如:不可或缺,部优,才高八斗,沉鱼落雁,催人奋进,动听,对劲儿 ...
- “负面评价”词语,如:丑,苦,超标,华而不实,荒凉,混浊,畸轻畸重,价高,空洞无物 ...
- “程度级别”词语,
- “主张”词语
由于上面介绍的这种简单的词典对比方法准确率并不高,所以本不会通过这种方法来实现用户评论情绪分析。
基于词袋或 Word2Vec 的方法
词袋模型
除了基于词典对评论进行情绪分析,我们还有一种方法称之为词袋模型。词袋不再将一句话看做是单个词汇构成,而是当作一个 1 imes N1×N 的向量。举个例子,我们现在有两句话需要处理,分别是:
我爱你,我非常爱你。 我喜欢你,我非常喜欢你。
我们针对这两句话进行分词之后,去重处理为一个词袋:
[‘我‘, ‘爱‘, ‘喜欢‘, ‘你‘, ‘非常‘]
然后,根据词袋,我们对原句子进行向量转换。其中,向量的长度 N 为词袋的长度,而向量中每一个数值依次为词袋中的词出现在该句子中的次数。
我爱你,我非常爱你。 → [2, 2, 0, 2, 1]
我喜欢你,我非常喜欢你。 → [2, 0, 2, 2, 1]
有了词袋,有了已经人工标注好的句子,就组成了我们的训练数据。再根据机器学习方法来构建分类预测模型。从而判断新输入句子的情绪。
你会发现,词袋模型和我们之前提到的独热编码非常相似。其实这里就是将之前独热编码里的词变成了句子而已。
词袋模型固然比简单的词典对比方法更好,但独热编码无法度量上下文之间的距离,也就无法结合上下文进行情绪判断。下面,我们介绍一种词向量的 Word2Vec 处理方法,就会很好地克服这个缺点。
Word2Vec
Word2Vec,故名思意就是将句子转换为向量,也就是词向量。Word2Vec 最早由 Google 在 2013 年开源,它是由浅层神经网络组成的词向量转换模型。
Word2Vec 的输入一般为规模庞大的语料库,输出为向量空间。Word2Vec 的特点在于,语料库中的每个词都对应了向量空间中的一个向量,拥有上下文关系的词,映射到向量空间中的距离会更加接近。
Word2Vec 的主要结构是 CBOW(Continuous Bag-of-Words Model)模型和 Skip-gram(Continuous Skip-gram)模型结合在一起。简单来讲,二者都是想通过上下文得到一个词出现的概率。
CBOW 模型通过一个词的上下文(各 N 个词)预测当前词。而 Skip-gram 则恰好相反,他是用一个词预测其上下文,得到了当前词上下文的很多样本,因此可用于更大的数据集。
CBOW(N=2)和 Skip-gram 的结构如下图所示:
图中 w(t)w(t) 表示当前的词汇,而 w(t?n)w(t?n),w(t+n)w(t+n) 等则用来表示上下文词汇。
用户评论情绪分析
为了保证良好的准确度,本次我们选用了 Word2Vec 结合决策树的文本情绪分析方法。首先,我们需要使用 Word2Vec 来建立向量空间,之后再使用决策树训练文本情绪分类模型。
由于我们未人工针对评论进行语料库标注,所以这里需要选择其他的已标注语料库进行模型训练。这里,我们选用了网友苏剑林提供的语料库。该语料库整合了书籍、计算机等 7 个领域的评论数据。
你可以通过下面网盘链接下载本次所需要的数据集:
链接:https://pan.baidu.com/s/1qpy23EDHG2rea9SzxphIsQ 提取码:g837
三个数据文件的预览如下。
其中,消极情绪文本 neg.xls
共有 10428 行。
import pandas as pd
pd.read_excel("data_09/data/neg.xls", header=None).head()
积极情绪文本 pos.xls
共有 10679 行。
pd.read_excel("data_09/data/pos.xls", header=None).head()
用户评论文本 comments.csv
共有 12377 行。
pd.read_csv("data_09/comments.csv").head()
语料库分词处理
在使用 Word2Vec 之前,我们需要先对训练语料库进行分词处理。这里依旧使用 jieba 分词。
import jieba
import numpy as np
# 加载语料库文件,并导入数据
neg = pd.read_excel('data_09/data/neg.xls', header=None, index=None)
pos = pd.read_excel('data_09/data/pos.xls', header=None, index=None)
# jieba 分词
def word_cut(x): return jieba.lcut(x)
pos['words'] = pos[0].apply(word_cut)
neg['words'] = neg[0].apply(word_cut)
# 使用 1 表示积极情绪,0 表示消极情绪,并完成数组拼接
x = np.concatenate((pos['words'], neg['words']))
y = np.concatenate((np.ones(len(pos)), np.zeros(len(neg))))
# 将 Ndarray 保存为二进制文件备用
np.save('X_train.npy', x)
np.save('y_train.npy', y)
print('done.')
你可以预览一下数组的形状,以 x 为例:
np.load('X_train.npy', allow_pickle=True)
Word2Vec 处理
有了分词之后的数组,我们就可以开始 Word2Vec 处理,将其转换为词向量了。目前,很多开源工具都提供了 Word2Vec 方法,比如 Gensim,TensorFlow,PaddlePaddle 等。这里我们使用 Gensim。
from gensim.models.word2vec import Word2Vec
import warnings
warnings.filterwarnings('ignore') # 忽略警告
# 导入上面保存的分词数组
X_train = np.load('X_train.npy', allow_pickle=True)
# 训练 Word2Vec 浅层神经网络模型
w2v = Word2Vec(size=300, min_count=10)
w2v.build_vocab(X_train)
w2v.train(X_train, total_examples=w2v.corpus_count, epochs=w2v.epochs)
def sum_vec(text):
# 对每个句子的词向量进行求和计算
vec = np.zeros(300).reshape((1, 300))
for word in text:
try:
vec += w2v[word].reshape((1, 300))
except KeyError:
continue
return vec
# 将词向量保存为 Ndarray
train_vec = np.concatenate([sum_vec(z) for z in X_train])
# 保存 Word2Vec 模型及词向量
w2v.save('w2v_model.pkl')
np.save('X_train_vec.npy', train_vec)
print('done.')
Word2Vec 过程可能需要几分钟。
训练情绪分类模型
有了词向量,我们就有了机器学习模型的输入,那么就可以训练情绪分类模型。这一块内容你应该很熟悉,选择速度较快的决策树方法,并使用 scikit-learn 完成。
from sklearn.externals import joblib
from sklearn.tree import DecisionTreeClassifier
# 导入词向量为训练特征
X = np.load('X_train_vec.npy')
# 导入情绪分类作为目标特征
y = np.load('y_train.npy')
# 构建支持向量机分类模型
model = DecisionTreeClassifier()
# 训练模型
model.fit(X, y)
# 保存模型为二进制文件
joblib.dump(model, 'dt_model.pkl')
执行决策树分类,该过程持续时间较长。
对评判进行情绪判断
有了 Word2Vec 模型以及支持向量机情绪分类模型。接下来,我们就可以对的用户评论进行情绪预测了。
# 读取 Word2Vec 并对新输入进行词向量计算
def sum_vec(words):
# 读取 Word2Vec 模型
w2v = Word2Vec.load('w2v_model.pkl')
vec = np.zeros(300).reshape((1, 300))
for word in words:
try:
vec += w2v[word].reshape((1, 300))
except KeyError:
continue
return vec
对评论进行情绪判断:
# 读取评论
df = pd.read_csv("data_09/comments.csv", header=0)
comment_sentiment = []
for string in df['评论内容']:
# 对评论分词
words = jieba.lcut(str(string))
words_vec = sum_vec(words)
# 读取支持向量机模型
model = joblib.load('dt_model.pkl')
result = model.predict(words_vec)
comment_sentiment.append(result[0])
# 实时返回积极或消极结果
if int(result[0]) == 1:
print(string, '[积极]')
else:
print(string, '[消极]')
# 将情绪结果合并到原数据文件中
merged = pd.concat([df, pd.Series(comment_sentiment, name='用户情绪')], axis=1)
pd.DataFrame.to_csv(merged, 'comment_sentiment.csv') # 储存文件以备后用
最后,我们可以通过饼状图看一下用户的情绪分布。总体看来,73% 都为积极评论,正能量满满。
总结
本章节,我们使用机器学习方法对用户真实评论进行了情绪分析。内容涉及比较多,尤其是 Word2Vec 处理。鉴于本课程的目的,我们并没有针对 Word2Vec 进行太详细的介绍。如果你对自然语言处理感兴趣,Word2Vec 一定是需要理解透彻的方法。除了使用机器学习方法,在文本情绪分析时。我们往往会用到 LSTM(Long Short Term Memory networks)长短期记忆递归神经网络训练分类模型,在大规模语料数据中,应用效果可能会更优于支持向量机等方法。学有余力时,也可以自行了解学习。
除此之外,由于本次所用语料库来源于第三方购物网站的评论。所以,其训练的模型在预测用户情绪方面,可能并没有太好的泛化能力。如果能针对现有数据进行人工标注,对于预测以后的数据,结果应该会更好。
以上是关于手机评论文本挖掘与数据分析(Python)的主要内容,如果未能解决你的问题,请参考以下文章