情感分词新手实践

news/2024/10/7 14:23:08

Amazon Full Review 情感分析任务

input: Remark Text

output: Sentiment(\(\{-1, 0, 1\}\)) convert to \(\{0, 1, 2\}\) for calculating accuracy

Mark: 之前没有用 torch 做过 NLP,因此相当于一个 tutorial

数据准备工作

  1. 文本分词

NLP 需要将文本数据分词并转换为词汇表中的 id,这里使用transformers库中的BertTokenizer进行处理。

  1. 创建词汇表

需要完成的工作为

  • 创建词汇表 Vocabulary, 用于将文本转换为数字,由于词汇数量巨大,并且测试集可能出现未知词汇,因此设置一个阈值,设置两个标记符号,一个是未知词汇,一个是填充符号。
  • 同时在之后的 Embedding 中,词嵌入的输入是固定的,因此可以尝试将所有的句子 ids 的长度设置为相同的长度,不足的部分用填充符号填充。
  1. 创建 DataSet

主要是将文件读取入字典中,并在 getitem 方法中将文本数据转换为数字,同时将标签转换为数字。

模板如下


class MyDataset(Dataset):def __init__(self, path, tokenizer=None, max_length=512, device="gpu"):self.data = self.load_csv(path)self.tokenizer = tokenizerself.max_length = max_lengthprint(f"Loaded {len(self.data)} data from {path}")def load_csv(self, path):Data = {}index = 0try:with open(path, "rt", encoding="utf-8") as f:for line in f:items = line.strip().split(",")# convert labelsData[index] = {"subject": items[1],"review": items[2],"label": label,}index += 1else:continueexcept IOError as e:print(f"Error opening or reading the file: {path}. Error: {e}")return Datadef __len__(self):return len(self.data)def __getitem__(self, idx):# 在这里进行数据处理if idx < len(self.data) and idx >= 0:item = self.data[idx]# 编码处理encoded_review = self.tokenizer.encode_plus(item['review'],add_special_tokens=True,max_length=self.max_length,return_token_type_ids=False,padding="max_length",truncation=True,return_attention_mask=True,return_tensors='pt',)item["ids"] = encoded_review["input_ids"].squeeze()return item
  1. 划分数据集

可以直接在 dataset 中使用 subset 划分,但在创建 dataloader 时会存在索引问题,因此排列在预处理之前,出现问题的代码如下:

indices = list(range(len(train_data)))
np.random.shuffle(indices)
split = int(np.floor(0.8 * len(train_data)))
train_indices = indices[:split]
valid_indices = indices[split:]train_data = Subset(train_data, train_indices)
valid_data = Subset(train_data, valid_indices)
  1. 创建 DataLoader

需要注意的几个参数为batch_size, shuffle, drop_last, 其中shuffle表示是否打乱数据,drop_last表示是否丢弃最后一个 batch。

模型构建

1. Embedding + Pooling + Linear

  • Embedding 层将输入的词汇 id 转换为词嵌入
  • 然后使用 Pooling 层将词嵌入转换为句子向量
  • 最后使用 Linear 层将句子向量转换为输出
class NBoW(nn.Module):def __init__(self, vocab_size, embedding_dim, num_class):super(NBoW, self).__init__()self.embedding = nn.Embedding(vocab_size, embedding_dim)self.fc = nn.Linear(embedding_dim, num_class)def forward(self, ids):# ids = [batch size, seq len]embedded = self.embedding(ids)# embedded = [batch size, seq len, embedding dim]pooled = torch.mean(embedded, dim=1)# pooled = [batch size, embedding dim]pred = self.fc(pooled)# pred = [batch size, output dim], 输出由于loss是CE, 不需要softmaxreturn pred

img

2. LSTM

模型结构如下:

  • Embedding 层将输入的词汇 id 转换为词嵌入
  • LSTM 层将词嵌入转换为句子向量
  • Linear 层将句子向量转换为输出

同时防止过拟合,使用了 Dropout 层。以dropout_rate的概率,在训练时将输入的某些元素置为 0,以防止过拟合。

class LSTM(nn.Module):def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim,n_layers, bidirectional, dropout_rate) -> None:super().__init__()self.embedding = nn.Embedding(vocab_size, embedding_dim)self.lstm = nn.LSTM(embedding_dim,hidden_dim,n_layers,bidirectional=bidirectional,dropout=dropout_rate,batch_first=True,)self.fc = nn.Linear(hidden_dim * 2 if bidirectional else hidden_dim, output_dim)self.dropout = nn.Dropout(dropout_rate)def forward(self, ids):# ids = [batch size, seq len]# length = [batch size]embedded = self.dropout(self.embedding(ids))# embedded = [batch size, seq len, embedding dim]output, (hidden, cell) = self.lstm(embedded)# hidden = [n layers * n directions, batch size, hidden dim]# cell = [n layers * n directions, batch size, hidden dim]# output = [batch size, seq len, hidden dim * n directions]if self.lstm.bidirectional:hidden = self.dropout(torch.cat([hidden[-1], hidden[-2]], dim=-1))# hidden = [batch size, hidden dim * 2]else:hidden = self.dropout(hidden[-1])# hidden = [batch size, hidden dim]prediction = self.fc(hidden)# prediction = [batch size, output dim]return prediction

模型训练

使用(torch.argmax(predict, dim=1) == label).float().mean().item()计算准确率。

在第一种模型中,batch_size=512, epoch=3,在第二种模型中,batch_size=128, epoch=3

训练过程中使用,Adam优化器,CrossEntropyLoss损失函数。

然而由于没有考虑到数据平衡性问题,因此在训练过程中,准确率并不高,可以考虑使用WeightedRandomSampler解决数据不平衡问题。

Embedding LSTM
img img

模型接口

要注意的是最终结果的计算,由于预处理时已经将 label 转换为 idx,因此获得结果时只需套torch.argmax获取 idx 即可。

def predict_sentiment(text, model, tokenizer, device):model.eval()encoded_review = tokenizer.encode_plus(text,add_special_tokens=True,max_length=512,return_token_type_ids=False,padding="max_length",truncation=True,return_attention_mask=True,return_tensors='pt',)ids = encoded_review["input_ids"].to(device)prediction = model(ids)return torch.argmax(prediction).item()

参考

  1. 快速入门 Transformer

  2. Pytorch Sentiment Analysis

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

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

相关文章

生活常见物理层接口(除去网线)

生活物理层接口 1.USB接口 秒懂所有USB接口类型,USB接口大全;Type-A、Type-B、Type-C、miniUSB、microUSB区分-知乎追风少年上图漏掉了苹果的lightning接口,又叫闪电接口USB-A全称USB Type-A口,俗称USB接口是最常见的接口,如下图左侧接口内部舌头非蓝色的是USB2.0,右侧蓝…

测试分类

单元测试:针对程序的最小单元来进行正确性检验的测试工作,包括类、方法等。(严格来说,单元测试只针对【功能点】进行测试,不包括对业务流程正确性的测试) 功能测试/接口测试:测试接口的功能是否正确。【接口,输入输出】 端到端测试:模拟真实用户的请求(客户端--服务端…

Linux学习第二天

今天学习linuxC编程。首先要熟悉linux下编写c程序的过程。 编写程序Hello World! 首先创建存放程序的文件夹,如下图所示:接下来在创建一个文件夹来保存这节要编写的代码。指令:mkdir 3.1接下来我们要设置VIM编辑器的一些配置,比如设置tab的字符数为4、以及设置VIM编辑器的行…

《线性代数的本质》笔记10

10-特征值与特征向量特征向量几何含义:在一次特定的线性变换中没有脱离原本张成空间的向量。特征值即为这个特征向量在这次变换中缩放的比例。 推导: $$ A\vec{v}=\lambda\vec{v} $$ $$(A-\lambda\textit{I})\vec{v}=\vec{0}$$ $$det(A-\lambda\textit{I})=0$$ 但并非所有线…

目录遍历-基于Pikachu的学习

目录遍历 原理 目录浏览漏洞是由于网站存在配置缺陷,存在目录可浏览漏洞,这会导致网站很多隐私文件与目录泄露,比如数据库备份文件、配置文件等,攻击者利用该信息可以更容易得到网站权限,导致网站被黑。 Pikachu 打开题目就是两个超链接,我随便点了一个发现url发现变化,有…

Testing Egineer note:2024_5_5-day05-part01

版本控制器之svn介绍 1.svn介绍(版本控制工具) 1、svn的定义: svn是一个开放源代码的版本控制系统,通过采用分支管理系统的高效管理,简而言之就是用于多个人共同开发同一个项目,实现共享资源,实现最终集中式个管理。 2.snv的作用: 在项目中对需求规格说明书,测试用例,…

9.前端——HTML详细

HTML详解 Hyper Text Markup Language (超文本标记语言) HTML5 W3C(万维网联盟World Wide Web Consortium) 国际中立性技术标准机构 W3C标准包括结构化标准语言(HTML,XML) 表现标准语言(CSS) 行为标准(DOM,ECMAScript)网页基本结构 <!--网页基本结构--> <!--D…

(搬运)碳知识大全

碳交易的一个小例子: 年初,有两个公司A和B,A公司每年规定排放二氧化碳100吨/年,B也是规定排放二氧化碳100吨/年;政府发放给A的碳配额是100吨/年,发放给B的碳配额也是100吨/年;2)年底,A公司通过节能改造,仅排放二氧化碳80吨,多余的20吨二氧化碳配额,就可以在碳交易市…