本文为学习Datawhale 2021.9组队学习情感分析笔记 原学习文档地址:https://github.com/datawhalechina/team-learning-nlp/tree/master/EmotionalAnalysis
baseline笔记见https://blog.csdn.net/weixin_43634785/article/details/120289701?spm=1001.2014.3001.5502
主要写需要注意的与baseline的不同点。 详细情况见原学习文档task3
1 加载数据
fasttext不是一个时序模型,不需要include_lengths=True了,但是它与其他文本分类模型的一个不同之处在于其计算了输入句子的n-gram,所以需要对数据进行生成n-grams的操作并读入这部分数据
下面是生成bigrams的函数
def generate_bigrams(x):
n_grams = set(zip(*[x[i:] for i in range(2)]))
for n_gram in n_grams:
x.append(' '.join(n_gram))
return x
分步查看得到
x = ['This', 'film', 'is', 'terrible']
print([x[i:] for i in range(2)])
y = [['This', 'film', 'is', 'terrible'], ['film', 'is', 'terrible']]
print(*y)
print(zip(*[x[i:] for i in range(2)]))
print(*zip(*[x[i:] for i in range(2)]))
print(set(zip(*[x[i:] for i in range(2)])))
输出
[['This', 'film', 'is', 'terrible'], ['film', 'is', 'terrible']]
['This', 'film', 'is', 'terrible'] ['film', 'is', 'terrible']
<zip object at 0x0000024962F77088>
('This', 'film') ('film', 'is') ('is', 'terrible')
{('film', 'is'), ('is', 'terrible'), ('This', 'film')}
例子
generate_bigrams(['This', 'film', 'is', 'terrible'])
加载数据时不需要include_lengths了,但需要preprocessing把bigrams加进去
TEXT = data.Field(tokenize = 'spacy',
tokenizer_language = 'en_core_web_sm',
preprocessing = generate_bigrams)
2 加载预训练词向量
MAX_VOCAB_SIZE = 25_000
TEXT.build_vocab(train_data,
max_size = MAX_VOCAB_SIZE,
vectors = "glove.6B.100d",
unk_init = torch.Tensor.normal_)
LABEL.build_vocab(train_data)
pretrained_embeddings = TEXT.vocab.vectors
model.embedding.weight.data.copy_(pretrained_embeddings)
UNK_IDX = TEXT.vocab.stoi[TEXT.unk_token]
model.embedding.weight.data[UNK_IDX] = torch.zeros(EMBEDDING_DIM)
model.embedding.weight.data[PAD_IDX] = torch.zeros(EMBEDDING_DIM)
同样地,使用了glove预训练词向量
3 FastText模型
class FastText(nn.Module):
def __init__(self, vocab_size, embedding_dim, output_dim, pad_idx):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=pad_idx)
self.fc = nn.Linear(embedding_dim, output_dim)
def forward(self, text):
embedded = self.embedding(text)
embedded = embedded.permute(1, 0, 2)
pooled = F.avg_pool2d(embedded, (embedded.shape[1], 1)).squeeze(1)
return self.fc(pooled)
结构很简单,输入的id先通过embedding得到一个句子里每一个单词的表示,然后再对所有单词的向量取个平均值,再加个线性层,就得到了输出。
4 FastText 、Embedding、Word2Vec
FastText与Word2Vec的结构很像,不同之处是fastText预测标签而CBOW预测的是中间词,即模型架构类似但是模型的任务不同。
都可以用预训练的Embedding,加个Embedding层做个转换就行了
FastText的效果不错,训练速度也快。他引入了n-grams特征对效果有提升,在训练的过程中还使用了一些技巧,比如层次softmax。
|