京东口红商品名称词云图
京东迪奥口红商品评论:文本分析、情感分析、LDA主题分析
思来想去,我比较钟意迪奥的某款口红,因为迪奥是评价人数最多的店铺,同时也是国际知名品牌,再加上七夕节打折力度非常大,所以我把它列为首选。但是为了更好的了解它的质量怎么样,我决定对迪奥口红的商品评论进行文本分析,情感分析,并使用LDA主题模型进行主题分析。
首先需要爬取数据,限于篇幅,爬虫代码只给出主要部分,感兴趣的朋友可以私信我领取。
# 通过for循环获取更多页的评论texts=[]for n in range(0,100): url = 'https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=100006262957&score=1&sortType=5&page='+str(n)+'&pageSize=10&isShadowSku=0&fold=1' time.sleep(5) try: data = requests.get(url, headers=headers).text # 正则表达式解析内容 pat = re.compile('"content":"(.*?)","creationTime"') texts.extend(pat.findall(data)) print('已爬取第'+str(n+1)+'页') except: continue
也可以参考我之前写的文章,原理是一样的:用Python爬取淘宝商品评论,看看辣条到底有多好吃
正在爬取中...
因为要进行情感分析和主题分析,所以评论最好是兼顾好评与差评,所以我爬取了100页好评与100页差评的数据,如图所示:
京东口红好评评论,共1000条
值得注意的是,对于差评,商家会在顾客评论下边回复,所以同样是一个页面,好评会有10个文本信息,但是差评会有20个文本信息(差评+商家回复),所以我爬了100页,差评却有接近2000条文本,所以需要把商家的回复清洗掉,通过观察可以发现,商家的回复基本上均包含“您好”、“亲爱的”、“您”这种表示尊敬的词语(而顾客的差评里基本没有这个词,毕竟打差评了心情肯定不会好),所以通过Excel的Ctrl+Shift+L可以将商家的回复筛选出来,删除即可。
京东口红差评评论,共1960条
将商家的回复删除后,正好剩下了1000条评论,说明基本清洗完毕。
之后人工打上情感标签,新建一列,命名为content_type,对于好评评论,标记为pos;对于差评评论,标记为neg(忽略实际给好评,但是评论是负向情感;忽略实际给差评,但是评论是正向情感的情况。因为很少见。)
将差评评论数据与好评评论数据合并在一起,形成最终的数据集,命名为“京东口红评论数据.xlsx”
接下来进行文本分析,首先导入各种第三方库:
import osimport pandas as pdimport reimport jieba.posseg as psgimport numpy as npimport matplotlib.pyplot as pltfrom wordcloud import WordCloudfrom collections import Counterfrom gensim import corpora,modelsimport itertoolsfrom sklearn.metrics import accuracy_scorefrom sklearn.model_selection import train_test_splitfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn import treefrom sklearn.metrics import classification_reportimport graphvizfrom sklearn.metrics import confusion_matrix
读取文件:
raw_data = pd.read_excel('京东口红评论数据.xlsx')
对评论进行去重:
reviews = raw_data.copy()print('去重之前:',reviews.shape[0])reviews = reviews.drop_duplicates()print('去重之后:',reviews.shape[0])
去重前与去重后的对比
进行数据清洗,通过正则表达式去除评论里的字母、数字、表情以及对文本分析无用的词汇:
# 清洗之前content = reviews['content']# 数据清洗info = re.compile('[^\u0000-?]|[0-9a-zA-Z]|口红|京东|迪奥')content = content.apply(lambda x:info.sub('',x))
清洗后的评论
之后对评论进行分词,并通过jieba里的posseg模块标注词性:
# 分词并标注词性worker = lambda s: [(x.word, x.flag) for x in psg.cut(s)] # 自定义简单分词函数seg_content = content.apply(worker)
分词后的评论seg_content
统计一下评论词的个数:
# 统计评论词数n_word = seg_content.apply(lambda s:len(s))
前六个句子的评论词数量
得到各分词在第几条评论:
# 得到各分词在第几条评论n_content = [ [x+1]*y for x,y in zip(list(seg_content.index),list(n_word))]index_content_long = sum(n_content,[])
n_content是一个列表,里面是1994个小列表
index_content_long是一个列表,包含144117条元素
index_content_long内部结构
对之前的seg_content去掉[],拉平:
# 分词及词性,去掉[],拉平seg_content_long = sum(seg_content,[])
将seg_content拉平后
# 得到加长版的分词,词性word_long = [x[0] for x in seg_content_long]nature_long = [x[1] for x in seg_content_long]
将content_type拉长:
# content_type拉长n_content_type = [[x]*y for x,y in zip(list(reviews['content_type']),list(n_word))]content_type_long = sum(n_content_type,[])
n_content_type
content_type_long
新建一个dataframe,将"index_content","word","nature","content_type"作为列索引:
reviews_long = pd.DataFrame({'index_content':index_content_long, 'word':word_long, 'nature':nature_long, 'content_type':content_type_long})