站点图标 AI技术聚合

Python大数据-电商产品评论情感数据分析

Python大数据-电商产品评论情感数据分析

Python大数据-电商产品评论情感数据分析 

目录

一、项目背景

 二、项目目标

三、分析方法与分析过程

四、数据清洗

 数据抓取 

评论去重

分词

停用词

词云图绘制

五、 数据分析

评论数据情感倾向分析

匹配情感词

修正情感倾向

LDA模型进行主题分析

寻找最优主题数 

 评价主题分析结果

六、 结论分析

一、项目背景

 二、项目目标

三、分析方法与分析过程

四、数据清洗

 数据抓取 

本文主要目标是对数据进行分析,数据抓取具有时效性,在这里对抓取的方法不进行赘述,有不懂的可以看Python爬虫-抓取数据到可视化全流程的实现

评论去重

从数据库中取出数据,可以看到共有1260条评论数据,分为8列

#导包
import pandas as pd 
import numpy as np
import pymysql
import matplotlib.pyplot as plt
import re
import jieba.posseg as psg
db_info={
    'host':"***",
    'user':"***",
    'passwd':'***',
    'database':'cx',# 这里说明我要连接哪个库
    'charset':'utf8'
}
conn = pymysql.connect(**db_info)
cursor = conn.cursor()
sql = 'select * from jdsppl'
result = pd.read_sql(sql,conn)
result
result.shape

部分电商平台对长时间未完成订单评价的客户会进行默认评价,此类数据没有分析价值,但是本次爬取的数据来自于京东,京东默认只保留前100页的评论数据,其他数据归为帮助不大的数据,因此在此次爬取的数据中,不存在这样的情况,同时如果在某个商品的评论中出现了完全相同的评论,一次两次或者多次,那么这种情况下的数据肯定是毫无意义的问题数据,这种评论数据只认为其第一条即首次出现时认为其存在一定价值。在评论中会出现一部分评论相似程度很高,但并不完全相同,个别词语还存在明显差异,对于这种情况,全部删除是不正确和不合适的,可以只删除重复的部分,保留有用的文本评论信息,留下更多有用的语料。

reviews = reviews[['content', 'content_type']].drop_duplicates()
content = reviews['content']
reviews

 可以看到有17条重复数据已经被删除

通过人工观察数据发现,评论中夹杂着许多数字与字母,对于本案例的挖掘目标而言,这类数据本身并没有实质性帮助。另外,由于该评论文本数据主要是围绕京东商城中韶音 AfterShokz Aeropex AS800骨传导蓝牙耳机进行评价的,其中“京东”“京东商城”“韶音”“耳机”“蓝牙耳机”等词出现的频数很大,但是对分析目标并没有什么作用,因此可以在分词之前将这些词去除,对数据进行清洗

# 去除去除英文、数字等
# 由于评论中不重要词语
strinfo = re.compile('[0-9a-zA-Z]|京东|京东商城|韶音|耳机|蓝牙耳机|')
content=result['评价内容']
content = content.apply(lambda x: strinfo.sub('', x))
content

 字段已经去除

分词

停用词

提取含有名词的评论

 提取评论中词性含有“n”(名词)的评论,

# 提取含有名词类的评论
ind = result[['n' in x for x in result['nature']]]['index_content'].unique()
result = result[[x in ind for x in result['index_content']]]

 

 

词云图绘制

进行数据预处理后,可绘制词云查看分词效果,词云会将文本中出现频率较高的“关键词”予以视觉上的突出。首先需要对词语进行词频统计,将词频按照降序排序,选择前100个词,使用wordcloud模块中的WordCloud绘制词云,查看分词效果(常用字体代码

import matplotlib.pyplot as plt
from wordcloud import WordCloud

frequencies = result.groupby(by = ['word'])['word'].count()
frequencies = frequencies.sort_values(ascending = False)
backgroud_Image=plt.imread('../data/pl.jpg')
wordcloud = WordCloud(font_path="simkai.ttf",
                      max_words=100,
                      background_color='white',
                      mask=backgroud_Image)
my_wordcloud = wordcloud.fit_words(frequencies)
plt.imshow(my_wordcloud)
plt.axis('off') 
plt.show()

​从生成的词云图中可以初步判断用户比较在意的是音质、质感、续航、舒适度等关键词

五、 数据分析

评论数据情感倾向分析

匹配情感词

import pandas as pd
import numpy as np
word = pd.read_csv("../tmp/result.csv")

# 读入正面、负面情感评价词
pos_comment = pd.read_csv("../data/正面评价词语(中文).txt", header=None,sep="\n", 
                          encoding = 'utf-8', engine='python')
neg_comment = pd.read_csv("../data/负面评价词语(中文).txt", header=None,sep="\n", 
                          encoding = 'utf-8', engine='python')
pos_emotion = pd.read_csv("../data/正面情感词语(中文).txt", header=None,sep="\n", 
                          encoding = 'utf-8', engine='python')
neg_emotion = pd.read_csv("../data/负面情感词语(中文).txt", header=None,sep="\n", 
                          encoding = 'utf-8', engine='python') 

# 合并情感词与评价词
positive = set(pos_comment.iloc[:,0])|set(pos_emotion.iloc[:,0])
negative = set(neg_comment.iloc[:,0])|set(neg_emotion.iloc[:,0])
intersection = positive&negative  # 正负面情感词表中相同的词语
positive = list(positive - intersection)
negative = list(negative - intersection)
positive = pd.DataFrame({"word":positive,
                         "weight":[1]*len(positive)})
negative = pd.DataFrame({"word":negative,
                         "weight":[-1]*len(negative)}) 

posneg = positive.append(negative)

#  将分词结果与正负面情感词表合并,定位情感词
data_posneg = posneg.merge(word, left_on = 'word', right_on = 'word', 
                           how = 'right')
data_posneg = data_posneg.sort_values(by = ['index_content','index_word'])

修正情感倾向

# 根据情感词前时候有否定词或双层否定词对情感值进行修正
# 载入否定词表
notdict = pd.read_csv("../data/not.csv")

# 处理否定修饰词
data_posneg['amend_weight'] = data_posneg['weight']  # 构造新列,作为经过否定词修正后的情感值
data_posneg['id'] = np.arange(0, len(data_posneg))
only_inclination = data_posneg.dropna()  # 只保留有情感值的词语
only_inclination.index = np.arange(0, len(only_inclination))
index = only_inclination['id']

for i in np.arange(0, len(only_inclination)):
    review = data_posneg[data_posneg['index_content'] == 
                         only_inclination['index_content'][i]]  # 提取第i个情感词所在的评论
            
# 更新只保留情感值的数据
only_inclination = only_inclination.dropna()

# 计算每条评论的情感值
emotional_value = only_inclination.groupby(['index_content'],
                                           as_index=False)['amend_weight'].sum()

# 去除情感值为0的评论
emotional_value = emotional_value[emotional_value['amend_weight'] != 0]

使用wordcloud包下的 WordCloud 函数分别对正面评论和负面评论绘制词云,以查看情感分析效果。

# 给情感值大于0的赋予评论类型(content_type)为pos,小于0的为neg
emotional_value['a_type'] = ''
emotional_value['a_type'][emotional_value['amend_weight'] > 0] = 'pos'
emotional_value['a_type'][emotional_value['amend_weight'] < 0] = 'neg'

# 查看情感分析结果
result = emotional_value.merge(word, 
                               left_on = 'index_content', 
                               right_on = 'index_content',
                               how = 'left')

result = result[['index_content','content_type', 'a_type']].drop_duplicates() 
confusion_matrix = pd.crosstab(result['content_type'], result['a_type'], 
                               margins=True)  # 制作交叉表
(confusion_matrix.iat[0,0] + confusion_matrix.iat[1,1])/confusion_matrix.iat[2,2]

# 提取正负面评论信息
ind_pos = list(emotional_value[emotional_value['a_type'] == 'pos']['index_content'])
ind_neg = list(emotional_value[emotional_value['a_type'] == 'neg']['index_content'])
posdata = word[[i in ind_pos for i in word['index_content']]]
negdata = word[[i in ind_neg for i in word['index_content']]]

# 绘制词云
import matplotlib.pyplot as plt
from wordcloud import WordCloud
# 正面情感词词云
freq_pos = posdata.groupby(by = ['word'])['word'].count()
freq_pos = freq_pos.sort_values(ascending = False)
backgroud_Image=plt.imread('../data/pl.jpg')
wordcloud = WordCloud(font_path="simkai.ttf",
                      max_words=100,
                      background_color='white',
                      mask=backgroud_Image)
pos_wordcloud = wordcloud.fit_words(freq_pos)
plt.imshow(pos_wordcloud)
plt.axis('off') 
plt.show()
# 负面情感词词云
freq_neg = negdata.groupby(by = ['word'])['word'].count()
freq_neg = freq_neg.sort_values(ascending = False)
neg_wordcloud = wordcloud.fit_words(freq_neg)
plt.imshow(neg_wordcloud)
plt.axis('off') 
plt.show()

# 将结果写出,每条评论作为一行
posdata.to_csv("../tmp/posdata.csv", index = False, encoding = 'utf-8')
negdata.to_csv("../tmp/negdata.csv", index = False, encoding = 'utf-8')

 可以看到在正面情感评论词云图中可以发现:“不错”、“喜欢”、“满意”、“舒服”等词出现的词频较高,且没有出现负面情感的词语。从负面情感评论中可以发现:“做工”、“客服”、“差”等出现词频较高,没有发现掺杂正面情感的词语,由此可以正面通过词表来分析文本的情感程度是有效的。

LDA模型进行主题分析

import pandas as pd
import numpy as np
import re
import itertools
import matplotlib.pyplot as plt

# 载入情感分析后的数据
posdata = pd.read_csv("../data/posdata.csv", encoding = 'utf-8')
negdata = pd.read_csv("../data/negdata.csv", encoding = 'utf-8')
from gensim import corpora, models
# 建立词典
pos_dict = corpora.Dictionary([[i] for i in posdata['word']])  # 正面
neg_dict = corpora.Dictionary([[i] for i in negdata['word']])  # 负面

# 建立语料库
pos_corpus = [pos_dict.doc2bow(j) for j in [[i] for i in posdata['word']]]  # 正面
neg_corpus = [neg_dict.doc2bow(j) for j in [[i] for i in negdata['word']]]   # 负面

寻找最优主题数 

  • 基于相似度的自适应最优LDA模型选择方法,确定主题数并进行主题分析。实验证明该方法可以在不需要人工调试主题数目的情况下,用相对少的迭代找到最优的主题结构。具体步骤如下:
  • 1)取初始主题数k值,得到初始模型,计算各主题之间的相似度(平均余弦距离)。
  • 2)增加或减少k值,重新训练模型,再次计算各主题之间的相似度。
  • 3 )重复步骤2直到得到最优k值。
  • 利用各主题间的余弦相似度来度量主题间的相似程度。从词频入手,计算它们的相似度,用词越相似,则内容越相近。
  •  构造主题数寻优函数
    def cos(vector1, vector2):  # 余弦相似度函数
        dot_product = 0.0;  
        normA = 0.0;  
        normB = 0.0;  
        for a,b in zip(vector1, vector2): 
            dot_product += a*b  
            normA += a**2  
            normB += b**2  
        if normA == 0.0 or normB==0.0:  
            return(None)  
        else:  
            return(dot_product / ((normA*normB)**0.5))   
    
                
    # 计算主题平均余弦相似度
    pos_k = lda_k(pos_corpus, pos_dict)
    neg_k = lda_k(neg_corpus, neg_dict)        
    
    # 绘制主题平均余弦相似度图形
    from matplotlib.font_manager import FontProperties  
    font = FontProperties(size=14)
    #解决中文显示问题
    plt.rcParams['font.sans-serif']=['SimHei']
    plt.rcParams['axes.unicode_minus'] = False  
    fig = plt.figure(figsize=(10,8))
    ax1 = fig.add_subplot(211)
    ax1.plot(pos_k)
    ax1.set_xlabel('正面评论LDA主题数寻优', fontproperties=font)
    
    ax2 = fig.add_subplot(212)
    ax2.plot(neg_k)
    ax2.set_xlabel('负面评论LDA主题数寻优', fontproperties=font)<

    从图中可以发现,当主题数为2时,主题间的余弦相似度达到最低,因此选择主题数为2

 评价主题分析结果

根据主题数寻优结果,使用Python的Gensim模块对正面评论数据和负面评论数据分别构建LDA主题模型,选取主题数为2,经过LDA主题分析后,每个主题下生成10个最有可能出现的词语及相应的概率

# LDA主题分析
pos_lda = models.LdaModel(pos_corpus, num_topics = 2, id2word = pos_dict)  
neg_lda = models.LdaModel(neg_corpus, num_topics = 2, id2word = neg_dict)  
pos_lda.print_topics(num_words = 10)
neg_lda.print_topics(num_words = 10)

 整理:

正面评价潜在主题:

1 2 1 2
音质 耳朵 感觉 传到
喜欢 不错 运动
做工 质感 舒适度 音效
满意 舒服 续航
耳朵 跑步 很快 值得

 

负面评价潜在主题:

1 2 1 2
客服 耳朵 几天
传导 赠品
音质 快递 理解 做工
不好 产品
声音 回来

六、 结论分析

版权声明:本文为博主你隔壁的小王原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/weixin_43212535/article/details/122585397

退出移动版