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

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

reviews_long

值得注意的是,content_type为neg的词语的个数只有18070个,而词语一共有144117个,也就是说content_type为pos的词语有126047个,为什么同样1000条好评与1000条差评,正向情感的词汇数量会远远多于负向情感呢,其实看一下评论就知道了,大多数的好评字数都很多,动辄几百字,而差评基本都是几十个字,也可能是消费者没有耐心多写字去打差评,往往几句话抱怨一下,而好评则是精心编写,难道是写好评会有奖励?:

len(reviews_long[reviews_long['content_type'] == 'neg'])

情感标签为neg的词语的个数

好评基本上几百字,这是要写作文吗...

差评基本上都是几十个字

接下来进一步对reviews_long进行数据清洗,包括去除标点符号,去除停用词(比如“了”,“啊”,“吧”这种对于文本分析无用的词语),最终得到更干净的reviews_long_clean:

# 去除标点符号reviews_long_clean = reviews_long[reviews_long['nature']!='x']# 导入停用词 stop_path = open('stoplist.txt','r',encoding='utf-8')stop_words = stop_path.readlines()stop_words[0:5]# 停用词,预处理,去掉stop_words = [word.strip('') for word in stop_words]stop_words[0:5]# 得到不含停用词的分词表word_long_clean = list(set(word_long)-set(stop_words))reviews_long_clean = reviews_long_clean[reviews_long_clean['word'].isin(word_long_clean)]

最后reviews_long_clean只剩下49388个词汇:

在reviews_long_clean中,再增加一列,表示该分词在本条评论的位置:

# 再次统计每条评论的分词数量n_word = reviews_long_clean.groupby('index_content').count()['word']index_word = [list(np.arange(1,x+1)) for x in list(n_word)]index_word_long = sum(index_word,[])len(index_word_long)reviews_long_clean['index_word'] = index_word_long

将reviews_long_clean保存成csv文件:

reviews_long_clean.to_csv('1_review_long_clean.csv')

经历了繁琐的数据处理过程,终于可以进入正题了,可想而知数据预处理在数据分析中是多么重要!

先来个开胃小菜,提取形容词,做一个词云图:

'''提取形容词'''a_reviews_long_clean = reviews_long_clean[['a' in nat for nat in reviews_long_clean.nature]]a_reviews_long_clean.nature.value_counts()a_reviews_long_clean.to_csv('1_a_reviews_long_clean.csv')'''词云图'''font = '微软雅黑 Light.ttc'background_image = plt.imread('pl.jpg')wordcloud = WordCloud(font_path=font,max_words=100,background_color='white',mask=background_image,colormap='Reds')wordcloud.generate_from_frequencies(Counter(a_reviews_long_clean.word.values))wordcloud.to_file('1_形容词_分词后的词云图.png')

可以看出,迪奥的口红评论中,“持久”出现的频率比较高,这说明不容易掉色(作为直男可不可以这么理解...),其次就是“漂亮”、“精致”、“细腻”这些评价,感觉还是不错的。当然也有一些负面词汇,比如“假”、“真伪”,难道是质疑在京东上买到假货?接下来还需要进一步分析。

京东口红评论词云图_形容词


接下来通过机器学习构建一个决策树模型,通过有监督学习,来进行情感分类,预测某条评论属于好评(pos)还是差评(neg)。

'''决策树'''# 第一步:构造特征工程和标签Y = []for ind in reviews_long_clean.index_content.unique():    y = [word for word in reviews_long_clean.content_type[reviews_long_clean.index_content==ind].unique()]    Y.append(y)len(Y)X = []for ind in reviews_long_clean.index_content.unique():    term = [word for word in reviews_long_clean.word[reviews_long_clean.index_content==ind].values]    X.append(' '.join(term))len(X)XY    #第二步:训练集、测试集划分x_train,x_test,y_train,y_test = train_test_split(X,Y,test_size=0.2,random_state=7)#第三步:词转向量,01矩阵count_vec = CountVectorizer(binary=True)x_train = count_vec.fit_transform(x_train)x_test = count_vec.transform(x_test)#第四步:构建决策树dtc = tree.DecisionTreeClassifier(max_depth=5)dtc.fit(x_train,y_train)print('在训练集上的准确率:%.2f'%accuracy_score(y_train,dtc.predict(x_train)))y_true = y_testy_pred = dtc.predict(x_test)print(classification_report(y_true,y_pred))print('在测试集上的准确率:%.2f'%accuracy_score(y_true,y_pred))

在训练集上的准确率为0.96,在测试集上的准确率为0.95,感觉还是可以的。

画决策树:

# 第五步:画决策树cwd = os.getcwd()dot_data = tree.export_graphviz(dtc,                                out_file=None,                                feature_names = count_vec.get_feature_names())graph = graphviz.Source(dot_data)graph.format='svg'graph.render(cwd+'/tree',view=True)graph

可以看到“颜色”、“喜欢”、“滋润”、“七夕”、“不错”都是比较重要的词:


接下来进行情感分析,刚才的决策树是有监督的机器学习,我用的人工打的标签;而情感分析则是没有人工打的标签,属于无监督学习。那么如何通过无监督的手段得到情感标签呢?

首先导入评价情感词,它是知网发布的情感分析用词语集:

# 导入评价情感词# 读入正面、负面情感评价词pos_comment = pd.read_csv("正面评价词语(中文).txt", header=None,sep="", encoding = 'utf-8')neg_comment = pd.read_csv("负面评价词语(中文).txt", header=None,sep="", encoding = 'utf-8')pos_emotion = pd.read_csv("正面情感词语(中文).txt", header=None,sep="", encoding = 'utf-8')neg_emotion = pd.read_csv("负面情感词语(中文).txt", header=None,sep="", encoding = 'utf-8') # 合并情感词与评价词positive = pd.concat([pos_comment,pos_emotion],axis=0)negative = pd.concat([neg_comment,neg_emotion],axis=0)