• 一维卷积英语电影评论情感分类项目


    1、一维卷积英语电影评论情感分类项目

    1.1 项目数据和模型说明

      使用一 维卷积对英语文本进行情感分类。我们要使用的数据集是 IMDB 电影评论数据集,数 据分为正面评论和负面评论。这个数据集直接从 Tensorflow 中获得:

    from tensorflow.keras.datasets import imdb
    
    • 1

      我们不需要进行任何数据处理就可以直接载入数据,数据的训练集有 25000 条评论数 据,正面评论 12500 条,负面评论 12500 条。测试集数据也是 25000 条数据,正负样本各占 50%。并且句子已经做好了分词,而且还把每个词都变成了编号(词出现的频率越高,编号越小)。例如,测试集第 0 行的数据如图所示。

    image-20220719230410257

      下面我们再说一下一维卷积在文本分类中的应用,如下图所示。

    image-20220719230441640

      我们可以用一个简单的方式来理解一维卷积和二维卷积的区别,二维卷积它的 kernel_size 也是两维的,并且可以沿两个方向进行移动(比如水平方向和竖直方向),二维卷积计算时要求输入数据必须是 4 维的(数据数量,图片高度,图片宽度,通道数 channels)一维卷积它的 kernel_size 是一维的,并且只能沿一个方向进行移动,一维卷积计算时要求输入数据必须时 3 维的(数据数量,序列长度,通道数 channels)。在文本分 类中,使用一维卷积和二维卷积都可以。

      如果是使用一维卷积相当于是对一个序列进行特征提取如上图中假设我们使用一维卷积,词汇数相当于是序列长度,每个词的词向量长度相当于是通道数 channels。我们把 kernel_size 设置为 3,也就是每次卷积会对图中 3 行数据进行卷积计算(图中的列数其实就是通道数 channels),步长一般设置为 1 就可以,每次走一步。卷积计算后得到特征图,接下来再进行 max-pooling 计算,最后再进行全连接得到分类结果。

    1.2 一维卷积英语电影评论情感分类程序

    from tensorflow.keras.preprocessing import sequence
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Dense,Dropout
    from tensorflow.keras.layers import Embedding
    from tensorflow.keras.layers import Conv1D,GlobalMaxPooling1D
    from tensorflow.keras.datasets import imdb
    from plot_model import plot_model
    from matplotlib import pyplot as plt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    # 最大词汇数量
    max_words = 10000
    # 最长句子设置为400
    # 这里句子长度值的是句子词汇数量,句子有100个词则长度为100
    maxlen = 400
    # 批次大小
    batch_size = 32
    # 词向量长度
    embedding_dims = 128
    # 训练周期
    epochs = 3
    # 滤波器数量
    filters = 64
    # 卷积核大小
    kernel_size = 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    # 载入imdb评论数据集,设置最大词汇数,只保留出现频率最高的前max_words个词
    # 出现频率越高,编号越小。词的编号从4开始,也就是频率最大的词编号为4。
    # 编号0表示padding,1表示句子的开始(每个句子第一个编号都是1),2表示OOV,3表示预留(所有的数据中都没有3)
    # Out-of-vocabulary,简称OOV,表示不在字典中的词
    # 数据的标签为0和1。0表示负面情感,1表示正面情感。
    (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_words)
    print('x_train.shape:',x_train.shape,'y_train.shape:',y_train.shape)
    print('x_test.shape:',x_test.shape,'y_test.shape:',y_test.shape)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220719230649903

    # 查看测试集第0个句子
    print(x_test[0])
    
    • 1
    • 2

    image-20220719230712888

    # 获得imdb数据集的字典,字典的键是英语词汇,值是编号
    # 注意这个字典的词汇编号跟数据集中的词汇编号是不对应的
    # 数据集中的编号减三才能得到这个字典的编号,举个例子:
    # 比如在x_train中'a'的编号为6,在word2id中'a'的编号为3
    word2id = imdb.get_word_index()
    
    # 把字典的键值对反过来:键是编号,值是英语词汇
    # 编号数值范围:0-88587
    # value+3把字典中词汇的编号跟x_train和x_test数据中的编号对应起来
    id2word = dict([(value+3, key) for (key, value) in word2id.items()])
    # 设置预留字符
    id2word[3] = '[RESERVE]'
    # 设置Out-of-vocabulary字符
    id2word[2] = '[OOV]'
    # 设置起始字符
    id2word[1] = '[START]'
    # 设置填充字符
    id2word[0] = '[PAD]'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    # 在词典中查询得到原始英语句子,如果编号不在字典用则用'?'替代
    decoded_review = ' '.join([id2word.get(i, '?') for i in x_test[0]])
    print(decoded_review)
    
    • 1
    • 2
    • 3

    image-20220719230737029

    # 序列填充,因为模型结构是固定的而句子的长度是不固定的,所以我们需要把句子变成相同的长度
    # 如果句子长度不足maxlen,则把句子填充到maxlen的长度,如果句子长度超过maxlen,则取句子前maxlen个词
    x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
    x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
    # 填充后所有句子都变成了400的长度
    print('x_train shape:', x_train.shape)
    print('x_test shape:', x_test.shape)
    print(x_test[0])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220719230803627

    # 构建模型
    model = Sequential()
    
    # Embedding是一个权值矩阵,包含所有词汇的词向量,Embedding的行数等于词汇数,列数等于词向量长度
    # Embedding的作用是获得每个词对应的词向量,这里的词向量是没有经过预训练的随机值,会跟随模型一起训练
    # max_words词汇数,embedding_dims词向量长度
    # 模型训练时数据输入为(batch, maxlen)
    model.add(Embedding(max_words,
                        embedding_dims))
    
    # 设置一个一维卷积
    model.add(Conv1D(filters,
                     kernel_size,
                     strides=1,
                     padding='same',
                     activation='relu'))
    
    # 卷积计算后得到的数据为(batch, maxlen, filters)
    # GlobalMaxPooling1D-全局最大池化计算每一张特征图的最大值
    # 池化后得到(batch, filters)
    model.add(GlobalMaxPooling1D())
    # 加上Dropout
    model.add(Dropout(0.5))
    # 最后2分类,设置2个神经元
    model.add(Dense(2,activation='softmax'))
    # 画图
    plot_model(model)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    # sparse_categorical_crossentropy和categorical_crossentropy都是交叉熵代价函数
    # categorical_crossentropy需要把标签变成独热编码one-hot
    # sparse_categorical_crossentropy不需要把标签变成独热编码one-hot(不是真的不需要,而且程序中会自动帮你做转换)
    # 所以这个程序中的标签没有转独热编码one-hot
    model.compile(loss='sparse_categorical_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])
    
    # 训练模型
    history=model.fit(x_train, y_train,
              batch_size=batch_size,
              epochs=epochs,
              validation_data=(x_test, y_test))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    image-20220719230916143

    # 显示训练集和验证集的acc和loss曲线
    acc = history.history['accuracy']
    val_acc = history.history['val_accuracy']
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    
    plt.subplot(1, 2, 1)
    plt.plot(acc, label='Training Accuracy')
    plt.plot(val_acc, label='Validation Accuracy')
    plt.title('Training and Validation Accuracy')
    plt.legend()
    
    plt.subplot(1, 2, 2)
    plt.plot(loss, label='Training Loss')
    plt.plot(val_loss, label='Validation Loss')
    plt.title('Training and Validation Loss')
    plt.legend()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

  • 相关阅读:
    React-组件-props 校验 类型 是否必填 默认值
    如何使用ffmpeg转换图片格式
    Vue表单修饰符:v-model.lazy、v-model.number、v-model.trim
    hive从入门到放弃(三)——DML数据操作
    B2B企业老板和市场人必看:如何做好数字化营销
    LeetCode Java刷题笔记—105. 从前序与中序遍历序列构造二叉树
    83、【backtrader期货策略】一个国债期货的日线趋势跟踪策略
    【Jmeter】安装配置:Jmeter 下载 MySQL JDBC 驱动
    python读取pdf表格并合并为excel
    goJS-绘图-控制显示内容
  • 原文地址:https://blog.csdn.net/qq_43753724/article/details/125883065