基于GRU的 电影评论情感分析 - python 深度学习 情感分类 计算机竞赛

news2024/11/16 3:51:15

文章目录

  • 1 前言
    • 1.1 项目介绍
  • 2 情感分类介绍
  • 3 数据集
  • 4 实现
    • 4.1 数据预处理
    • 4.2 构建网络
    • 4.3 训练模型
    • 4.4 模型评估
    • 4.5 模型预测
  • 5 最后

1 前言

🔥 优质竞赛项目系列,今天要分享的是

基于GRU的 电影评论情感分析

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1.1 项目介绍

其实,很明显这个项目和微博谣言检测是一样的,也是个二分类的问题,因此,我们可以用到学长之前提到的各种方法,即:

朴素贝叶斯或者逻辑回归以及支持向量机都可以解决这个问题。

另外在深度学习中,我们可以用CNN-Text或者RNN以及LSTM等模型最好。

当然在构建网络中也相对简单,相对而言,LSTM就比较复杂了,为了让不同层次的同学们可以接受,学长就用了相对简单的GRU模型。

如果大家想了解LSTM。以后,学长会给大家详细介绍。

2 情感分类介绍

其实情感分析在自然语言处理中,情感分析一般指判断一段文本所表达的情绪状态,属于文本分类问题。一般而言:情绪类别:正面/负面。当然,这就是为什么本人在前面提到情感分析实际上也是二分类问题的原因。

3 数据集

学长本次使用的是非常典型的IMDB数据集。

该数据集包含来自互联网的50000条严重两极分化的评论,该数据被分为用于训练的25000条评论和用于测试的25000条评论,训练集和测试集都包含50%的正面评价和50%的负面评价。该数据集已经经过预处理:评论(单词序列)已经被转换为整数序列,其中每个整数代表字典中的某个单词。

查看其数据集的文件夹:这是train和test文件夹。

在这里插入图片描述

接下来就是以train文件夹介绍里面的内容
在这里插入图片描述

然后就是以neg文件夹介绍里面的内容,里面会有若干的text文件:
在这里插入图片描述

4 实现

4.1 数据预处理



    #导入必要的包
    import zipfile
    import os
    import io
    import random
    import json
    import matplotlib.pyplot as plt
    import numpy as np
    import paddle
    import paddle.fluid as fluid
    from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear, Embedding
    from paddle.fluid.dygraph.base import to_variable
    from paddle.fluid.dygraph import GRUUnit
    import paddle.dataset.imdb as imdb


    #加载字典
    def load_vocab():
        vocab = imdb.word_dict()
        return vocab
    #定义数据生成器
    class SentaProcessor(object):
        def __init__(self):
            self.vocab = load_vocab()
    
        def data_generator(self, batch_size, phase='train'):
            if phase == "train":
                return paddle.batch(paddle.reader.shuffle(imdb.train(self.vocab),25000), batch_size, drop_last=True)
            elif phase == "eval":
                return paddle.batch(imdb.test(self.vocab), batch_size,drop_last=True)
            else:
                raise ValueError(
                    "Unknown phase, which should be in ['train', 'eval']")



步骤

  1. 首先导入必要的第三方库

  2. 接下来就是数据预处理,需要注意的是:数据是以数据标签的方式表示一个句子,因此,每个句子都是以一串整数来表示的,每个数字都是对应一个单词。当然,数据集就会有一个数据集字典,这个字典是训练数据中出现单词对应的数字标签。

4.2 构建网络

这次的GRU模型分为以下的几个步骤

  • 定义网络
  • 定义损失函数
  • 定义优化算法

具体实现如下


#定义动态GRU
class DynamicGRU(fluid.dygraph.Layer):
def init(self,
size,
param_attr=None,
bias_attr=None,
is_reverse=False,
gate_activation=‘sigmoid’,
candidate_activation=‘relu’,
h_0=None,
origin_mode=False,
):
super(DynamicGRU, self).init()
self.gru_unit = GRUUnit(
size * 3,
param_attr=param_attr,
bias_attr=bias_attr,
activation=candidate_activation,
gate_activation=gate_activation,
origin_mode=origin_mode)
self.size = size
self.h_0 = h_0
self.is_reverse = is_reverse
def forward(self, inputs):
hidden = self.h_0
res = []
for i in range(inputs.shape[1]):
if self.is_reverse:
i = inputs.shape[1] - 1 - i
input_ = inputs[ :, i:i+1, :]
input_ = fluid.layers.reshape(input_, [-1, input_.shape[2]], inplace=False)
hidden, reset, gate = self.gru_unit(input_, hidden)
hidden_ = fluid.layers.reshape(hidden, [-1, 1, hidden.shape[1]], inplace=False)
res.append(hidden_)
if self.is_reverse:
res = res[::-1]
res = fluid.layers.concat(res, axis=1)
return res

class GRU(fluid.dygraph.Layer):
    def __init__(self):
        super(GRU, self).__init__()
        self.dict_dim = train_parameters["vocab_size"]
        self.emb_dim = 128
        self.hid_dim = 128
        self.fc_hid_dim = 96
        self.class_dim = 2
        self.batch_size = train_parameters["batch_size"]
        self.seq_len = train_parameters["padding_size"]
        self.embedding = Embedding(
            size=[self.dict_dim + 1, self.emb_dim],
            dtype='float32',
            param_attr=fluid.ParamAttr(learning_rate=30),
            is_sparse=False)
        h_0 = np.zeros((self.batch_size, self.hid_dim), dtype="float32")
        h_0 = to_variable(h_0)
        
        self._fc1 = Linear(input_dim=self.hid_dim, output_dim=self.hid_dim*3)
        self._fc2 = Linear(input_dim=self.hid_dim, output_dim=self.fc_hid_dim, act="relu")
        self._fc_prediction = Linear(input_dim=self.fc_hid_dim,
                                output_dim=self.class_dim,
                                act="softmax")
        self._gru = DynamicGRU(size=self.hid_dim, h_0=h_0)
        
    def forward(self, inputs, label=None):
        emb = self.embedding(inputs)
        o_np_mask =to_variable(inputs.numpy().reshape(-1,1) != self.dict_dim).astype('float32')
        mask_emb = fluid.layers.expand(
            to_variable(o_np_mask), [1, self.hid_dim])
        emb = emb * mask_emb
        emb = fluid.layers.reshape(emb, shape=[self.batch_size, -1, self.hid_dim])
        fc_1 = self._fc1(emb)
        gru_hidden = self._gru(fc_1)
        gru_hidden = fluid.layers.reduce_max(gru_hidden, dim=1)
        tanh_1 = fluid.layers.tanh(gru_hidden)
        fc_2 = self._fc2(tanh_1)
        prediction = self._fc_prediction(fc_2)
        
        if label is not None:
            acc = fluid.layers.accuracy(prediction, label=label)
            return prediction, acc
        else:
            return prediction

4.3 训练模型


def train():
with fluid.dygraph.guard(place = fluid.CUDAPlace(0)): # # 因为要进行很大规模的训练,因此我们用的是GPU,如果没有安装GPU的可以使用下面一句,把这句代码注释掉即可
# with fluid.dygraph.guard(place = fluid.CPUPlace()):

        processor = SentaProcessor()
        train_data_generator = processor.data_generator(batch_size=train_parameters["batch_size"], phase='train')

        model = GRU()
        sgd_optimizer = fluid.optimizer.Adagrad(learning_rate=train_parameters["lr"],parameter_list=model.parameters())

        steps = 0
        Iters, total_loss, total_acc = [], [], []
        for eop in range(train_parameters["epoch"]):
            for batch_id, data in enumerate(train_data_generator()):

                steps += 1
                doc = to_variable(
                    np.array([
                        np.pad(x[0][0:train_parameters["padding_size"]], 
                              (0, train_parameters["padding_size"] - len(x[0][0:train_parameters["padding_size"]])),
                               'constant',
                              constant_values=(train_parameters["vocab_size"]))
                        for x in data
                    ]).astype('int64').reshape(-1))
                label = to_variable(
                    np.array([x[1] for x in data]).astype('int64').reshape(
                        train_parameters["batch_size"], 1))
        
                model.train()
                prediction, acc = model(doc, label)
                loss = fluid.layers.cross_entropy(prediction, label)
                avg_loss = fluid.layers.mean(loss)
                avg_loss.backward()
                sgd_optimizer.minimize(avg_loss)
                model.clear_gradients()
 
                if steps % train_parameters["skip_steps"] == 0:
                    Iters.append(steps)
                    total_loss.append(avg_loss.numpy()[0])
                    total_acc.append(acc.numpy()[0])
                    print("step: %d, ave loss: %f, ave acc: %f" %
                         (steps,avg_loss.numpy(),acc.numpy()))

                if steps % train_parameters["save_steps"] == 0:
                    save_path = train_parameters["checkpoints"]+"/"+"save_dir_" + str(steps)
                    print('save model to: ' + save_path)
                    fluid.dygraph.save_dygraph(model.state_dict(),
                                                   save_path)
    draw_train_process(Iters, total_loss, total_acc)

在这里插入图片描述
在这里插入图片描述

4.4 模型评估

在这里插入图片描述

结果还可以,这里说明的是,刚开始的模型训练评估不可能这么好,很明显是过拟合的问题,这就需要我们调整我们的epoch、batchsize、激活函数的选择以及优化器、学习率等各种参数,通过不断的调试、训练最好可以得到不错的结果,但是,如果还要更好的模型效果,其实可以将GRU模型换为更为合适的RNN中的LSTM以及bi-
LSTM模型会好很多。

4.5 模型预测


train_parameters[“batch_size”] = 1

with fluid.dygraph.guard(place = fluid.CUDAPlace(0)):

    sentences = 'this is a great movie'
    data = load_data(sentences)
    print(sentences)
    print(data)
    data_np = np.array(data)
    data_np = np.array(np.pad(data_np,(0,150-len(data_np)),"constant",constant_values =train_parameters["vocab_size"])).astype('int64').reshape(-1)
    infer_np_doc = to_variable(data_np)

    model_infer = GRU()
    model, _ = fluid.load_dygraph("data/save_dir_750.pdparams")
    model_infer.load_dict(model)
    model_infer.eval()
    result = model_infer(infer_np_doc)
    print('预测结果为:正面概率为:%0.5f,负面概率为:%0.5f' % (result.numpy()[0][0],result.numpy()[0][1]))

在这里插入图片描述

训练的结果还是挺满意的,到此为止,我们的本次项目实验到此结束。

5 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1116352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hadoop3教程(二十六):(生产调优篇)NameNode核心参数配置与回收站的启用

文章目录 (143)NameNode内存配置(144)NN心跳并发配置(145)开启回收站参考文献 (143)NameNode内存配置 每个文件块(的元数据等)在内存中大概 占用150byte&…

Android 12.0 Launcher3定制化功能之抽屉式(双层)app列表排序功能实现

1.概述 在12.0的系统开发中,在定制Launcher3的开发中,对于抽屉式即双层桌面的workspace的app列表排序的功能,也是常有的需求,把常用的app图标放在前面,其他的可以放在列表后面做个整体的排序,这就需要了解app列表排序的流程,然后根据需求来实现功能 如图: 2.Launcher3 …

并发编程-延时队列DelayQueue

数据结构学习网站: Data Structure Visualization 思维导图 DelayQueue (延时队列) DelayQueue 是一个支持延时获取元素的阻塞队列 , 内部采用优先队列 PriorityQueue 存储元素,同时元素必须实现 Delayed 接口&#x…

Elasticsearch 8.X 分词插件版本更新不及时解决方案

1、关于 Elasticsearch 8.X IK 分词插件相关问题 球友在 ElasticSearch 版本选型问题中提及:如果要使用ik插件,是不是就使用目前最新的IK对应elasticsearch的版本“8.8.2”? https://github.com/medcl/elasticsearch-analysis-ik/releases/ta…

C++入门3+类和对象上

C入门3类和对象上 一.内联函数1.宏函数的缺点2.宏函数的优点3.内联函数的语法4.内联函数的优缺点5.内联函数的使用条件6.内联函数的展开7.内联函数的一大注意事项1.内联函数声明跟定义分离2.内联函数声明跟定义分离的"奇怪"现象 二.C11对于C语法的补充1.auto关键字1.…

【Nginx34】Nginx学习:安全链接、范围分片以及请求分流模块

Nginx学习:安全链接、范围分片以及请求分流模块 又迎来新的模块了,今天的内容不多,但我们都进行了详细的测试,所以可能看起来会多一点哦。这三个模块之前也从来都没用过,但是通过学习之后发现,貌似还都挺有…

python模块之feapder 爬虫框架

一、简介 官网:https://feapder.com/#/ feapder是一款上手简单,功能强大的Python爬虫框架,内置AirSpider、Spider、TaskSpider、BatchSpider四种爬虫解决不同场景的需求,但像任何工具一样,它也有其优点和缺点。以下是…

如何利用考培系统进行个性化学习和评估

考培系统作为一种现代化的学习和评估工具,可以为学生提供个性化的学习和评估服务。它利用先进的技术和算法,根据学生的学习情况和需求,为其量身定制学习计划,并提供相应的评估反馈。 1. 个性化学习 考培系统通过分析学生的学习情…

QML(25)——文本输入框组件的区别(TextField TextInput TextArea TextEdit)

目录 效果展示适用场景文本组件TextLabelText和Label的区别 单行文本输入框TextFieldTextInputTextField 和 TextInput的区别 多行文本输入框TextAreaTextArea 和 TextEdit 的区别 效果展示 适用场景 场景组件属性短文本Text长文本 末尾省略Textelide: Text.ElideRight文本设置…

通用FIFO设计深度8宽度64,verilog仿真,源码和视频

名称:通用FIFO设计深度8宽度64,verilog仿真 软件:Quartus 语言:verilog 本代码为FIFO通用代码,其他深度和位宽可简单修改以下参数得到 reg [63:0] ram [7:0];//RAM。深度8,宽度64 代码功能&#xff1a…

ArmSoM-RK3588编解码之mpp解码demo解析:mpi_dec_test

1. 简介 [RK3588从入门到精通] 专栏总目录 mpi_dec_test 是rockchip官方解码 demo 本篇文章进行mpi_dec_test 的代码解析,解码流程解析 2. 环境介绍 硬件环境: ArmSoM-W3 RK3588开发板 软件版本: OS:ArmSoM-W3 Debian11 3.…

低代码助力软件开发

低代码开发工具正在日益变得强大,它正不断弥合着前后端开发之间的差距。对于后端来说,基于低代码平台开发应用时,完全不用担心前端的打包、部署等问题,也不用学习各种框架(Vue、React、Angular等等)&#x…

GO 语言如何用好变长参数?

函数重载 对于函数重载相信编码过的 xdm 肯定不会陌生,函数重载就是在同一个作用域内定义多个具有相同名称但参数列表不同的函数 此处的参数列表不同,可以是参数的类型不同,参数的个数不同 那么我们一起分别来看看 C 语言,C 语…

物联网专业前景怎么样?

物联网专业前景怎么样? 物联网专业在当今技术发展迅速的背景下具有广阔的前景。以下是物联网专业的一些优势和就业前景: 1.市场需求大:物联网作为人工智能、云计算和大数据等技术的结合,已经成为许多行业的核心需求。各行各业都需…

【智能指针】

目录: 前言智能指针(一)智能指针初始了解内存泄漏1. 内存泄漏分类2. 如何检测内存泄漏3. 如何避免内存泄漏使用智能指针之前,异常安全的处理 (二)智能指针实现既原理智能指针RAII使用智能指针之后&#xff…

060:mapboxGL点击某处,通过flyTo,以动画的形式聚焦到此点

第060个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中点击某处,通过flyto,以动画的形式聚焦到此点。这里用到了flyTo的方法,里面可以设置bearing,zoom,pitch等众多的属性内容。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示…

数据结构与算法-(10)---列表(List)

🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…

Linux 最大可以打开多少文件描述符?

Linux 最大可以打开多少文件描述符? 在日常开发中,对文件的操作可谓是再寻常不过的意见事情。那么你是否有这样一个疑问, 我最多可以打开多少个文件呢? 在Linux系统中,当某个程序打开文件时,内核返回相应…

SQL查询命令互转vba格式

最近搞个Excel的vba查询数据库,发现vba有代码行长度限制需要转换下就弄了这个,布局和功能暂且这样了,哪位大佬如果有兴趣的可以再美化下! 这次更新了SQL命令互转VBA格式, SQL原始格式要分行的不能一坨贴进去&#xff0…

Java日志系统之JUL

目录 JUL介绍 JUL的使用 日志级别 指定日志输出地址 Logger对象的父子关系 Logger读取配置文件 JUL介绍 Java自带的框架,使用简单,无需引入依赖 JUL的使用 public class JULTest {Testpublic void testLogger() throws Exception{//获取日志记录…