二分类问题可能是应用最广泛的机器学习问题。今天我们将学习根据电影评论的文字内容将其划分为正面或负面。

一、数据集来源

我们使用的是IMDB数据集,它包含来自互联网电影数据库(IMDB)的50000条严重两极分化的评论。为了避免模型过拟合只记住训练数据,我们将数据集分为用于训练的25000条评论与用于测试的25000条评论,训练集和测试集都包含50%的正面评论和50%的负面评论。

与MNIST数据集一样,IMDB数据集也内置于Keras库。它已经过预处理:评论(单词序列)已经被转换为整数序列,其中每个整数代表字典中的某个单词。

通过以下代码加载数据集并限制每条评论最多取前一万个常用的word,以便于我们进行向量处理。

import tensorflow as tfimdb = tf.keras.datasets.imdb
(train_data, train_labels),(test_data, test_labels) = imdb.load_data(num_words=10000)
print(train_data[0])
print(train_labels[0])

通过输出可以看到,train_data和test_data是评论记录的集合,每条评论记录又是由众多的单词索引组成的集合。
train_labels和test_labels是针对评论的分类的集合,其中0表示负面评论,1表示正面评论。

[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]
1

我们可以通过word与编号的映射关系将评论的内容转化为具体的文本

def get_text(comment_num):"""将数字形式的评论转化为文本"""# word_index = tf.keras.datasets.imdb.get_word_index()word_index = imdb.get_word_index()reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])text = ' '.join([reverse_word_index.get(i - 3, '?') for i in comment_num])return textcomment = get_text(train_data[0])
print(comment)

第一条电影评论的内容

? this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert ? is an amazing actor and now the same being director ?

二、格式化输入数据

由于我们无法直接将整数序列输入神经网络,所以需要将其转换为张量。可以通过以下两种方式进行转化

  • 填充列表,使其具有相同的长度,然后将列表转化为(samples, word_index)的2D形状的整数张量。
  • 对列表进行one-hot编码,将其转化为0和1组成的向量。

这里我们采用one-hot进行编码处理

def vectorize_sequences(sequences, diamension = 10000):results = np.zeros((len(sequences), diamension))for i, sequence in enumerate(sequences):results[i, sequence] = 1return resultsx_train = vectorize_sequences(train_data)
print(x_train[0])
print(len(x_train[0]))
x_test = vectorize_sequences(test_data)
print(x_test[0])
print(len(x_test[0]))

转化完成的输入结果

[0. 1. 1. ... 0. 0. 0.]
10000
[0. 1. 1. ... 0. 0. 0.]
10000

将标签进行向量化处理

y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

三、构建神经网络

针对这里二分类单标签,我们可以直接使用带有relu激活函数的全连接层的简单堆叠。
我们使用了两个具有16个隐藏单元的中间层和具有一个隐藏单元的层。中间层使用的relu激活函数负责将所有的负值归零,最后一层使用sigmoid函数将任意值压缩到[0,1]之间并作为预测结果的概率。

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'))

这里的Dense层实现了如下的张量计算,传入Dense层的参数16表示隐藏单元的个数,同时也表示这个层输出的数据的维度数量。隐藏单元越多,网络越能够学习到更加复杂的表示,但是网络计算的代价就越高。

output = relu(dot(W, input) + b)

我们使用rmsprop优化器和binary_crossentropy损失函数来配置模型。

model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

四、训练模型

将训练数据分出一小部分作为校验数据,同时将512个样本作为一批量处理,并进行20轮的训练,同时出入validation_data来监控校验样本上的损失和计算精度。

x_val = x_train[:10000]
partial_x_train = x_train[10000:]y_val = y_train[:10000]
partial_y_train = y_train[10000:]
history = model.fit(partial_x_train, partial_y_train, epochs= 20, batch_size=512, validation_data=(x_val, y_val))

调用fit()返回的history对象包含训练过程的所有数据

history_dict = history.history
print(history_dict.keys())

字典中包含4个条目,对应训练过程和校验过程的指标,其中loss是训练过程中损失指标,accuracy是训练过程的准确性指标,而val_loss是校验过程的损失指标,val_accuracy是校验过程的准确性指标。

dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])

我们使用Matplotlib画出训练损失和校验损失的情况

loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(loss_values) + 1)plt.plot(epochs, loss_values, 'bo', label='Training loss')
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

从图中可以看到整个训练过程,损失函数值一直在不断的变小,但是校验过程的损失函数值却先变小后变大,在2.5-5之间的某个点达到最小值。

我们使用Matplotlib画出训练精度和校验精度的情况

plt.clf()
acc = history_dict['accuracy']
val_acc = history_dict['val_accuracy']
plt.plot(epochs, acc, 'bo', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

从图中可以看到整个训练过程,准确度值一直在不断的升高,但是校验过程的精度数值却在不断的进行波动,在2.5-5之间的某个点达到最大值。

通过对训练和校验指标的分析,可以看到训练的损失每轮都在降低,训练的精度每轮都在提升。但是校验损失和校验精度基本上在第4轮左右达到最佳值。为了防止这种过拟合的情况,我们可以在第四轮完成之后直接停止训练。

history = model.fit(partial_x_train, partial_y_train, epochs= 4, batch_size=512, validation_data=(x_val, y_val))
results = model.evaluate(x_test, y_test)
print(results)

重新执行可以看到模型的精度可以达到87%

782/782 [==============================] - 1s 876us/step - loss: 0.3137 - accuracy: 0.8729
[0.3137112557888031, 0.8728799819946289]

五、使用测试数据预测结果

使用训练的模型对test数据集进行预测

result = model.predict(x_test)
print(result)
[[0.31683978][0.9997941 ][0.9842608 ]...[0.18170357][0.23360077][0.6573206 ]]

六、小结

  • 需要对原始数据进行预处理并转化为符合要求的张量。
  • 对于二分类问题,最后一层使用sigmoid作为激活函数,并输出0-1的标量来表示结果出现的概率。
  • 对于二分类问题的sigmoid标量输出,应该使用binary_crossentropy损失函数。
  • 随着训练过程的进行,很容易出现过拟合现象,我们需要时刻监控模型在非训练数据集的表现。

完整代码下载

深度学习之电影二分类的情感问题相关推荐

  1. 深度学习1:二分类问题

    IMDB数据 包含来自互联网电影数据库的50000条两极分化的评论,数据集被分为用于训练的25000条评论与用于测试的25000条评论,训练集和测试集都包含百分之五十的正面评论和百分之五十负面评论. ...

  2. 深度学习2.1二分类(Binary Classification)

    二分类-深度学习2.1-吴恩达老师课程 介绍 案例 符号定义 仅作为个人学习记录 介绍 当实现一个神经网络的时候,我们需要知道一些非常重要的技术和技巧.例如有一个包含mmm个样本的训练集,你很可能习惯 ...

  3. 基于深度学习的简单二分类(招聘信息的真假)

    招聘数据真假分类 此次机器学习课程大作业-招聘数据真假分类,是一个二分类问题.训练集中共有14304个样本,每个样本有18个特征,目标是判断不含有标签的招聘信息的真假性. 利用Pandas读取训练集和 ...

  4. 【NLP】相当全面:各种深度学习模型在文本分类任务上的应用

    论文标题:Deep Learning Based Text Classification:A Comprehensive Review 论文链接:https://arxiv.org/pdf/2004. ...

  5. 用深度学习解决大规模文本分类问题

     用深度学习解决大规模文本分类问题 人工智能头条 2017-03-27 22:14:22 淘宝 阅读(228) 评论(0) 声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者 ...

  6. 利用深度学习(Keras)进行癫痫分类-Python案例

    目录 癫痫介绍 数据集 Keras深度学习案例 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 QQ交流群:903290195 癫痫介绍 癫痫,即俗称"羊癫风",是由多种 ...

  7. 产品经理之深度学习促进产品(二)

    产品经理之深度学习促进产品(二) 案例一 阿里巴巴 电子商务公司阿里巴巴通过大数据技术获取企业交易数据,自动分析和预测是否增加对企业的贷款,整个过程没有人工介入,全部为自动化处理. 到目前为止,阿里巴 ...

  8. 深度学习在点云分类中的研究综述————文献总结

    根据知网的一篇文章写的总结,详见我的资源:深度学习在点云分类中的研究综述_王文曦.pdf 这篇文章详细介绍了点云语义分割的发展概况. 正文开始 点云的语义分割的发展概况,先上图: 基于深度学习的分类方 ...

  9. 【神经网络与深度学习】1.线性分类与感知机

    线性分类与感知机 线性分类 线性回归 线性二分类 多分类回归 多层感知机 神经元模型 感知机模型 作为机器学习的一类,深度学习通常基于神经网络模型逐级表示越来越抽象的概念或模式. 这里从线性回归和so ...

  10. 神经网络与深度学习笔记汇总二

    神经网络与深度学习笔记汇总二 正交化(方便调整参数) 迭代 单实数评估指标(判断几种手段/方法哪个更好) 指标选取 训练集.开发集.测试集作用与用途 评估指标 判断算法是好是坏 迁移学习 总结 往期回 ...

最新文章

  1. c++语言中,vector容器与list容器的区别和联系?_百度知道
  2. VS2015静态编译libcurl(C++ curl封装类)
  3. Django model、view拆分,添加service
  4. 树莓派利用Django搭建聊天网页服务器 —— 准备篇
  5. crontab 每5分钟_Crontab安装步骤和命令使用详细解说
  6. T-1-java语言基础
  7. android 列表图片优化经历
  8. Android中通过反射和getResource()得到id的方式去改变View的显示效果
  9. 利用opencv作透明重叠人群密度热度图
  10. Android插件库
  11. Apache Kylin在美团数十亿数据OLAP场景下的实践
  12. matlab常用数学函数实验,实验二-MATLAB的数学运算基础.ppt
  13. android 微信 语音转文字,微信语音转文字功能
  14. 日志易——中国版的splunk
  15. CSJ加人|cs如何加人|cs加人快捷键
  16. 浏览器打开时总是hao123.com的网站解决办法
  17. excel countif_如何在Excel中使用COUNTIF,COUNTIFS和SUMPRODUCT工作表功能
  18. 《连载 | 物联网框架ServerSuperIO教程》- 15.数据持久化接口的使用。附:3.2发布与版本更新说明。...
  19. 2022年3月盗取微软源代码的 APT组织 lapsus$完整资料汇总
  20. Udacity Deep Learning课程作业(五)

热门文章

  1. 怎么把CAD高版本转低版本?CAD版本转换方法分享
  2. 深入浅出 —— 操作系统知识点大复习 !
  3. 今日指数项目之项目介绍和数据采集【四】
  4. 基于JavaEE的网上企业办公自动化管理系统_JSP网站设计_SqlServer数据库设计目
  5. NetSuite SuiteQlet 功能包
  6. 【数据库查询--电影制片系列】--所有涉及到的表
  7. Java 【手写webserver】学习笔记
  8. 电壁挂炉一年的费用到底有多少
  9. 磁铁会损坏或擦拭笔记本电脑的硬盘吗?
  10. 遥遥领先!华为Mate 60 供应商有哪些