内容简介:本文为 AI 研习社编译的技术博客,原标题 :Using Aspect-Based Sentiment Analysis to Understand User-Generated Content
本文为 AI 研习社编译的技术博客,原标题 :
Using Aspect-Based Sentiment Analysis to Understand User-Generated Content
作者 | Steve Mutuvi
翻译 | 清都江水郎、ybNero 编辑 | 王立鱼
原文链接:
https://heartbeat.fritz.ai/using-aspect-based-sentiment-analysis-to-understand-user-generated-content-2cfd5d3e25bb
注:本文的相关链接请访问文末【阅读原文】
简介
用户生成的内容(UGC)在近年来有了明显地增长。这些内容大多是文本的,主要通过在线论坛和社交媒体平台产生,同时也包含着用户对公司/组织或者热点事件的观点评论。
商业通过提供商品交易或者服务而存在,也就是说要想获得成功,与顾客的交流和关系维护便是关键因素了。分析顾客的反馈——不管是顾客的评论或是抱怨——这些分享在网上或社交媒体平台的反馈会给予商家优化顾客服务的重要观点。事实上,有大量的统计表明这类通过用户生成的内容的分析是品牌战略的重要部分。
尽管有这些公认的好处,商家要去把这些大量的无结构数据解析和重组成更易于理解和行动的见解仍是一项巨大的挑战。这些离散的无结构的自然语言文本数据尤其难以人工分析。然而,基于机器学习的观点挖掘技术拥有自动抽取观点和它们对应情感极性的巨大潜能。这种方法被称为方面级别的情感分析(ABSA)
规范地说,情感分析或观点挖掘是通过计算来研究人们的观点、情感、评价、态度、心情和情绪。方面级别的情感分析包含了2个子任务:第一,从给定的文本数据中检测出观点或方面的术语;第二,找出检测出的方面的术语所匹配的情感。
在这篇文章里,我们将展示搭建一个自然语言处理路线,从大量的顾客评论中抽取有意义的见解。这是一次从给定主题的用户生成文本中,理解观点,并将这个过程自动化的尝试。
数据集
我们在这里使用 2016年SemEval年度大赛提供的关于餐厅评论的数据集。这项大赛致力于从顾客评论中提取特定的词组和计算相关的情感值来建立他们的模型。
我们首先导入一些依赖库:
# NLTK
import nltk
from nltk.corpus import stopwords
from nltk.stem import SnowballStemmer
nltk.download('stopwords')
#Spacy
import spacy
nlp = spacy.load('en')
# Other
import re
import json
import string
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
#Keras
from keras.models import load_model
from keras.models import Sequential
from keras.layers import Dense, Activation
这个训练集使用 pandas 的 read_csv() 函数来载入数据,我们可以使用 head() 函数来查看训练集的前五条数据:
#load data
import pandas as pd
reviews_train = pd.read_csv("Training_Set_Restaurant_Cleaned.csv").astype(str)
#show first 5 records
reviews_train.head()
数据集中的前五条数据
表格中的 aspect_category 和 sentiment 属性分别代表了该评论的类别以及其情感倾向。我们可以使用下面的代码来计算全部的评论类别:
# reviews_train.columns
print(reviews_train.groupby('aspect_category').size().sort_values(ascending=False))
#how many categories
print("number of categories",reviews_train.aspect_category.nunique())
评论总类别
在我们的数据中,我们共有13种评论类别。
模型训练
通过Keras Library,我们将为方面类别和情感分类搭建并训练神经网络。Keras是一个能迅速部署实验的高阶、对用户友好、模块化并且易于拓展的神经网络接口。Keras是由Francois Chollet开发并维护的,可以运行在CPU或GPU上。
定义神经网络架构
让我们开始定义方面分类器的架构:
absa_model = Sequential()
absa_model.add(Dense(512, input_shape=(6000,), activation='relu'))
absa_model.add((Dense(256, activation='relu')))
absa_model.add((Dense(128, activation='relu')))
absa_model.add(Dense(13, activation='softmax'))
#compile model
absa_model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
我们将使用一个三层的全连接网络结构。我们首先创建一个Sequencial的对象然后使用add方法来添加模型的层。Dense类是用来定义一个全连接层,其中,网络中的每个神经元都会接收从前一层的神经元传来的全部输入。
输入的大小被设定为6000,这也就是使用词嵌入所创建的词汇量的最大值,同时还将relu设定为该模型的非线性的激活函数。非线性函数将数据转变成可以被高效分类的节点。输出层包含了13个神经元,每个对应着一个类别。softmax激活函数在我们的模型中被用于返回每个类别的概率值——目标类别会有最高的概率。
一旦我们的架构被确定,我们需要对学习过程的参数进行设置:确定优化器,损失函数和评估指标。“学习”简单地解释为找出一组模型参数的组合,最后针对给定的训练数据样本和它们对应的目标,把损失函数最小化。由于手中的问题是多分类问题,损失函数就被确定了是分类交叉熵损失。
词向量表示
为了将评论进行编码,我们使用一种叫词袋模型(BoW)的词嵌入技巧。在这种方法中,我们对一条评论使用分词(tokenized),然后得出每一个分词(token)的频率:
vocab_size = 6000 # We set a maximum size for the vocabulary
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts(reviews_train.review)
reviews_tokenized = pd.DataFrame(tokenizer.texts_to_matrix(reviews_train.review))
同时我们也需要把方面目录的列名也做编码:
label_encoder = LabelEncoder()
integer_category = label_encoder.fit_transform(reviews_train.aspect_category)
encoded_y = to_categorical(integer_category)
以上的三个步骤会在情感分类器中不断重复。然而,分类器的输出层被初始化为数值3,由于这其中有3中情感——正面的(positive)、中性的(neutral)和负面的(negative)。
#model architecture
sentiment_model = Sequential()
sentiment_model.add(Dense(512, input_shape=(6000,), activation='relu'))
sentiment_model.add((Dense(256, activation='relu')))
sentiment_model.add((Dense(128, activation='relu')))
sentiment_model.add(Dense(3, activation='softmax'))
#compile model
sentiment_model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
#create a word embedding of reviews data
vocab_size = 6000 # We set a maximum size for the vocabulary
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts(reviews_train.review)
reviews_tokenized = pd.DataFrame(tokenizer.texts_to_matrix(reviews_train.review))
#encode the label variable
label_encoder = LabelEncoder()
integer_sentiment = label_encoder.fit_transform(reviews_train.sentiment)
encoded_y = to_categorical(integer_sentiment)
训练过程
以上搭建好的模型将开始进行训练。首先,我们会在模型上使用`fit()`方法,其中的参数设置为训练数据(reviews_tokenized)、目标数据(encoded_y)、epochs数量和verbose参数。Verbose能帮助我们观察每个epoch下的训练过程。
#fit aspect classifier
absa_model.fit(reviews_tokenized, dummy_category, epochs=100, verbose=1)
#fit sentiment classifier
sentiment_model.fit(reviews_tokenized, dummy_category, epochs=100, verbose=1)
训练过程
模型的精确度可以通过超参数的调优来进行提高。
最后,如下图所示,我们用几条评论来测试我们的模型。这些评论还做了一些微小的预处理,比如把它们全部都小写化:
test_reviews = [
"Good, fast service.",
"The hostess was very pleasant.",
"The bread was stale, the salad was overpriced and empty.",
"The food we ordered was excellent, although I wouldn't say the margaritas were anything to write home about.",
"This place has totally weird decor, stairs going up with mirrored walls - I am surprised how no one yet broke their head or fall off the stairs"
]
# Aspect preprocessing
test_reviews = [review.lower() for review in test_reviews]
test_aspect_terms = []
for review in nlp.pipe(test_reviews):
chunks = [(chunk.root.text) for chunk in review.noun_chunks if chunk.root.pos_ == 'NOUN']
test_aspect_terms.append(' '.join(chunks))
test_aspect_terms = pd.DataFrame(tokenizer.texts_to_matrix(test_aspect_terms))
# Sentiment preprocessing
test_sentiment_terms = []
for review in nlp.pipe(test_reviews):
if review.is_parsed:
test_sentiment_terms.append(' '.join([token.lemma_ for token in review if (not token.is_stop and not token.is_punct and (token.pos_ == "ADJ" or token.pos_ == "VERB"))]))
else:
test_sentiment_terms.append('')
test_sentiment_terms = pd.DataFrame(tokenizer.texts_to_matrix(test_sentiment_terms))
# Models output
test_aspect_categories = label_encoder.inverse_transform(absa_model.predict_classes(test_aspect_terms))
test_sentiment = label_encoder_2.inverse_transform(sentiment_model.predict_classes(test_sentiment_terms))
for i in range(5):
print("Review " + str(i+1) + " is expressing a " + test_sentiment[i] + " opinion about " + test_aspect_categories[i])
测试结果
这个模型在对我们的测试评论中表现还不错。
结论
方面级别的情感分析(ABSA)可以帮助商业变得以顾客为重心并把他们的顾客时时牵挂在心上。这即是倾听顾客,了解顾客的发声,分析顾客的反馈然后研究更多的顾客经历和他们对产品或服务的期望。
当计算方法的使用在顾客意见挖掘上被证明是有前景的同时,更该做的便是提高这些模型的表现了。一个可信的提高模型表现的方法是使用更先进词表示技巧,尤其是与上下文语境有关的词嵌入。
与上下文语境有关的词嵌入表示起源于预训练的双向语言模型(biLMs)在近期的一系列NLP任务中取得的当前最高水平的显著进步。在这些上下文词嵌入技巧中最受关注的便是谷歌的BERT模型了。
上下文语境表示是以每个单词来表示句子中其他单词作为特征。因此,这个分类模型在从用户生成内容学习的丰富语境表达后,表现将会有显著的进步。
想要继续查看该篇文章相关链接和参考文献?
点击底部 【阅读原文】 即可访问:
https://ai.yanxishe.com/page/TextTranslation/1742
滑动查看更多内容
扫码下载
Yann Lecun 原版演讲PPT
每天进步一点点
扫码进入每日一题
扫码查看
图像处理数据集三大列表
扫码查看 Github项目:
Facebook的新研究——根据图片自动生成食谱
<< 滑动查看更多栏目 >>
点击 阅读原文 ,查看本文更多内容
以上所述就是小编给大家介绍的《通过基于情感方面的分析来理解用户生成的内容》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 论文浅尝 | 通过文本到文本神经问题生成的机器理解
- 机器学习算法生成的界面,真的能被用户理解吗?
- 深入理解python的迭代器,生成器,可迭代对象区别
- IoC-spring 的灵魂(带你轻松理解IOC思想及bean对象的生成过程)
- 实战生成对抗网络(二):生成手写数字
- 实战生成对抗网络[2]:生成手写数字
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。