使用LSTM进行情感分析学习实例一含数据和代码分析

使用LSTM进行情感分析

原理见https://mp.csdn.net/console/editor/html/108697113

数据集见下文https://pan.baidu.com/s/1SctPmfFlq6ilY2bxcXHIFA

使用keras实现LSTM 情感分析见https://blog.csdn.net/ghj786110/article/details/89669783

案例流程

1) 制作词向量,可以使用gensim这个库,也可以直接用现成的
2) 词和ID的映射,常规套路了
3) 构建RNN网络架构
4) 训练我们的模型

数据集
IMDB数据集下载地址为:http://ai.stanford.edu/~amaas/data/sentiment/数据集应用于影评情绪的分类。

另提一句,该数据集也集成在tensorflow的keras模块中,可以通过以下语句导入。

from keras.datasets import imdb
 
# num_words参数为保留训练集出现频率在前10000的词。
(train_data,train_labels),(test_data,test_labels) = imdb.load_data(num_words=10000)

使用Keras首次导入时要下载 链接如下

https://pan.baidu.com/s/15belo01keGvFri43K8TxFQ 提取码:9h3u

 导入数据

首先,我们需要去创建词向量。为了简单起见,我们使用训练好的模型来创建。

作为该领域的一个最大玩家,Google 已经帮助我们在大规模数据集上训练出来了 Word2Vec 模型,包括 1000 亿个不同的词!在这个模型中,谷歌能创建 300 万个词向量,每个向量维度为 300。

在理想情况下,我们将使用这些向量来构建模型,但是因为这个单词向量矩阵相当大(3.6G),我们用另外一个现成的小一些的,该矩阵由 GloVe 进行训练得到。矩阵将包含 400000 个词向量,每个向量的维数为 50。

我们将导入两个不同的数据结构,一个是包含 400000 个单词的 Python 列表,一个是包含所有单词向量值得 400000*50 维的嵌入矩阵。

import tensorflow as tf

import numpy as np

from random import randint

import time

import re

from os import listdir

from os.path import isfile, join

import matplotlib.pyplot as plt


def getTrainBatch():  # 从文件总获取训练集

    labels = []

    arr = np.zeros([batchSize, maxSeqLength])

    for i in range(batchSize):

        if (i % 2) == 0:

            num = randint(1, 11499)

            labels.append([1, 0])

        else:

            num = randint(13499, 24999)

            labels.append([0, 1])

        arr[i] = ids[num - 1:num]

    return arr, labels


def getTestBatch():  # 从文件中获取数据集

    labels = []

    arr = np.zeros([batchSize, maxSeqLength])

    for i in range(batchSize):

        num = randint(11499, 13499)

        if (num <= 12499):

            labels.append([1, 0])

        else:

            labels.append([0, 1])

        arr[i] = ids[num - 1:num]

    return arr, labels


if __name__ == "__main__":

    maxSeqLength = 250

    batchSize = 24#批处理大小
    numDimensions = 250

    lstmUnits = 64#LSTM的单元个数

    numClasses = 2#分类类别

    iterations = 50000#和训练次数

    wordsList = np.load(r'.\training_data\wordsList.npy')
    print('Loaded the word list!')
    wordsList = wordsList.tolist()#Originally loaded as numpy array

    wordsList = [word.decode('UTF-8') for word in wordsList]  # 进行解码,这一步很重要,不然回报word not in vocab错误

    wordVectors = np.load(r'.\training_data\wordVectors.npy')
    print('Loaded the word vectors!')
    print(len(wordsList))
    print(wordVectors.shape)

    ids = np.load(r'.\LSTM\training_data\idsMatrix.npy')

    tf.reset_default_graph()

    input_data = tf.placeholder(tf.int32, shape=[batchSize, maxSeqLength])  # 占位符,必不可少

    labels = tf.placeholder(tf.int32, shape=[batchSize, numClasses])  # 根据其格式来写

    data = tf.Variable(tf.zeros([batchSize, maxSeqLength, numDimensions]), dtype=tf.float32)

    data = tf.nn.embedding_lookup(wordVectors, input_data)  # 按照索引来找相应的词向量

    data = tf.cast(data, tf.float32)  # 由于版本的问题,这一步必不可少,将x的数据格式转化成dtype,有的版本可以不写

    # LSTM网络的构建

    lstmCell = tf.contrib.rnn.BasicLSTMCell(lstmUnits)  # lstmUnits为cell中隐藏层神经元的个数

    lstmCell = tf.contrib.rnn.DropoutWrapper(cell=lstmCell, output_keep_prob=0.75)

    value, _ = tf.nn.dynamic_rnn(lstmCell, data, dtype=tf.float32)

    weight = tf.Variable(tf.truncated_normal([lstmUnits, numClasses]))

    bias = tf.Variable(tf.constant(0.1, shape=[numClasses]))

    value = tf.transpose(value, [1, 0, 2])  # value的输出为[batchsize,length,hidden_size]

    # 也可以写成 value, states = tf.nn.dynamic_rnn(lstmCell, data, dtype=tf.float32),vale=states[-1],可以先打印出states的shape再进行判断

    last = tf.gather(value, int(value.get_shape()[0]) - 1)  # 上述对value做这种变化与注释中states[-1]结果相似

    prediction = (tf.matmul(last, weight) + bias)  # 可以再加上softmax层

    correctPred = tf.equal(tf.argmax(prediction, 1), tf.argmax(labels, 1))  # 与标签进行判断

    accuracy = tf.reduce_mean(tf.cast(correctPred, tf.float32))

    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=labels))  # 计算交叉熵

    optimizer = tf.train.AdamOptimizer().minimize(loss)  # 随机梯度下降最小化loss

    with tf.Session() as sess:

        saver = tf.train.Saver()  # 保存模型

        sess.run(tf.global_variables_initializer())  # 初始化变量

        for i in range(iterations):

            # Next Batch of reviews

            nextBatch, nextBatchLabels = getTrainBatch()

            sess.run(optimizer, {input_data: nextBatch, labels: nextBatchLabels})

            if (i % 1000 == 0 and i != 0):
                loss_ = sess.run(loss, {input_data: nextBatch, labels: nextBatchLabels})

                accuracy_ = sess.run(accuracy, {input_data: nextBatch, labels: nextBatchLabels})

                print("iteration {}/{}...".format(i + 1, iterations),

                      "loss {}...".format(loss_),

                      "accuracy {}...".format(accuracy_))

                # Save the network every 10,000 training iterations

            if (i % 10000 == 0 and i != 0):
                save_path = saver.save(sess, "models/pretrained_lstm.ckpt", global_step=i)

                print("saved to %s" % save_path)
iterations = 10
for i in range(iterations):
    nextBatch, nextBatchLabels = getTestBatch();
    print("Accuracy for this batch:", (sess.run(accuracy, {input_data: nextBatch, labels: nextBatchLabels})) * 100)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值