好还是坏:人工智能二分类问题

上一篇文章我们介绍了深度学习的 Hello World,代码写起来相比其他语言的 Hello World 有点多,且其背后的很多原理你可能还没有完全弄懂,但从宏观上来看,整体的思想是很好理解的。接下包括本篇在内的三篇文章,我们来用深度学习解决三个实际问题,也是非常经典的三个问题,分别是:

  1. 二分类问题(电影评论的好坏偏向性判断)
  2. 多分类问题(将新闻按照主题分类)
  3. 回归问题(根据房地产数据估算房地产价格)

我们解决这三个问题用到的训练模型为:

今天是第一篇,我们关注他们其中比较简单的二分类问题,代码在最后。

实际背景是 IMDB(互联网电影资料库,你可以理解为国外的豆瓣)有大量的关于电影的评论,但是由于数据量的问题,很难去人工手动判断一条评定是对电影的夸奖还是批评,这需要借助人工智能的帮助,根据用户评论的内容去判断用户的评论是积极的还是消极的(为使问题简化,我们取的数据是倾向性很明显的数据),数据集来自 IMDB,Numpy 数据格式:每一个单词对应一个索引数字,这样每一条评论就可以对应一个索引数字的序列,组成一维数组,也是一个一维向量,这样的多个一维向量组成二维数组,就对应对条评论。

背景介绍完了,整个过程分为如下几步,同时思考几个问题:

  1. 由于每一条评论的长度不一样,每个一维向量长度不一致,这样的数据不好处理,因此需要将数据进行预处理,这里采用 one-hot 方法(one-hot 是一个常用的方法,后面会有专门的文章介绍),简单点来 one-hot 做的事情就是:假如一个数组是[1, 3, 5, 3],需要处理成 10 维数据就是[0, 1, 0, 1, 0, 1, 0, 0, 0, 0],对应数数组索引处的数字是 1,其他数字是 0,本实际问题中,评论处理后的数据是一个向量(25000,10000)。
  2. 针对这种 one-hot 处理过的数据(0-1 类型的训练数据集),用带有 relu 激活的以 Dense 为中间层的网络进行深度学习表现很好(为什么这个表现的好,为什么 Dense 第一个参数即隐藏层的个数是 16 都是很复杂的问题,后续深入研究,这里只下结论将数据投影到 16 维空间中且是两个中间层的网络可以满足要求),随后一层是将输出格式化为 0-1 概率判断的结果。
  3. 针对损失函数,因为最后输出的结果是这条评论倾向性的概率值,所以选择交叉熵作为损失函数(binary_crossentropy,二元交叉熵对于这种情况的判断训练效果表现较好)。
  4. 最后,因为我们的模型是要做拟合,是一个有反馈的网络,从上图中可以看出来,因此这里选择部分数据用于提供反馈数据(反馈的意思是说先训练出一个模型,然后用另外一些数据进行测试,计算偏差,将偏差结果反馈给网络,网络进行参数调整,再一轮训练)且提供反馈的数据不应该用于训练,因此从训练集中取出一部分数据用于提供反馈。这里选择训练数据集中前一万条数据用于提供反馈数据,后一万五千条数据用于训练。
  5. 最后一步是启动 fit 训练模型,fit 中 validation_data 参数是用于提供验证数据的。最后我们从训练的过程中,提取出每一轮循环得到的数据画图直观看看训练损失、验证损失、训练精度和验证精度的具体变化:

我们从图中可以看出,随着训练网络迭代的次数越来越多,训练精度越来越大,训练损失越来越小,这是我们期望的;但是同时差不多在第四次迭代后,验证损失越来越大,验证精度越来越小,这就跟期望不相符了,这不科学,那这是为什么?

这是因为由于迭代次数过多,出现了过拟合。

随着训练数据迭代次数过多,训练出的模型为了更好的拟合训练集的数据,导致一些参数设置的会过于绝对,出现了过拟合,这是我们在训练网络中经常会遇到的问题,因此我们认为在迭代四次是比较好的,类似于数学概念上的极值,更多更少的迭代次数都不够好,因此我们将 fit 中的迭代次数改为 4,再次训练网络。

最后在另外的两万五千条测试集上进行验证,效果还可以,基本满足要求,问题得到解答。更多的细节已经写在了下面代码相关注释内容部分了,有兴趣请自行阅读。

#!/usr/bin/env python3
?
import matplotlib.pyplot as plt
import numpy as np
from keras import layers
from keras import models
from keras.datasets import imdb
?
?
# IMDB 数据集,分类一个评论是正面的还是反面的
def comment():
    # num_words = 10000 代表取前一万高频词,加入低频词数据量会过大且作用较小,暂不考虑
    # 25000 条训练数据,25000 条测试数据
    (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
?
    # 训练集被处理成整数数列,每条数据表示一条评论中单词出现的次数(如 good 出现次数是 5 次)
    # [1, 14, 22, ... 19, 178, 32]
    # print(train_data[0])
?
    # 用 0 代表负面评论,1 代表正面评论
    # print(train_labels[0])
    # print(max([max(sequence) for sequence in train_data]))
?
    # 单词与索引对照表
    # word_index = imdb.get_word_index()
    # reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
    # decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
?
    # 将评论翻译成可读语言
    # this film was just brilliant casting location scenery story direction everyone's really suited the part they
    # print(decoded_review)
?
    # one-hot 方法预处理数据为向量
    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')
?
    # 构造网络
    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.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
    # model.compile(optimizer=optimizers.RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['accuracy'])
    # model.compile(optimizer=optimizers.RMSprop(lr=0.001), loss=losses.binary_crossentropy,
    #               metrics=[metrics.binary_accuracy])
?
    # 由于这里有反馈,因此需要有一定的数据进行数据进行验证,这里取前一万个数据进行验证操作
    x_val = x_train[:10000]
    partial_x_train = x_train[10000:]
    y_val = y_train[:10000]
    partial_y_train = y_train[10000:]
?
    # validation_data 用于传递验证数据
    history = model.fit(partial_x_train, partial_y_train, epochs=4, batch_size=512, validation_data=(x_val, y_val))
?
    # History 是训练过程中的所有数据
    history_dict = history.history
    print(history_dict.keys())
    history_dict = history.history
    loss_values = history_dict['loss']
    val_loss_values = history_dict['val_loss']
    epochs = range(1, len(loss_values) + 1)
?
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.plot(epochs, loss_values, 'bo', label='训练损失')
    plt.plot(epochs, val_loss_values, 'b', label='验证损失')
    plt.title('训练和验证损失')
    plt.xlabel('迭代')
    plt.ylabel('损失')
    plt.legend()
    plt.show()
?
    plt.clf()
    acc = history_dict['acc']
    val_acc = history_dict['val_acc']
    plt.plot(epochs, acc, 'bo', label='训练精度')
    plt.plot(epochs, val_acc, 'b', label='验证精度')
    plt.title('训练和验证精度')
    plt.xlabel('迭代')
    plt.ylabel('精度')
    plt.legend()
    plt.show()
?
    results = model.evaluate(x_test, y_test)
    # [0.3329389461231232, 0.8639600276947021]
    print(results)
    # [[0.1754326], [0.9990357], [0.855113]...]
    print(model.predict(x_test))
?
?
def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results
?
?
if __name__ == "__main__":
    comment()

原文地址:https://www.cnblogs.com/renyuzhuo/p/12222556.html

时间: 2024-10-23 18:31:45

好还是坏:人工智能二分类问题的相关文章

二分类算法评估指标

我们都知道机器学习要建模,但是对于模型性能的好坏我们并不知道是怎样的,很可能这个模型就是一个差的模型,对测试集不能很好的预测.那么如何知道这个模型是好是坏呢?必须有个评判的标准,需要用某个指标来衡量,这就是性能度量的意义.有了一个指标,就可以对比不同模型了,从而知道哪个模型更好,或者通过这个指标来调参优化选用的模型. 对于分类.回归.聚类等,分别有各自的评判标准.本篇主要介绍二分类算法(多分类可以扩展转化成二分类)的相关指标.评估一个二分类的分类器的性能指标有:准确率.查准率.查全率.F1值.A

matlab 实现感知机线性二分类算法(Perceptron)

感知机是简单的线性分类模型 ,是二分类模型.其间用到随机梯度下降方法进行权值更新.参考他人代码,用matlab实现总结下. 权值求解过程通过Perceptron.m函数完成 function W = Perceptron(X,y,learnRate,maxStep) % Perceptron.m % Perception Learning Algorithm(感知机) % X一行为一个样本,y的取值{-1,+1} % learnRate:学习率 % maxStep:最大迭代次数 [n,m] =

【机器学习具体解释】SVM解二分类,多分类,及后验概率输出

转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/51073885 CSDN?勿在浮沙筑高台 支持向量机(Support Vector Machine)以前在分类.回归问题中非常流行.支持向量机也称为最大间隔分类器,通过分离超平面把原始样本集划分成两部分. 首先考虑最简单的情况:线性可分支持向量机.即存在一个超平面能够把训练样本分开. 1.线性可分支持向量机 1.考虑一个线性二分类的问题:例如以下左图,在二维平面上有两种样本点x

【机器学习详解】SVM解二分类,多分类,及后验概率输出

转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/51073885 CSDN?勿在浮沙筑高台 支持向量机(Support Vector Machine)曾经在分类.回归问题中非常流行.支持向量机也称为最大间隔分类器,通过分离超平面把原始样本集划分成两部分. 首先考虑最简单的情况:线性可分支持向量机,即存在一个超平面可以把训练样本分开. 1.线性可分支持向量机 1.考虑一个线性二分类的问题:如下左图,在二维平面上有二种样本点x,目

Spark 多项式逻辑回归__二分类

package Spark_MLlib import org.apache.spark.ml.Pipeline import org.apache.spark.ml.classification.{LogisticRegression, LogisticRegressionModel} import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator import org.apache.spark.ml.feature

Spark 二项逻辑回归__二分类

package Spark_MLlib import org.apache.spark.ml.Pipeline import org.apache.spark.ml.classification.{BinaryLogisticRegressionSummary, LogisticRegression, LogisticRegressionModel} import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator i

tensorflow实现svm iris二分类——本质上在使用梯度下降法求解线性回归(loss是定制的而已)

iris二分类 # Linear Support Vector Machine: Soft Margin # ---------------------------------- # # This function shows how to use TensorFlow to # create a soft margin SVM # # We will use the iris data, specifically: # x1 = Sepal Length # x2 = Petal Width

基于TextCNN的情感二分类

0. Cause I just wanna wake up in the fleeting light 0.1 アイスクリームみた溶けそう.その瞳にみつめられたなら 新论文方向想好了,一个改进的TextCNN应用实例吧.数据集来源于学长之前打比赛时官方发的2G数据包,大概达到的效果就是通过用户短评去给某个景点的旅行指标进行打分.当然会有一个疑问,在我们现实的应用场景中不都是用户进行打分吗.但这里我要做的是对短评的深层语义进行挖掘,然后得出打分(无奈,为了写论文而写),其实确实没有什么意义,但是自

用二项逻辑斯蒂回归解决二分类问题

逻辑斯蒂回归: 逻辑斯蒂回归是统计学习中的经典分类方法,属于对数线性模型.logistic回归的因变量可以是二分类的, 也可以是多分类的 基本原理 logistic 分布 折X是连续的随机变量,X服从logistic分布是指X具有下列分布函数和密度函数: 其中为位置参数,为形状参数.与图像如下,其中分布函数是以为中心对阵,越小曲线变化越快 二项logistic回归模型: 二项logistic回归模型如下: 其中是输入,输出,W称为权值向量,b称为偏置, 是w和x的内积 参数估计 ? 假设: ?