文章目录
传送门:
- 数据挖掘实战—财政收入影响因素分析及预测
- 数据挖掘实战—航空公司客户价值分析
- 数据挖掘实战—商品零售购物篮分析
- 数据挖掘实战—基于水色图像的水质评价
- 数据挖掘实战—家用热水器用户行为分析与事件识别
- 数据挖掘实战—电商产品评论数据情感分析
引言
本文主要针对用户在电商平台上留下的评论数据,对其进行分词、词性标注和去除停用词等文本预处理。基于预处理后的数据进行情感分析,并使用LDA主题模型提取评论关键信息,以了解用户的需求、意见、购买原因及产品的优缺点等,最终提出改善产品的建议。
定义如下挖掘目标:
- 对京东商城中美的电热水器的评论进行情感分析
- 从评论文本中挖掘用户的需求、意见、购买原因及产品的优缺点
- 根据模型结果给出改善产品的建议
定义如下挖掘步骤:
- 利用Python对京东商城中美的电热水器的评论进行爬取。
- 利用Python爬取的京东商城中美的电热水器的评论数据,对评论文本数据进行数据清洗、分词、停用词过滤等操作。
- 对预处理后的数据进行情感分析,将评论文本数据按照情感倾向分为正面评论数据(好评)和负面评论数据(差评)。
- 分别对正、负面评论数据进行LDA 主题分析,从对应的结果分析文本评论数据中有价值的内容。
一、评论预处理
1.评论去重
由语言的特点可知,在大多数情况下,不同购买者之间的有价值的评论是不会出现完全重复的,如果不同购物者的评论完全重复,那么这些评论一般都是毫无意义的。显然这种评论中只有最早的评论才有意义(即只有第一条有作用)。有的部分评论相似程度极高,可是在某些词语的运用上存在差异。此类评论即可归为重复评论,若是删除文字相近评论,则会出现误删的情况。由于相近的评论也存在不少有用的信息,去除这类评论显然不合适。因此,为了存留更多的有用语料,本节针对完全重复的语料下手,仅删除完全重复部分,以确保保留有用的文本评论信息。
%matplotlib inline
import pandas as pd
import numpy as np
import re
import jieba.posseg as psg
# 加载评论数据
reviews = pd.read_csv('data/reviews.csv')
# 统计重复数据
reviews[['content', 'content_type']].duplicated().sum()
# 评论去重
reviews = reviews[['content', 'content_type']].drop_duplicates()
# 重置索引
reviews.reset_index(drop=True,inplace=True)
2.数据清洗
通过人工观察数据发现,评论中夹杂着许多数字与字母,对于本案例的挖掘目标而言,这类数据本身并没有实质性帮助。另外,由于该评论文本数据主要是围绕京东商城中美的电热水器进行评价的,其中“京东”“京东商城”“美的”“热水器”“电热水器"等词出现的频数很大,但是对分析目标并没有什么作用,因此可以在分词之前将这些词去除,对数据进行清洗
# 去掉评论中的数字、字母,以及“京东”“京东商城”“美的”“热水器”“电热水器"
content = reviews['content']
# 编译匹配模式
pattern = re.compile('[a-zA-Z0-9]|京东|美的|电热水器|热水器|京东商城')
# re.sub用于替换字符串中的匹配项
content = content.apply(lambda x : pattern.sub('',x))
二、评论分词
1.分词、词性标注、去除停用词
jieba的几个分词接口:cut、lcut、posseg.cut、posseg.lcut
# 自定义简单的分词函数
worker = lambda s : [[x.word,x.flag] for x in psg.cut(s)] # 单词与词性
seg_word = content.apply(worker)
# 将词语转化为数据框形式,一列是词,一列是词语所在的句子id,最后一列是词语在该句子中的位置
# 每一评论中词的个数
n_word = seg_word.apply(lambda x: len(x))
# 构造词语所在的句子id
n_content = [[x+1]*y for x,y in zip(list(seg_word.index), list(n_word))]
# 将嵌套的列表展开,作为词所在评论的id
index_content = sum(n_content, [])
seg_word = sum(seg_word,[])
# 词
word = [x[0] for x in seg_word]
# 词性
nature = [x[1] for x in seg_word]
# content_type评论类型
content_type = [[x]*y for x,y in zip(list(reviews['content_type']),list(n_word))]
content_type = sum(content_type,[])
# 构造数据框
result = pd.DataFrame({
'index_content': index_content,
'word' : word,
'nature': nature,
'content_type' : content_type})
观察nature列得,x表示标点符号
删除标点符号
# 删除标点符号
result = result[result['nature'] != 'x']
删除停用词
# 删除停用词
# 加载停用词
stop_path = open('data/stoplist.txt','r',encoding='utf-8')
stop = [x.replace('\n','') for x in stop_path.readlines()]
# 得到非停用词序列
word = list(set(word) - set(stop))
# 判断表格中的单词列是否在非停用词列中
result = result[result['word'].isin(word)]
# 构造各词在评论中的位置列
n_word = list(result.groupby(by=['index_content'])['index_content'].count())
index_word = [list(np.arange(0,x)) for x