1. 编程大数据数据科学使用AI进行情感分析

约翰·保罗·穆勒(John Paul Mueller),卢卡·穆勒(Luca Mueller)

情感分析是根据作者对文本主题的态度(无论是积极的,消极的还是中立的)从书面文本中计算得出的。事实证明,这种分析对从事营销和传播工作的人员很有用,因为它可以帮助他们了解客户和消费者对产品或服务的看法,从而采取适当的行动(例如,尝试恢复不满意的客户或决定使用其他销售策略) )。每个人都进行情绪分析。例如,在阅读文本时,人们自然会尝试确定使书写文本的人感动的情感。但是,当阅读和理解的文本数量过多且文本不断积累时(例如在社交媒体和客户电子邮件中),自动进行情感分析非常重要。

人工智能情绪分析

即将到来的示例是使用Keras和TensorFlow对RNN进行的测试,它构建了一种情感分析算法,能够对电影评论中表达的态度进行分类。数据是IMDb数据集的样本,其中包含50,000个电影评论(在火车和测试集之间分成两半),并带有表示评论情绪的标签(0 =负面,1 =正面)。 IMDb是一个大型在线数据库,其中包含有关电影,电视连续剧和视频游戏的信息。最初由粉丝群维护,现在由亚马逊子公司运营。在IMDb上,人们可以找到自己喜欢的节目所需的信息,并发表评论或撰写评论以供其他访问者阅读。

Keras提供了IMDb数据的可下载包装。您准备,随机整理这些数据并将其安排到训练和测试集中。特别是,Keras提供的IMDb文本数据将清除标点符号,并标准化为小写形式,然后转换为数值。每个单词被编码成一个数字,表示其频率排名。最常见的单词数量很少;频率较低的单词具有较高的数字。

首先,该代码从Keras导入了imdb函数,并使用它从Internet检索数据(下载约17.5MB)。该示例使用的参数仅包含前10,000个单词,Keras应该使用特定的随机种子对数据进行混洗。 (了解种子可以根据需要再现随机播放。)该函数返回两个训练集和测试集,均由文本序列和情感结果组成。

从keras.datasets导入imdb
top_words = 10000
(((x_train,y_train),
(x_test,y_test))= imdb.load_data(num_words = top_words,
种子= 21)

前面的代码完成后,您可以使用以下代码检查示例数:

print(“培训示例:%i”%len(x_train))
print(“测试示例:%i”%len(x_test))

在查询了可用于神经网络的训练和测试阶段的案例数之后,该代码为每个阶段输出了25,000个示例的答案。 (此数据集是一个相对较小的语言问题;显然,该数据集主要用于演示目的。)此外,代码确定该数据集是否平衡,这意味着它具有几乎相同数量的正面和负面情绪示例。

将numpy导入为np
打印(np.unique(y_train,return_counts = True))

结果array([12500,12500])确认数据集在正面和负面结果之间平均分配。响应类之间的这种平衡完全是由于数据集的说明性。在现实世界中,您很少会找到平衡的数据集。下一步将创建一些Python字典,这些字典可以在数据集中使用的代码和真实单词之间进行转换。实际上,此示例中使用的数据集已经过预处理,并提供了代表单词的数字序列,而不是单词本身。 (您在Keras中找到的LSTM和GRU算法期望将数字序列作为数字。)

word_to_id = {imdb.get_word_index()。items()中w,i的w:i + 3}
id_to_word = {0: '',1: '',2: ''}
id_to_word.update({i + 3:w for imb.get_word_index()。items()中的w,i})
def convert_to_text(sequence):
返回''.join(如果s> = 3,则按顺序[[id_to_word [s] for s]))
打印(convert_to_text(x_train [8]))

前面的代码段定义了两个转换字典(从单词到数字代码,反之亦然)和一个将数据集示例转换为可读文本的函数。举例来说,代码印出了第九个示例:“这部电影就像火车残骸一样严重……”。从此摘录中,您可以轻松地预测这部电影的情绪不是积极的。诸如坏,残骸和恐怖之类的词语传达出强烈的消极情绪,这使猜测正确的情绪变得容易。

在此示例中,您将收到数字序列并将其转换回单词,但是相反的情况很常见。通常,您会得到由单词组成的词组,并将其转换为整数序列,以馈送到RNN层。 Keras提供了专门的功能Tokenizer,可以为您完成此任务。它使用fit_on_text方法来学习如何从训练数据中将单词映射为整数,并使用texts_to_matrix将文本转换为序列。

但是,用其他短语来说,您可能找不到用于情感分析的显眼单词。这种感觉以一种更加微妙或间接的方式表达,并且在文本的早期可能无法理解情绪,因为揭示的短语和单词可能会在话语的后面出现。因此,您还需要确定要分析的短语数量。

按照惯例,您将文本的开头部分用作整个评论的代表。有时候,您只需要几个初始单词(例如前50个单词)即可理解。有时您需要更多。特别是较长的文字不会尽早揭示其方向。因此,您可以根据自己的理解理解文本的类型,并决定使用深度学习分析多少个单词。本示例仅考虑前200个字,这足够了。

您已经注意到,代码开始为以数字3开头的单词提供代码,从而使代码从0到2。较低的数字用于特殊标记,例如表示短语的开始,填充空白以固定顺序以一定的长度,并标记出由于频率不够高而被排除的单词。本示例仅选择最常见的10,000个单词。使用标记指出开始,结束和值得注意的情况是与RNN配合使用的技巧,特别是对于机器翻译。

从keras.preprocessing.sequence导入pad_sequences
max_pad = 200
x_train = pad_sequences(x_train,
maxlen = max_pad)
x_test = pad_sequences(x_test,
maxlen = max_pad)
打印(x_train [0])

通过使用来自Keras的pad_sequences函数(将max_pad设置为200),代码将使用每个评论的前200个单词。如果审阅包含少于200个单词,则在序列之前需要达到必要数量的零值以达到所需数量的序列元素。将序列切成一定长度并用零值填充空隙称为输入填充,这是使用像深度学习算法这样的RNN时的重要处理活动。现在,代码设计了体系结构:

从keras.models导入顺序
从keras.layers导入双向,密集,辍学
从keras.layers导入GlobalMaxPool1D,LSTM
从keras.layers.embeddings导入嵌入
embedding_vector_length = 32
模型= Sequential()
model.add(Embedding(top_words,
embedding_vector_length,
input_length = max_pad))
model.add(双向(LSTM(64,return_sequences = True)))
model.add(GlobalMaxPool1D())
model.add(Dense(16,activation =“ relu”))
model.add(Dense(1,activation =“ sigmoid”))
model.compile(loss ='binary_crossentropy',
Optimizer ='adam',
指标= ['准确性'])
打印(model.summary())

之前的代码段定义了深度学习模型的形状,其中使用了一些专用层来进行Keras的自然语言处理。该示例还需要模型的摘要(model.summary()命令),以通过使用不同的神经层来确定体系结构正在发生的情况。

您具有嵌入层,该层将数字序列转换为密集的单词嵌入。这种类型的单词嵌入更适合由RNN层学习。 Keras提供了一个嵌入层,除了不一定必须是网络的第一层之外,它还可以完成两项任务:

  • 将预训练的单词嵌入(例如Word2vec或GloVe)应用于序列输入。您只需要将包含嵌入的矩阵传递给其参数权重即可。 根据收到的输入从头开始创建单词嵌入。

在第二种情况下,嵌入只需要知道:

  • input_dim:数据期望的词汇量 output_dim:将要产生的嵌入空间的大小(所谓的尺寸) input_length:期望的序列大小

确定参数后,嵌入将找到更好的权重,以在训练过程中将序列转换为密集矩阵。密集的矩阵大小由序列的长度和嵌入的维数确定。

如果使用Keras提供的“嵌入”层,则必须记住,该函数仅提供词汇量乘以所需嵌入尺寸的权重矩阵。它将单词映射到矩阵的各列,然后将矩阵权重调整为提供的示例。尽管该解决方案对于非标准语言问题是可行的,但它与先前讨论的词嵌入不同,后者以不同的方式在数百万个示例中进行了训练。

该示例使用双向包装-64个单元的LSTM层。通过将普通LSTM层加倍,可以对其进行双向转换:在第一方面,它将应用您提供的普通输入序列;在第二个,它通过序列的相反。之所以使用这种方法,是因为有时您会以不同的过度适合的顺序使用单词,并且构建双向图层会捕获任何单词模式,无论顺序如何。 Keras的实现确实非常简单:只需将其作为函数应用在要双向渲染的图层上即可。

双向LSTM设置为返回序列(return_sequences = True);也就是说,对于每个单元格,它返回查看序列中每个元素后提供的结果。对于每个序列,结果是200 x 128的输出矩阵,其中200是序列元素的数量,而128是该层中使用的LSTM单元的数量。此技术可防止RNN获取每个LSTM单元的最后结果。关于文本情感的提示实际上可以出现在嵌入单词序列中的任何位置。

简而言之,重要的是不要获取每个单元格的最后结果,而要获取最佳结果。因此,该代码依赖于下一层GlobalMaxPool1D来检查每个LSTM单元提供的每个结果序列,并仅保留最大结果。那应该确保该示例从每个LSTM单元中拾取最强的信号,希望通过训练以挑选出一些有意义的信号来对它进行专门化。

在对神经信号进行滤波之后,该示例将具有128个输出层,每个LSTM单元一个。该代码使用具有ReLU激活的16个神经元的连续密集层来减少和混合信号(因此仅使正信号通过)。该体系结构的最后一个节点是使用S型激活的节点,它将结果压缩到0–1范围内并使它们看起来像概率。

定义了架构之后,您现在可以训练网络以执行情感分析。三个时期(通过网络将数据传递三遍以使其学习模式)就足够了。该代码每次使用256个批处理进行批处理,这使网络在使用反向传播更新权重之前,每次都能看到足够多的单词和情感。最后,代码着重于验证数据(不是培训数据的一部分)提供的结果。从验证数据中获得良好结果意味着神经网络正在正确处理输入。该代码在每个时期完成后就报告验证数据。

历史= model.fit(x_train,y_train,
validation_data =(x_test,y_test),
epochs = 3,batch_size = 256)

获得结果需要一段时间,但是如果您使用的是GPU,那么它将在您喝一杯咖啡的时间内完成。此时,您可以再次使用验证数据评估结果。 (结果不应与培训期间的代码报告有任何惊奇或差异。)

损失,度量= model.evaluate(x_test,y_test,verbose = 0)
打印(“测试精度:%0.3f”%指标)

最终的准确度(即来自深度神经网络的正确答案的百分比)约为85-86%。由于构建神经网络时的随机性,每次运行实验的结果都会略有变化。考虑到要处理的数据量很小,这完全正常。如果您从正确的幸运举重开始,那么在如此短的培训课程中学习将变得更加容易。

最后,您的网络是一种情绪分析器,可以正确地猜测电影评论中表达的情绪,大约有85%的时间。有了更多的训练数据和更复杂的神经体系结构,您可以获得的结果会更加令人印象深刻。在市场营销中,类似的工具用于自动执行许多需要阅读文本并采取措施的流程。同样,您可以将像这样的网络与听声音并将其转换为文本的神经网络耦合。 (这是RNN的另一个应用程序,现在可以为Alexa,Siri,Google语音和许多其他个人助理提供支持。)过渡使该应用程序即使在语音表达(例如来自客户的电话)中也可以理解情绪。