《Python数据分析与挖掘实战》第15章——文本挖掘

本文是基于《Python数据分析与挖掘实战》的实战部分的第15章的数据——《电商产品评论数据情感分析》做的分析。

旨在回顾对评论文本数据的处理和建模方法。

1 挖掘背景与目标

    对京东平台上的热水器评论进行文本挖掘分析,挖掘建模如下:

1)分析某一个品牌热水器的用户情感倾向

2)从评论文本中挖掘出该品牌热水器的优点和不足

3)提炼不同品牌热水器的卖点

2 数据探索与预处理

2.1 数据筛选

# -*- coding:utf-8 -*-
import pandas as pd
inputfile = 'huizong.csv' # 评论汇总文件
data = pd.read_csv(inputfile, encoding = 'utf-8')
result = data[[u'评论']][data[u'品牌'] == u'美的']
result.info()

输出结果

2.2 to_txt

# 必须导入下面这个包,要不然会报错'ascii' codec can't encode characters in position
# Python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
result.to_csv('1_1my_meidi_jd.txt', index = False, header = False) # 将评论提取后保存到txt中,不要索引,不要列名(***)

2.3 原始数据去重

import pandas as pd
inputfile = '1_1my_meidi_jd.txt' # 评论汇总文件
data = pd.read_csv(inputfile, encoding = 'utf-8', header = None) #(***)
l1 = len(data) 
print u'原始数据有%d条' % l1  # 原始数据有55774条 
data = pd.DataFrame(data[0].unique())# (*****)
l2 = len(data)
print u'去重后数据有%d条' % l2 # 去重后数据有53049条
data.to_csv('2_1my_meidi_jd_delduplis.txt', header = False, index = False, encoding='utf-8') # (***)

2.4 删除前缀

inputfile1 = u'meidi_jd_process_end_负面情感结果.txt' # 评论汇总文件
inputfile2 = u'meidi_jd_process_end_正面情感结果.txt' # 评论汇总文件

data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #(***)
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None) #(***)

data1 = pd.DataFrame(data1[0].str.replace('.*?\d+?\\t', '')) # 使用正则表达式替换掉前缀
data2 = pd.DataFrame(data2[0].str.replace('.*?\d+?\\t', '')) # 使用正则表达式替换掉前缀

data1.to_csv(u'3_1my_meidi_jd_process_end_负面情感结果.txt', header = False, index = False, encoding='utf-8') # (***)
data2.to_csv(u'3_2my_meidi_jd_process_end_正面情感结果.txt', header = False, index = False, encoding='utf-8') # (***)

2.5 分词

import pandas as pd
import jieba # 导入结巴分词包

inputfile1 = u'3_1my_meidi_jd_process_end_负面情感结果.txt' 
inputfile2 = u'3_2my_meidi_jd_process_end_正面情感结果.txt'
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #(***)
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None) #(***)

mycut = lambda s: " ".join(jieba.cut(s)) # 自定义简单分词函数
data1 = data1[0].apply(mycut) # 通过广播形式分词,加快速度
data2 = data2[0].apply(mycut) # 通过广播形式分词,加快速度

data1.to_csv(u'4_1my_meidi_jd_process_end_负面情感结果_cut.txt', header = False, index = False, encoding='utf-8') # (***)
data2.to_csv(u'4_2my_meidi_jd_process_end_正面情感结果_cut.txt', header = False, index = False, encoding='utf-8') # (***)

3 基于LED 模型的主题分析

# 方法:在分好词的正面评价、负面评价以及过滤用的停用词表上进行,使用Gensim库完成LDA分析代码
import pandas as pd

# 参数初始化
inputfile1 = u'4_1my_meidi_jd_process_end_负面情感结果_cut.txt' 
inputfile2 = u'4_2my_meidi_jd_process_end_正面情感结果_cut.txt'
inputfile3 = 'stoplist.txt' # 停用词表

data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #(***)
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None) #(***)
stop = pd.read_csv(inputfile3, encoding = 'utf-8', sep = 'tipdm', header = None) #(***)
# sep 设置分割词, 由于csv默认以半角逗号为分割词,而该词恰好在停用词表中,因此会导致读取出错
# 所以,解决方法是手动设置一个不存在的分割词,如tipdm
stop = [' ', ''] +list(stop[0]) # pandas自动过滤了空格符,所以手动将其加入

data1 [1] = data1[0].apply(lambda s: s.split(' ')) # 定义一个分隔函数,用apply广播
data1 [2] = data1[1].apply(lambda x: [i for i in x if i not in stop]) # 逐词判断是否是停用词

data2 [1] = data2[0].apply(lambda s: s.split(' ')) # 定义一个分隔函数,用apply广播
data2 [2] = data2[1].apply(lambda x: [i for i in x if i not in stop]) # 逐词判断是否是停用词
from gensim import corpora, models
# 负面主题分析
data1_dict = corpora.Dictionary(data1[2]) # 建立词典
data1_corpus = [data1_dict.doc2bow(i) for i in data1[2]] # 建立语料库

data1_LDA = models.LdaModel(data1_corpus, num_topics =3, id2word = data1_dict) # LDA训练模型
for i in range(3):
    data1_LDA.print_topic(i)# 输出每个主题
# 正面主题分析
data2_dict = corpora.Dictionary(data2[2]) # 建立词典
data2_corpus = [data2_dict.doc2bow(i) for i in data2[2]] # 建立语料库

data2_LDA = models.LdaModel(data2_corpus, num_topics =3, id2word = data2_dict) # LDA训练模型
for i in range(3):
    data2_LDA.print_topic(i)# 输出每个主题
PS:不知道为什么输出时有编码问题

data1_LDA.print_topic(0)

输出:

u'0.044*"\u7684" + 0.036*"\u8fd8" + 0.027*"\u5b89\u88c5" + 0.024*"\u4e86" + 0.021*"\u5f88" + 0.019*"\u4e0d\u9519" + 0.015*"\u4e0d" + 0.013*"\u7528" + 0.011*"\u597d" + 0.011*"\u5c31\u662f"'


备注:本章完整代码请见:点击打开链接


猜你喜欢

转载自blog.csdn.net/u012063773/article/details/79324528