基于Keras的imdb数据集电影评论情感二分类
IMDB数据集下载速度慢,可以在我的repo库中找到下载,下载后放到/.keras/datasets/目录下,即可正常运行。)中找到下载,下载后放到/.keras/datasets/目录下,即可正常运行。
电影评论分类:二分类
二分类可能是机器学习最常解决的问题。我们将基于评论的内容将电影评论分类:正类和父类。
IMDB数据集
IMDB数据集有5万条来自网络电影数据库的评论;其中2万5千条用来训练,2万5千条用来测试,每个部分正负评论各占50%.
划分训练集、测试集的必要性:不能在相同的数据集上对机器学习模型进行测试。因为在训练集上模型表现好并不意味着泛化能力好(在没有见过的数据上仍然表现良好),而我们关心的是模型的泛化能力.
和MNIST数据集类似,IMDB数据集也集成在Keras中,同时经过了预处理:电影评论转换成了一系列数字,每个数字代表字典中的一个单词。
加载数据集
from keras.datasets import imdb
(train_data,train_labels),(test_data,test_labels) = imdb.load_data(num_words=10000)
num_words=10000意味着只保留训练集中最常出现的前10000个词,不经常出现的单词被抛弃---最终所有评论的维度保持相同。
变量train_data,test_data是电影评论的列表,每条评论由数字(对应单词在词典中出现的位置下标)列表组成。train_labels,test_labels是0,1列表,0负面评论,1表示正面评论。
>>> train_data[0]
[1, 14, 22, 16, ... 178, 32]
>>> train_labels[0]
1
预处理数据
不能直接将list类型的数据送到神经网络中训练,必须将list类型转换为tensor张量类型。有两种转换方式:
- 填充列表使每个列表长度都相同,然后转换为整数类型的张量,形状为(samples, word_indices),使用张量作为神经网络的第一层(Embedding层,能处理这样的整数类型张量);
- 将列表进行one-hot编码,转换成0、 1向量。然后用Dense网络层作为神经网络的第一层,处理浮点类型向量数据。
import numpy as np
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension)) #数据集长度,每个评论维度10000
for i, sequence in enumerate(sequences):
results[i, sequence] = 1 # one-hot
return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
y_train = np.asarray(train_labels).astype('float32') # 向量化标签数据
y_test = np.asarray(test_labels).astype('float32')
构建网络模型
现在输入数据是向量类型,对应标签数据为标量(0, 1):最容易处理的数据格式。处理这类问题最常见的网络模型是Dense网络层的线性堆叠,Dense(16, activation='relu')。
Dense网络层接收的参数16表示网络层神经元数目。一个神经元单元表示网络层表示空间的一个维度。16个神经元表示网络层权重系数形状为(input_dimensions, 16);dot点积运算将会把输出张量转换为16维度的表示张量。越多的神经元数目表示神经网络可以学习到更加复杂的特征表示,相应的计算效率降低,也可能学到不必要的特征。
Dense网络层堆叠时回答两个关键的问题:
- 有多少层网络?
- 每个层网络有多少个神经元?
激活函数能给网络模型增加非线性表示。
使用的网络模型如下:
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(16, activation='relu',input_shape=(10000,)))
model.add(layers.Dense(16,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))
最后,选择损失函数和优化算法。因为是二分类问题,网络模型的输出是一个概率,最好使用binary_crossentropy损失函数,也可以使用mean_squared_error均方误差损失函数。但是交叉熵是处理模型输出为概率时最佳选择。
配置使用rmsprop优化算法以及binary_crossentropy损失函数,选择监测的指标。
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
这里参数使用字符串传递,因为在keras中对应字符串已经定义好了。同时,可以传递函数类型给相应的参数。如:
from keras import losses
from keras import metrics
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
loss=losses.binary_crossentropy,
metrics=[metrics.binary_accuracy])
模型验证
为了在训练过程中在没有见过数据上监测准确率变化,需要分出一个验证集。从训练集中分出10000条做验证集。
x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]
在512小批量,迭代20次进行模型训练,同时在验证集上监测准确率变化。
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['acc'])
history = model.fit(partial_x_train,partial_y_train,epochs=20,batch_size=512,validation_data=(x_val, y_val))
通过调用model.fit()方法返回一个history对象,history对象有history属性---一个包含在训练过程中记录的数据的字典。
>>> history_dict = history.history
>>> history_dict.keys()
[u'acc', u'loss', u'val_acc', u'val_loss']
字典包括4个键--在训练、验证过程中被监测的指标。
在图中画出训练损失和验证损失的变化图:
import matplotlib.pyplot as plt
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, loss_values, 'bo', label='Training loss')#bo:blue dot蓝点
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')#b: blue蓝色
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
训练集和验证集上准确率变化:
plt.clf()
acc_values = history_dict['acc']
val_acc_values = history_dict['val_acc']
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
可以从上面的两张图中看到,训练损失逐渐降低,训练准确度逐渐提高--这正是使用梯度下降算法,我们所期望看到的。但是,验证损失和验证集上的准确率却在第4次迭代左右开始变差----模型在训练集上表现良好,在没有见过的数据上表现很差(泛化能力差)。用术语讲,模型发生了过拟合。在这里可以,使模型在第4次epoch时,训练结束,这样来尽可能避免过拟合现象的发生。
重新训练
model = models.Sequential()
model.add(layers.Dense(16,activation='relu',input_shape=(10000,)))
model.add(layers.Dense(16,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
model.fit(x_train,y_train,epochs=4,batch_size=512)
results = model.evaluate(x_test, y_test)
#[0.2929924130630493, 0.88327999999999995] 模型准确率为88%
使用训练好的模型在新数据上做预测
使用训练好的模型做预测----训练模型的目的.
可以使用predict函数对数据进行预测,给出为正面评论的概率。
>>> model.predict(x_test)
array([[ 0.98006207]
[ 0.99758697]
[ 0.99975556]
...,
[ 0.82167041]
[ 0.02885115]
[ 0.65371346]], dtype=float32)
小结
- 在把数据送到模型训练之前,需要对原始数据进行预处理---将原始数据转换成tensor张量格式。
- 使用relu为激活函数的Dense网络层的线性连接能解决很大一部分问题;
- 在二分类问题中,网络模型应该以包含一个神经元,激活函数为sigmoid的Dense层结束;输出是介于0~1的标量,可以理解为概率。
- 二分类问题,sigmoid标量输出,对应损失函数应该选择binary_crossentropy;
- rmsprop优化算法大多数情况下是一个很好的选择,无论问题是什么。
基于Keras的imdb数据集电影评论情感二分类的更多相关文章
- kaggle——Bag of Words Meets Bags of Popcorn(IMDB电影评论情感分类实践)
kaggle链接:https://www.kaggle.com/c/word2vec-nlp-tutorial/overview 简介:给出 50,000 IMDB movie reviews,进行0 ...
- 【项目实战】Kaggle电影评论情感分析
前言 这几天持续摆烂了几天,原因是我自己对于Kaggle电影评论情感分析的这个赛题敲出来的代码无论如何没办法运行,其中数据变换的维度我无法把握好,所以总是在函数中传错数据.今天痛定思痛,重新写了一遍代 ...
- 基于keras中IMDB的文本分类 demo
本次demo主题是使用keras对IMDB影评进行文本分类: import tensorflow as tf from tensorflow import keras import numpy a ...
- keras框架下的深度学习(二)二分类和多分类问题
本文第一部分是对数据处理中one-hot编码的讲解,第二部分是对二分类模型的代码讲解,其模型的建立以及训练过程与上篇文章一样:在最后我们将训练好的模型保存下来,再用自己的数据放入保存下来的模型中进行分 ...
- 电影评论分类:二分类问题(IMDB数据集)
IMDB数据集是Keras内部集成的,初次导入需要下载一下,之后就可以直接用了. IMDB数据集包含来自互联网的50000条严重两极分化的评论,该数据被分为用于训练的25000条评论和用于测试的250 ...
- kaggle之电影评论文本情感分类
电影文本情感分类 Github地址 Kaggle地址 这个任务主要是对电影评论文本进行情感分类,主要分为正面评论和负面评论,所以是一个二分类问题,二分类模型我们可以选取一些常见的模型比如贝叶斯.逻辑回 ...
- tensorflow 教程 文本分类 IMDB电影评论
昨天配置了tensorflow的gpu版本,今天开始简单的使用一下 主要是看了一下tensorflow的tutorial 里面的 IMDB 电影评论二分类这个教程 教程里面主要包括了一下几个内容:下载 ...
- 京东评论情感分类器(基于bag-of-words模型)
京东评论情感分类器(基于bag-of-words模型) 近期在本来在研究paraVector模型,想拿bag-of-words来做对照. 数据集是京东的评论,经过人工挑选,选出一批正面和负面的评论. ...
- 基于Keras 的VGG16神经网络模型的Mnist数据集识别并使用GPU加速
这段话放在前面:之前一种用的Pytorch,用着还挺爽,感觉挺方便的,但是在最近文献的时候,很多实验都是基于Google 的Keras的,所以抽空学了下Keras,学了之后才发现Keras相比Pyto ...
随机推荐
- Office 365实现单点登录系列(2)—Azure AD Connect安装与配置
前言 第一篇文章我已经为大家分享了在在Azure上搭建域控服务器的方法,如果大家本地已经有了域环境,可以直接从这一篇文章开始阅读.Azure AD Connect的前身是DirSync,是专门用于目录 ...
- shell命令工作总结
shell命令工作总结: 1.sed命令:1.1.将文本input.txt中含有”姓名”字符串的行中的谢朝辉替换成扎巴依:sed -e '/姓名/s/谢朝辉/扎巴依/g' input.txt1.2.将 ...
- September 17th 2017 Week 38th Sunday
Distance could make you forget about them, but the memories would always be there. 距离会让你遗忘,但是回忆却始终在那 ...
- 关于RSA、公钥、私钥、加密、签名的那些概念
前言 作为一名程序员,经常会听到加密解密之类的词.而非对称加密技术,应用的非常广泛.本文不写加密技术的原理,只是希望以一个简单的类比,让大家了解非对称加密中常见词的概念,以及它的作用. 介绍 在RSA ...
- ZT 安卓手机的安全性 prepare for Q
如何增强安卓手机的安全性?安卓的安全性太低了!!! 众所周知,安卓手机是非常容易破解的,刷过机的人都知道,不管你之前在手机怎么设置密码,只要进入recovery清空使用记录,手机就会恢复出厂设置,到时 ...
- ZT 类模板的声明和实现是不能分离的
http://bbs.csdn.net/topics/380250382 adlay adlay 等级: #9 得分:0 回复于: 2012-03-31 11:19:35 引用 6 楼 的回复: 引 ...
- 【FLEX教程】#008 开发中的问题笔记(慢更…)
在这里记录一下个人在FLEX开发中遇到的一些问题.方便一些遇到同样问题的朋友们,能够快速的解决这些问题. 这篇笔记我会慢慢的更新,(PS:有遇到问题就往上面更….) 2015年1月4日 12:53:5 ...
- SQL Server 中的排名函数与使用场景
1.RowNumber() Over (oder by.....) 在需要对某个不连续ID的表进行排序时使用 2.ROW_NUMBER() over(PARTITION by ...... ord ...
- JSF标签之f:facet 的用法
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zkn_CS_DN_2013/article/details/33717091 f:facet标签用来 ...
- DNS_PROBE_FINISHED_NXDOMAIN 问题解决
手动设置 (说明:如果您使用DNS有特殊设置,请保存设置后再进行操作) 1.打开[控制面板]→[网络连接]→打开[本地连接]→[属性]:2.双击[Internet 协议(TCP/IP)]→选择[自 ...