NLP实战:用主题建模分析网购评论(附Python代码)

2018 年 10 月 17 日 论智
来源:Analytics Vidhya
编译:Bing

现在电商行业势头正好,对在线零售商来说,他们不受库存或空间的限制,而实体店则必须在有限的空间中存储产品。

但是,在线购物也有它的局限之处,最大的难题之一就是检验产品的真伪。它的质量是否如宣传所说的那么好?消费者留言的评价是真实的吗还是虚假宣传?这是消费者决定购买的重要因素。

所以,我们决定用NLP技术在这一主题中进行探索,本文将帮助你了解用主题建模分析在线产品评论的重要性。

有关主题建模,可以参考我们此前的文章:《用隐藏语义分析(LSA)进行主题建模(附Python代码)》

商品评论的重要性

前几天,我从某网站买了一部智能手机,价格符合我的预期,并且评分为4.5分(满分为5)。

但是,拿到手之后我才发现,电池续航远不及平均水平。在购买时我只看了评分,却没关注评论,所以我知道肯定不只我一个人不满意!

所以网购看评论应该是必不可少的参考,可以,如果评论有成百上千条,根本看不过来怎么办?这就需要用到自然语言处理技术了。

明确问题

我们应该如何用NLP分析大量商品评论呢?首先让我们明确这一问题。

从卖家角度,他们可以从评论中估计顾客对商品的反应。想从大量评论中找到关键信息,这样的智能系统需要做到两点:

  1. 能让顾客从中迅速提取出关键主题

  2. 卖家也能通过这些主题获得用户反馈

为了解决这一任务,我们将在亚马逊的汽车评论数据上使用主题建模(LDA),数据集可以在这个地址中下载:snap.stanford.edu/data/amazon/productGraph/categoryFiles/reviewsAutomotive5.json.gz。

为什么用主题建模

和这项技术的名称一样,主题建模是自动确定文本目标中主题的过程,同时从文本语料中展示隐藏语义。主题模型有多重用途,包括:

  • 文件聚合

  • 组织大型文本数据

  • 从未被组织的文本中进行信息检索

  • 特征选择

一个好的主题模型,如果在与股票市场相关的文本上训练时,应该会生成类似“出价”、“买卖”、“分红”、“交易”等主题。下图展示了一个典型的主题模型工作的流程:

在我们的案例中,文本数据来自“汽车”类目下的商品评论。这里,我们的目标是从评论中提取一些重要的有代表性的单词。这些关键词可以帮助我们了解某位顾客的态度。

Python实现

在这一部分,我们会用到Jupyter Notebook(或你在Python下使用的任意IDE)。这里我们会用到“隐含狄利克雷分布(LDA)”的概念,如果对这一概念不了解的读者,可以参考这一博文:www.cnblogs.com/huangshiyu13/p/6148217.html

首先我们要下载所需的库:

  
  
    
  1. import nltk

  2. from nltk import FreqDist

  3. nltk.download('stopwords') # run this one time

  
  
    
  1. import pandas as pd

  2. pd.set_option("display.max_colwidth", 200)

  3. import numpy as np

  4. import re

  5. import spacy

  6. import gensim

  7. from gensim import corpora

  8. # libraries for visualization

  9. import pyLDAvis

  10. import pyLDAvis.gensim

  11. import matplotlib.pyplot as plt

  12. import seaborn as sns

  13. %matplotlib inline

要导入数据,首先要将数据提取到你的工作类别中,然后使用pandas中的read_json( )函数在pandas的数据框架中读取。

  
  
    
  1. df = pd.read_json('Automotive_5.json', lines=True)

  2. df.head()

如你所见,数据包含以下类目:

  • 评论者的ID

  • 产品ID

  • 评论者的用户名

  • 该评论的有用性

  • 评论文本

  • 产品评分

  • 评论总结

  • 评论执行时间

  • 评论原始时间(raw)

在这篇文章中,我们只使用“评论文本”这一类。

数据处理

在开始文本挖掘前,数据处理和清洗是很重要的一步。在这一步中,我们会删除标点、停止词等,让评论的形式尽可能统一。处理好之后,就可以检查数据中最常出现的词语了。所以,让我们在这里定义一个函数,可以通过条形图展示数据中最常见的n个词语。

  
  
    
  1. # function to plot most frequent terms

  2. def freq_words(x, terms = 30):

  3.  all_words = ' '.join([text for text in x])

  4.  all_words = all_words.split()

  5.  fdist = FreqDist(all_words)

  6.  words_df = pd.DataFrame({'word':list(fdist.keys()), 'count':list(fdist.values())})

  7.  # selecting top 20 most frequent words

  8.  d = words_df.nlargest(columns="count", n = terms)

  9.  plt.figure(figsize=(20,5))

  10.  ax = sns.barplot(data=d, x= "word", y = "count")

  11.  ax.set(ylabel = 'Count')

  12.  plt.show()

函数定义如下。

  
  
    
  1. freq_words(df['reviewText'])

如图,最常见的词语是“the”、“and”、“to”等等,这些词对我们并没有什么帮助,所以也要删除这些词语。在这之前,让我们先删除标点和数字。

  
  
    
  1. # remove unwanted characters, numbers and symbols

  2. df['reviewText'] = df['reviewText'].str.replace("[^a-zA-Z#]", " ")

接着删除停止词和少于两个字母的单词:

  
  
    
  1. from nltk.corpus import stopwords

  2. stop_words = stopwords.words('english')

  
  
    
  1. # function to remove stopwords

  2. def remove_stopwords(rev):

  3.    rev_new = " ".join([i for i in rev if i not in stop_words])

  4.    return rev_new

  5. # remove short words (length < 3)

  6. df['reviewText'] = df['reviewText'].apply(lambda x: ' '.join([w for w in x.split() if len(w)>2]))

  7. # remove stopwords from the text

  8. reviews = [remove_stopwords(r.split()) for r in df['reviewText']]

  9. # make entire text lowercase

  10. reviews = [r.lower() for r in reviews]

再对常出现的词进行可视化:

  
  
    
  1. freq_words(reviews, 35)

我们可以看出有了变化,像“电池”、“价格”、“产品”、“汽油”等与汽车较相关的词语出现了。但是,仍然有一些中性词存在,例如“the”、“this”、“much”、“they”等等。

为了进一步去除文本中的噪音,我们可以用spaCy库中的词形还原处理。它可以将词语还原到原始形式,减少单词的重复。

  
  
    
  1. !python -m spacy download en # one time run

  
  
    
  1. nlp = spacy.load('en', disable=['parser', 'ner'])

  2. def lemmatization(texts, tags=['NOUN', 'ADJ']): # filter noun and adjective

  3.       output = []

  4.       for sent in texts:

  5.             doc = nlp(" ".join(sent))

  6.             output.append([token.lemma_ for token in doc if token.pos_ in tags])

  7.       return output

我们对评语进行符号化,然后对其进行词形还原。

  
  
    
  1. tokenized_reviews = pd.Series(reviews).apply(lambda x: x.split())

  2. print(tokenized_reviews[1])

  
  
    
  1. ['these', 'long', 'cables', 'work', 'fine', 'truck', 'quality', 'seems', 'little', 'shabby',

  2. 'side', 'for', 'money', 'expecting', 'dollar', 'snap', 'jumper', 'cables', 'seem', 'like',

  3. 'would', 'see', 'chinese', 'knock', 'shop', 'like', 'harbor', 'freight', 'bucks']

  
  
    
  1. reviews_2 = lemmatization(tokenized_reviews)

  2. print(reviews_2[1]) # print lemmatized review

  
  
    
  1. ['long', 'cable', 'fine', 'truck', 'quality', 'little', 'shabby', 'side', 'money', 'dollar',

  2. 'jumper', 'cable', 'chinese', 'shop', 'harbor', 'freight', 'buck']

可以看到,这一过程并不仅仅还原了词形,而且只留下了名词和形容词。之后,我们将这次词语在变换成正常形式。

  
  
    
  1. reviews_3 = []

  2. for i in range(len(reviews_2)):

  3. reviews_3.append(' '.join(reviews_2[i]))

  4. df['reviews'] = reviews_3

  5. freq_words(df['reviews'], 35)

这样可以看出常见词都是和汽车相关的,我们可以继续搭建主题模型了。

搭建一个LDA模型

首先,我们要对语料创建术语词典,其中每个唯一的词语都被看做一个index

  
  
    
  1. dictionary = corpora.Dictionary(reviews_2)

之后,我们要用创建好的词典将评论转化成文件术语矩阵。

  
  
    
  1. doc_term_matrix = [dictionary.doc2bow(rev) for rev in reviews_2]

  
  
    
  1. # Creating the object for LDA model using gensim library

  2. LDA = gensim.models.ldamodel.LdaModel

  3. # Build LDA model

  4. lda_model = LDA(corpus=doc_term_matrix,

  5.                                   id2word=dictionary,

  6.                                   num_topics=7,

  7.                                   random_state=100,

  8.                                   chunksize=1000,

  9.                                   passes=50)

上述代码的执行可能需要一段时间。注意,我在这一模型中,用num_topics参数将主题的数量定为7,你可以修改这一数字。

接着就可以生成LDA模型学习到的主题。

  
  
    
  1. lda_model.print_topics()

  
  
    
  1. [(0, '0.030*"car" + 0.026*"oil" + 0.020*"filter" + 0.018*"engine" + 0.016*"device" + 0.013*"code"

  2. + 0.012*"vehicle" + 0.011*"app" + 0.011*"change" + 0.008*"bosch"'),

  3. (1, '0.017*"easy" + 0.014*"install" + 0.014*"door" + 0.013*"tape" + 0.013*"jeep" + 0.011*"front" +

  4. 0.011*"mat" + 0.010*"side" + 0.010*"headlight" + 0.008*"fit"'),

  5. (2, '0.054*"blade" + 0.045*"wiper" + 0.019*"windshield" + 0.014*"rain" + 0.012*"snow" +

  6. 0.012*"good" + 0.011*"year" + 0.011*"old" + 0.011*"car" + 0.009*"time"'),

  7. (3, '0.044*"car" + 0.024*"towel" + 0.020*"product" + 0.018*"clean" + 0.017*"good" + 0.016*"wax" +

  8. 0.014*"water" + 0.013*"use" + 0.011*"time" + 0.011*"wash"'),

  9. (4, '0.051*"light" + 0.039*"battery" + 0.021*"bulb" + 0.019*"power" + 0.018*"car" + 0.014*"bright"

  10. + 0.013*"unit" + 0.011*"charger" + 0.010*"phone" + 0.010*"charge"'),

  11. (5, '0.022*"tire" + 0.015*"hose" + 0.013*"use" + 0.012*"good" + 0.010*"easy" + 0.010*"pressure" +

  12. 0.009*"small" + 0.009*"trailer" + 0.008*"nice" + 0.008*"water"'),

  13. (6, '0.048*"product" + 0.038*"good" + 0.027*"price" + 0.020*"great" + 0.020*"leather" +

  14. 0.019*"quality" + 0.010*"work" + 0.010*"review" + 0.009*"amazon" + 0.009*"worth"')]

Topic 3中含有“towel”、“clean”、“wax”、“water”等词语,表明这一话题和汽车清洁有关。Topic 6含有“price”、“quality”和“worth”等词语,说明和产品的价格有关。

主题可视化

为了在二维空间中对我们的主题进行可视化,我们用的是pyLDAvis库。

  
  
    
  1. # Visualize the topics

  2. pyLDAvis.enable_notebook()

  3. vis = pyLDAvis.gensim.prepare(lda_model, doc_term_matrix, dictionary)

  4. vis

其他分析网站评论的方法

除了主题建模,还有很多其他的NLP方法可以用来分析理解网络评论:

  1. 文本总结:对评语进行关键点总结。

  2. 实体识别(entity recognition):从评论中提取出实体,分析哪种产品更受欢迎。

  3. 确定流行趋势:根据评论的时间,可以掌握某一商品的受欢迎趋势。

  4. 语义分析:对零售商来说,理解评论的语义情感对改善产品和服务是非常有帮助的。

下一步工作

信息检索让我们省去了浏览大量评论的时间,也让我们知道了顾客对产品说了些什么。但是,它并没有展示出评论是积极的、中立的、还是消极的。这就是信息检索之后要做的工作。我们不仅要提取出话题,还要分析其中的情感。在接下来的文章中我们会具体讲解,请大家关注。

原文地址:www.analyticsvidhya.com/blog/2018/10/mining-online-reviews-topic-modeling-lda/

登录查看更多
18

相关内容

Natural Language Toolkit,自然语言处理工具包,在NLP领域中,最常使用的一个Python库。
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
190+阅读 · 2020年6月29日
商业数据分析,39页ppt
专知会员服务
157+阅读 · 2020年6月2日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
331+阅读 · 2020年3月17日
Python中的端对端主题建模: 隐含狄利克雷分布(LDA)
Python程序员
9+阅读 · 2019年5月15日
文本分析与可视化
Python程序员
8+阅读 · 2019年2月28日
教你在Python中实现潜在语义分析(附代码)
数据派THU
8+阅读 · 2018年12月6日
教你用Python进行自然语言处理(附代码)
数据派THU
6+阅读 · 2018年3月28日
【入门】数据分析六部曲
36大数据
17+阅读 · 2017年12月6日
文本挖掘之特征选择(python 实现)
数据挖掘入门与实战
4+阅读 · 2017年7月19日
如何用Python从海量文本抽取主题?
AI研习社
7+阅读 · 2017年7月6日
Arxiv
3+阅读 · 2018年12月18日
Arxiv
21+阅读 · 2018年8月30日
Arxiv
3+阅读 · 2017年12月18日
Arxiv
3+阅读 · 2015年5月16日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
190+阅读 · 2020年6月29日
商业数据分析,39页ppt
专知会员服务
157+阅读 · 2020年6月2日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
331+阅读 · 2020年3月17日
相关资讯
Python中的端对端主题建模: 隐含狄利克雷分布(LDA)
Python程序员
9+阅读 · 2019年5月15日
文本分析与可视化
Python程序员
8+阅读 · 2019年2月28日
教你在Python中实现潜在语义分析(附代码)
数据派THU
8+阅读 · 2018年12月6日
教你用Python进行自然语言处理(附代码)
数据派THU
6+阅读 · 2018年3月28日
【入门】数据分析六部曲
36大数据
17+阅读 · 2017年12月6日
文本挖掘之特征选择(python 实现)
数据挖掘入门与实战
4+阅读 · 2017年7月19日
如何用Python从海量文本抽取主题?
AI研习社
7+阅读 · 2017年7月6日
Top
微信扫码咨询专知VIP会员