当前位置: 91看电影 > 影评观感 > 正文

(tensorflow)对电影评论进行文本分类

2018-10-10 19:51 17

本文利用tensorflow.keras对电影评论进行文本分类,分为正面和负面两个类别。这是二分类器的一个经典例子。二分类器是一个重要且应用广泛的机器学习问题。

我们将使用IMDB数据集,这个数据集包含50,000从国际电影数据库中摘录的电影评论数据,我们将其拆分为25,000的训练集和25,000的测试集。训练集和测试集是平衡样本,即他们所包含相同的正负样本数。

我们使用tf.keras,它是tensorflow中的一个高层次的api, 用来建立及训练模型。首先导入必须的库。

importtensorflow as tf

from tensorflowimport keras

import numpy asnp

print(tf.__version__)

1.11.0

下载IMDB数据集:

       IMDB数据集打包在Tensorflow中,它已经经过处理,每个单词是词典中的索引位置。

下面的代码下载IMDB数据集到你的机器中,也可以事先下载,然后通过path参数指定文件。

Imdb = keras.datasets.imdb

(train_data,train_labels), (test_data,test_labels) = imdb.load(num_words=10000)

其中,参数num_words=10000,保留出现频率最高的10000个单词。

浏览数据:

让我们花一点时间来理解下数据格式,这个数据集经过预处理,每个样本是一个整数组成的数组,每个数字代表电影评论的单词。每个标签是一个整数0或者1,0是负面评论,1是正面评论。

print("Training entries: {}, labels: {}".format(len(train_data),len(train_labels)))

Trainingentries: 25000, labels: 25000

评论的文本被转为了整数,每个整数代表字典中的一个特定的词。

print(train_data[0])

电影评论可能有不同的长度。下面的代码显示出第一个评论的长度与第二个评论的长度的不同,由于神经网络的输入必须有相同的长度,因此我们需要在后面解决这个问题。

len(train_data[0],len(train_data[1])

把整数转回为单词:

知道如何把整数转回为单词可能是有用的,这里,我们将编写一个函数用来查询一个包含整数到字符映射的字典对象。

# A dictionary mapping words to an integerindex

word_index = imdb.get_word_index()

# The first indices are reserved

word_index = {k:(v+3) for k,v inword_index.items()}

word_index[""] = 0

word_index[""] = 1

word_index[""] =2  # unknown

word_index[""] = 3

reverse_word_index = dict([(value, key) for(key, value) in word_index.items()])

def decode_review(text):

return ''.join([reverse_word_index.get(i, '?') for i in text])

现在,我们可以使用decode_review函数来展示第一个评论的文本:

decode_review(train_data[0])

准备数据:

在输入到神经网络之前,整数数组构成的评论必须转化为张量,此转化可以有两种方法:

  • One-hot编码。此方法需要单词数*评论数大小的矩阵

  • 填充评论以便他们有相同的长度。这将产生最大长度*评论数大小的张量.我们可以使用嵌入层来处理这种形状的张量。

在此文章中,我们使用第二种方法。

我们使用pad_sequences 函数来表转化长度:

train_data =keras.preprocessing.sequence.pad_sequences(train_data,

                                                     value=word_index[""],

                                                       padding='post',

                                                        maxlen=256)

test_data =keras.preprocessing.sequence.pad_sequences(test_data,

                                                     value=word_index[""],

                                                      padding='post',

                                                      maxlen=256)

建立模型:

此神经网络需要堆积层来实现,这需要两个关键的决定:

  • 模型中使用几层?

  • 每层中的隐藏神经元有几个?

在此例子,输入数据由单词数组构成,预测的标签是1或者0.让我们为这个问题建立模型:

# input shape is the vocabulary count usedfor the movie reviews (10,000 words)

vocab_size = 10000

model = keras.Sequential()

model.add(keras.layers.Embedding(vocab_size,16))

model.add(keras.layers.GlobalAveragePooling1D())

model.add(keras.layers.Dense(16,activation=tf.nn.relu))

model.add(keras.layers.Dense(1,activation=tf.nn.sigmoid))

model.summary()

这些层按顺序堆叠在一起构建此分类器:

  • 第一层为 Embedding 层,结果的维度为(batch, sequence, embedding).

  • 第二层为 GlobalAveragePooling1D层,返回序列维度的平均值长度的输出向量。

  • 第二层的输出通过全连接层连接16个隐藏神经元。

  • 最后一层为单节点输出,激活函数使用sigmoid。表示置信度。

  • 损失函数和优化器:

    一个模型需要损失函数和优化器来进行训练,由于这是一个二分类问题,模型的输出为0-1之间的概率值,因此我们使用binary_crossentropy 损失函数。

    但这并不是唯一的选择,我们也可以选择mean_squared_error,但是,通常来说,binary_crossentropy 是处理概率问题较好的选择,它测量概率分布间的距离。

    然后,当我们探索回归问题时,我们将看到如何使用另外的叫均方误差的损失函数。

    下面,让我们用损失函数和优化器来配置此模型:

                  loss='binary_crossentropy',

                  metrics=['accuracy'])

    产生验证集:

    当训练时,我们想要验证此时模型的精确度,我们从原始训练集中分出10,000个验证集.

    x_val = train_data[:10000]

    partial_x_train = train_data[10000:]

    y_val = train_labels[:10000]

    partial_y_train = train_labels[10000:]

    训练模型:

    我们用40个迭代来训练模型,每批512个样品数。40个迭代在所有的x_train 和y_train样本上,当训练时,监视模型在验证集上的损失和精确度。

    history = model.fit(partial_x_train,

                        partial_y_train,

                        epochs=40,

                        batch_size=512,

                        validation_data=(x_val,y_val),

                       verbose=1)

    评估模型:

    下面,让我们来看看模型的表现,我们将看到两个值,损失和准确度。

    results = model.evaluate(test_data,test_labels)

    print(results)

    25000/25000 [==============================] - 1s34us/step

    产生精确度和损失对时间的图:

    model.fit() 返回一个history对象,此对象包含训练过程中所有数据字典。

    欢迎 发表评论:

    Copyright © 2018 91看电影