PyTorch 深度学习实战
方远
LINE China 数据科学家
10381 人已学习
新⼈⾸单¥59
登录后,你可以任选3讲全文学习
课程目录
已完结/共 32 讲
开篇词 (1讲)
PyTorch 深度学习实战
15
15
1.0x
00:00/00:00
登录|注册

23 | 情感分析:如何使用LSTM进行情感分析?

你好,我是方远。
欢迎来跟我一起学习情感分析,今天我们要讲的就是机器学习里的文本情感分析。文本情感分析又叫做观点提取、主题分析、倾向性分析等。光说概念,你可能会觉得有些抽象,我们一起来看一个生活中的应用,你一看就能明白了。
比方说我们在购物网站上选购一款商品时,首先会翻阅一下商品评价,看看是否有中差评。这些评论信息表达了人们的各种情感色彩和情感倾向性,如喜、怒、哀、乐和批评、赞扬等。像这样根据评价文本,由计算机自动区分评价属于好评、中评或者说差评,背后用到的技术就是情感分析。
如果你进一步观察,还会发现,在好评差评的上方还有一些标签,比如“声音大小合适”、“连接速度快”、“售后态度很好”等。这些标签其实也是计算机根据文本,自动提取的主题或者观点。
情感分析的快速发展得益于社交媒体的兴起,自 2000 年初以来,情感分析已经成长为自然语言处理(NLP)中最活跃的研究领域之一,它也被广泛应用在个性化推荐、商业决策、舆情监控等方面。
今天这节课,我们将完成一个情感分析项目,一起来对影评文本做分析。

数据准备

现在我们手中有一批影评数据(IMDB 数据集),影评被分为两类:正面评价与负面评价。我们需要训练一个情感分析模型,对影评文本进行分类。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何使用LSTM进行情感分析。作者首先解释了情感分析的概念和应用场景,然后详细介绍了使用Torchtext工具包读取IMDB数据集,并利用分词器和词汇表对文本进行处理。接着,作者讲解了数据处理pipelines的创建和训练数据的生成,以及如何处理变长数据。随后,文章详细介绍了LSTM网络的构建和训练过程,包括模型定义、损失函数与优化方法的设置,以及训练过程中的loss计算和模型评估。最后,文章提出了一个练习任务,要求读者编写一个函数实现输入一句话,输出情绪类别与概率的功能。整篇文章以教程的形式呈现,适合对情感分析和自然语言处理感兴趣的读者阅读学习。文章内容详实,涵盖了情感分析的技术细节和实现步骤,对读者进行了全面的指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《PyTorch 深度学习实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(21)

  • 最新
  • 精选
  • 李雄
    置顶
    如果是使用torchtext==0.8.1以下的版本建议看官网文档: https://pytorch.org/text/0.8.1/datasets.html
    2021-12-31
    1
  • 林于翔
    LSTM模型定义中: if self.lstm.bidirectional: hidden = self.dropout(torch.cat([hidden[-1], hidden[-2]], dim=-1)) 这里不太理解,最后连接的不是最后一层hidden的第一个时间步和最后一个时间步嘛?另外dim为什么会是-1。

    作者回复: Hello,感谢留言。 我们首先看一下torch.nn.LSTM这个函数的输入与输出,详见文档: https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html?highlight=nn%20lstm#torch.nn.LSTM torch.nn.LSTM的输入参数: input_size: 表示的是输入的矩阵特征数 hidden_size: 表示的是输出矩阵特征数 num_layers 表示堆叠几层的LSTM,默认是1 bidirectional: 默认是false,代表不用双向LSTM,双向LSTM,也就是序列从左往右算一次,从右往左又算一次,这样就可以两倍的输出 batch_first: True 或者 False,因为nn.lstm()接受的数据输入是(序列长度,batch,输入维数),这和我们cnn输入的方式不太一致,所以使用batch_first,我们可以将输入变成(batch,序列长度,输入维数) torch.nn.LSTM的输出格式为:output,(h_n,c_n) 其中: output的shape=(seq_length,batch_size,num_directions*hidden_size),它包含的是LSTM的最后一时间步的输出特征(h_t),t是batch_size中每个句子的长度。 h_n.shape==(num_directions * num_layers,batch,hidden_size) c_n.shape==h_n.shape h_n包含的是句子的最后一个单词(也就是最后一个时间步)的隐藏状态,c_n包含的是句子的最后一个单词的细胞状态,所以它们都与句子的长度seq_length无关。 output[-1]与h_n是相等的,因为output[-1]包含的正是batch_size个句子中每一个句子的最后一个单词的隐藏状态。 if self.lstm.bidirectional: hidden = self.dropout(torch.cat([hidden[-1], hidden[-2]], dim=-1)) 这里面,hidden是torch.nn.LSTM的第二个输出h_n,hidden的shape是(2 * 2, batch, 300)。 因此,双向LSTM时,hidden[-1]表示从最后一个堆叠的从左到右的LSTM的的最后一个时间步向量,hidden[-2]表示最后一个堆叠的从右到左的LSTM最后一个时间步向量。将这两个向量拼接在一起,得到最后的hidden层。 而dim=-1表示torch.cat的拼接方式,拼接300(embedding_dim)那个维度,也就是将两个300维度的向量拼接成一个600维度的向量。

    2021-12-17
    1
  • hallo128
    torchtext可以支持中文分词吗

    作者回复: 你好,感谢你的留言。 torchtext支持的分词器有:spacy, moses, toktok, revtok, subword。 spacy库是可以支持中文分词的。 可以尝试以下代码: import spacy spacy = spacy.load("zh_core_web_sm") tokenizer = get_tokenizer(spacy)

    2022-06-30
  • Geek_a82ba7
    import torchtext train_iter = torchtext.datasets.IMDB(root='./data', split='train') next(train_iter) 'MapperIterDataPipe' object is not an iterator 为什么说这个不是一个迭代器,查了很多资料都没有解决,老师能回答一下吗? c

    作者回复: 您好,感谢你的留言。 看看是不是torchtext版本更新了? 我用的是0.10.1

    2022-06-21
    4
  • Sarai青霞
    方老师,我试了代码,输出显示: "\n输出:['here', 'is', 'the', 'an', 'example', '!']\n" 是断行出现问题了吗? 谢谢!

    作者回复: 你好,感谢留言。 python的多行注释是用三对单引号。 ''' 输出:['here', 'is', 'the', 'an', 'example', '!'] ''' 这部分内容是代码中的注释,为了告诉你上述代码的运行结果是什么。 有的IDE运行时会输出多行注释,只需把注释删除即可,并不是断行出现问题。

    2022-06-01
  • Ringcoo
    老师好,请问 packed_output, (hidden, cell) = self.lstm(packed_embedded) output, output_length = torch.nn.utils.rnn.pad_packed_sequence(packed_output) 为什么从lstm层出来以后 会有(hidden, cell) ,我不太理解,以及为什么lstm层出来以后还有在进RNN层,底下的流程图上明明是lstm层出来以后进入了fc全连接层。麻烦您讲解一下

    作者回复: hello,Ringcoo,你好。感谢你的留言。 当我们训练LSTM时,因为文本句子长短不一,如果想要进行批次化训练,就需要选择一个合适的长度来进行截断和填充。 torch.nn.utils.rnn.pad_packed_sequence()并不是一个rnn层,这个函数的目的是将LSTM返回的结果进行统一填充,得到长度相同的Tensor对象。 hidden和cell是LSTM的结构中的一部分。 LSTM神经元在时间维度上向后传递了两份信息: (1)cell state; (2)hidden state。 hidden state是cell state经过一个神经元和一道“输出门”后得到的,因此hidden state里包含的记忆,实际上是cell state衰减之后的内容。 另外,cell state在一个衰减较少的通道里沿时间轴传递,对时间跨度较大的信息的保持能力比hidden state要强很多。 因此,实际上hidden state里存储的,主要是“近期记忆”;cell state里存储的,主要是“远期记忆”。 cell state的存在,使得LSTM得以对长依赖进行很好地刻画。

    2022-05-01
  • 赵心睿
    请问使用的torchtext是哪个版本的呢?

    作者回复: 你好,赵心睿,感谢留言。使用的是0.10.1。

    2022-03-14
  • 快乐小夜曲
    packed_embedded = torch.nn.utils.rnn.pack_padded_sequence(embedded, length.to('cpu'), batch_first=True, enforce_sorted=False) 这里length必须转为成cpu,否则会报错。

    作者回复: 你好,快乐小夜曲,感谢你的留言。 在train函数中,已经对length进行了转换:length = length.to(device) length是从外部传入的,所以这里无需显示对length再进行转换了。

    2022-01-02
  • 李雄
    请问这是那个版本的torchtext

    作者回复: hello,我用的是torchtext 0.10.1。

    2021-12-31
  • 吴十一
    def predict_sentiment(text, model, tokenizer, vocab, device): max_length = 256 pad = text_pipeline('<pad>') processed_text = text_pipeline(text)[:max_length] ids, length = [],[] ids.append((processed_text+pad*max_length)[:max_length]) length.append(len(processed_text)) ids_t,length_t = torch.tensor(ids, dtype = torch.int64), torch.tensor(length, dtype = torch.int64) print(ids_t,length_t) ids_t.to(device) length_t.to(device) pred = model(ids_t,length_t) return pred vocab_size = len(vocab) embedding_dim = 300 hidden_dim = 300 output_dim = 2 n_layers = 2 bidirectional = True dropout_rate = 0.5 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model = LSTM(vocab_size, embedding_dim, hidden_dim, output_dim, n_layers, bidirectional, dropout_rate) model = model.to(device) model.load_state_dict(torch.load("./lstm.pt")) model.eval() text = "This film is terrible!" pred = predict_sentiment(text, model, tokenizer, vocab, device) ''' 输出:('neg', 0.8874172568321228) ''' tips:一定要安装torchtext 稍微新点的版本,0.6.0 IDMB数据set跑报错,会一直要求用tensorflow v1 版本兼容
    2022-06-12
    1
收起评论
显示
设置
留言
21
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部