美文网首页Udacity
Udacity——基于RNN网络的情感分析(一)

Udacity——基于RNN网络的情感分析(一)

作者: handSomeJoe | 来源:发表于2017-08-15 15:55 被阅读540次

    在Udacity上课也有一阵子了,所以趁着假期时间把一些小项目总结一下,这样也有助于自己今后对知识的回顾。闲话不多说,让我们开始这个有趣的项目吧!该项目是基于RNN的情感分析(项目链接),用RNN网络而不用前馈网络是因为RNN可以通过对序列的学习提高预测的准确性。数据集我们采用的是电影评论及对应的标签,RNN网络结构如图所示。

    network_diagram

    这里,我们通过嵌入层传入数据,原因是嵌入层输入数据要比独热编码有更高的表示效率(具体的内容可以参考Word2Vec原理笔记),嵌入层的数据将传入LSTM单元,最终LSTM输出的的数据将传入一个sigmoid输出层。我们使用sigmoid输出层是因为我们尝试预测文本的积极情感或者消极情感,最终输出层只有一个sigmoid激活函数单元。


    数据的预处理

    首先我们要将数据调整成适合传入网络的形式。既然我们用嵌入层,我们就要将文字转换为整数,这样的形式更加简洁。
    具体的处理的方法要基于数据本身,以我们现有的数据集为例首先观察评论数据的形式

    'bromwell high is a cartoon comedy . it ran at the same time as some other programs about school life such as teachers . my years in the teaching profession lead me to believe that bromwell high s satire is much closer to reality than is teachers . the scramble to survive financially the insightful students who can see right through their pathetic teachers pomp the pettiness of the whole situation all remind me of the schools i knew and their students . when i saw the episode in which a student repeatedly tried to burn down the school i immediately recalled . . . . . . . . . at . . . . . . . . . . high . a classic line inspector i m here to sack one of your teachers . student welcome to bromwel......'

    因此我们要做以下两个工作:

    • 删去所有的标点符号
    • 根据回车键'\n'将评论逐条存入训练数组中

    from string import punctuation
    all_text = ''.join([c for c in reviews if c not in punctuation])
    reviews = all_text.split('\n')

    此时我们就得到了评论的数组。由于我们要将文字转换为整数,因此我们要对所有文字进行统计:

    • 合并所有评论
    • 逐词将单词存入数组

    all_text = ' '.join(reviews)
    words = all_text.split()

    最终得到的单词数组形式如下:

    ['bromwell',
    'high',
    'is',
    'a',
    'cartoon',
    'comedy',
    'it',
    'ran',
    'at',
    'the',
    'same',
    'time',
    'as',
    'some',
    'other',
    'programs',
    'about',
    'school',
    'life',
    'such',
    'as',
    'teachers'...]


    评论文字转数字

    我们可以通过加工word数组,得到word:num的字典,这里值得注意的一点是由于我们会将0作为输入网络向量的初始元素,所以文字对应的数字应该从1开始,代码简单易懂如下:

    vocab_set = set(words)
    vocab_list = list(words)
    vocab_to_int = {word: (num+1) for num,word in enumerate(vocab_list)}

    得到这张word:num字典,我们就可以将评论中的文字转换为数字:

    reviews_ints = []
    for review in reviews:
    reviews_ints.append([vocab_to_int[word] for word in review.split()])

    此时评论转化后的形式:

    [[2287959,
    6015634,
    6020195,
    6020170,
    6005621,
    6013460,
    6020180,
    6003912,
    6020174,
    6020166,
    6018044,
    6020193,
    6020107,
    6020139,
    6020049,
    5991273,
    6019751,
    6015635,
    6018542,
    6017437,
    6020107,
    6005105,
    6020143,
    6019526,
    6020091,
    6020166,
    5988232,
    5703051,
    6018165,
    6019810,
    6020114,
    6019578,
    6020161,
    2287959,
    6015634,
    6020111,
    6004283...]]


    标签文字转数字

    标签中只有'positve','negative'以及'\n',我们的目的是将'positve'设定为1,'negative'设定为0并删去'\n'。

    labels = labels.split('\n')
    labels = np.array([1 if label == 'positive' else 0 for label in labels])代码如下:

    最后得到的标签数组如下所示:

    array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
    0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
    0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
    1, 0, 1, 0, 1, 0, 1, 0])


    目前为止,我们已经将评论和标签的文字均转换为了数字,但这只是数据处理的第一步,下一步我们要做的是删除长度为0的评论,因为这些评论毫无意义。要注意的一点是我们不能破坏评论—标签的位置对应关系,所以我们删减根据的是位置信息。

    non_zero_idx = [num for num,review in enumerate(reviews_ints) if len(review) != 0]
    reviews_ints = [reviews_ints[num] for num in non_zero_idx]
    labels = np.array([labels[num] for num in non_zero_idx])

    此时我们就可以对数据进行最后的统一维度处理,我们不难发现,评论文字的长短差距会很大,短则几个字,多则上千个字。因此我们设定200这个阈值,多于200个字的评论我们只保留前200个字;少于200个字的评论用0来填充剩余的长度,这样我们就统一了输入向量的维度。代码如下:

    seq_len = 200
    features = np.zeros((len(reviews_ints),seq_len),dtype=int)
    for num,review in enumerate(reviews_ints):
    features[num,-len(review):] = np.array(review)[:seq_len]

    此时我们得到的最终可以输入到网络数据形式如下:

    array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 21025, 308, 6,
    3, 1050, 207, 8, 2138, 32, 1, 171, 57,
    15, 49, 81, 5785, 44, 382, 110, 140, 15,
    5194, 60, 154, 9, 1, 4975, 5852, 475, 71,
    5, 260, 12, 21025, 308, 13, 1978, 6, 74,
    2395...]...])


    截止目前,我们已经将输入网络的数据和标签数据进行了处理,能够达到用于训练的要求,那么下一篇笔记将主要讲解该项目的网络模型。

    相关文章

      网友评论

        本文标题:Udacity——基于RNN网络的情感分析(一)

        本文链接:https://www.haomeiwen.com/subject/uxvurxtx.html