深度|为了七夕节送女朋友一支口红,我爬取了京东并进行数据分析

2020-08-26 22:21:33 作者: 深度|为了七

京东口红商品名称词云图


京东迪奥口红商品评论:文本分析、情感分析、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})