预训练词向量的使用

目录

1.代码实现

2.知识点:


 

两个网站可以下载预训练词向量

1.代码实现

import os
import torch
from torch import nn
import dltools
class TokenEmbedding:    #没写括号,就是继承python默认的Object类
    def __init__(self, file_path):
        self.idx_to_token, self.idx_to_vec= self._load_embedding(file_path)
        self.unknown_idx = 0
        #创建 词与索引 对应的词典
        self.token_to_idx = {token: idx for idx, token in enumerate(self.idx_to_token)}
        
    
    #加载预训练好的词向量
    def _load_embedding(self, file_path):
        #创建列表,分别存放词与词向量对应的索引
        idx_to_token, idx_to_vec = ['<unk>'], []  #在存放词索引的列表中先加一个未知字符<unk>
        with open(file_path, 'r', encoding='utf-8') as f:
            #对于数据量非常大的文件读取,把其当做迭代器,一行行遍历输出,避免一下子把整个文件加载进来
            for line in f:
                #strip()移除字符串头尾指定的字符 ( 默认为空白符 ) 空格 ( ' ' ) 、制表符 ( \t ) 、换行符 (\r\ ) 统称为空白符
                #rstrip()只对右边进行移除空白符操作
                elems = line.rstrip().split(' ')  #输出的elems就是一个列表
                token, elems = elems[0], [float(elem) for elem in elems[1:]]
                #跳过fasttext的第一行    fasttext的第一行只有两个元素(一个token, 一个elem) 
                if len(elems) > 1:
                    idx_to_token.append(token)
                    idx_to_vec.append(elems)
        
        #在idx_to_vec中为<unk>添加一个全是0的词向量   #idx_to_vec是一个二维列表
        idx_to_vec = [[0] * len(idx_to_vec[0])] + idx_to_vec
        return idx_to_token, torch.tensor(idx_to_vec)
    
    def __getitem__(self, tokens):
        """根据输入的tokens返回对应的词向量"""
        #根据tokens获取对应的词索引 
        #dict[token]索引字典中没有的元素会报错, dict.get(token, 0) 索引字典中没有的元素会返回0
        indices = [self.token_to_idx.get(token, self.unknown_idx) for token in tokens]
        #根据索引indices来获取对应的词向量
        vecs = self.idx_to_vec[torch.tensor(indices)]
        return vecs
    
    def __len__(self): 
        """返回tokens的数量长度"""
        return len(self.idx_to_token)
glove_6b50d = TokenEmbedding(r'E:/ALOT/10_deep_learning/data/glove.6B/glove.6B.50d.txt')
len(glove_6b50d)
400001
glove_6b50d.token_to_idx['beautiful']
3367
glove_6b50d.idx_to_token[3367]   #idx_to_token是列表,可以根据索引来获取值

 'beautiful'

#计算余弦相似度来衡量词的相似度
def knn(W, x, k):
    cos = torch.mv(W,x.reshape(-1, )) / (torch.sqrt(torch.sum(W * W, axis=1) + 1e-9) * torch.sqrt((x * x).sum()))
    #筛选cos前10位
    _, topk = torch.topk(cos, k=k)
    return topk, [cos[int(i)] for i in topk] 
def get_similar_tokens(query_token, k, embed):
    #获取topk, cos
    #embed.idx_to_vec 已经做了embed的词向量
    #embed[[query_token]]获取查询词的词向量
    topk, cos = knn(embed.idx_to_vec, embed[[query_token]], k+1)
    for i, c in zip(topk[1:], cos[1:]):   #排除查询词query_token它本身
        print(f'{embed.idx_to_token[int(i)]} : cosine相似度={float(c):.3f}')
#查询“chip芯片”的相似词
get_similar_tokens('chip', 3, glove_6b50d)
chips : cosine相似度=0.856
intel : cosine相似度=0.749
electronics : cosine相似度=0.749
#词类比
#例如: man - woman :  son - daughter
#上面相当于
#-->daughter = woman - man  + son
def get_analogy(token_a, token_b, token_c, embed):
    #分别获取token_a, token_b, token_c的词向量
    vecs = embed[[token_a, token_b, token_c]]
    x = vecs[1] - vecs[0] + vecs[2]
    topk, cos = knn(embed.idx_to_vec, x, 1)
    return embed.idx_to_token[int(topk[0])]
get_analogy('man', 'woman', 'son', glove_6b50d)

'daughter' 

#加载fastText词向量
fasttext_16b300d = TokenEmbedding(r'E:/ALOT/10_deep_learning/data/wiki-news-300d-1M.vec')
len(fasttext_16b300d)
999995
fasttext_16b300d.token_to_idx['boy']

 2033

fasttext_16b300d.idx_to_token[2033]

 'boy'

fasttext_16b300d.idx_to_vec[2033].shape


fasttext_16b300d.idx_to_vec[2033].reshape(-1,).shape

 两个形状输出都是:

torch.Size([300])
get_similar_tokens('boy', 2, fasttext_16b300d)

 

girl : cosine相似度=0.862
boys : cosine相似度=0.772 
get_analogy('man', 'woman', 'son', fasttext_16b300d)  #词类比效果比较差

 'son'

2.知识点:

 

 

 

自然语言处理中,预训练词向量(如Word2Vec、GloVe或BERT等模型生成的向量)是一个关键工具,它们将词语转换为高维稠密向量,这些向量捕捉了词语之间的语义和语法关联。使用预训练词向量主要有以下几个步骤: 1. **加载预训练模型**:首先,你需要从相应的库(如gensim、spaCy或huggingface的transformers)中加载预训练的词嵌入模型。例如,如果你用的是GloVe,可以下载预训练模型并加载。 ```python from gensim.models import KeyedVectors model = KeyedVectors.load_word2vec_format('path_to_glove_file.txt', binary=True) ``` 2. **查找/编码单词**:对于新的或未知的单词,你可以选择将其转换为其在词典中的索引,如果不在词汇表内,通常会返回特殊的标识符(比如`unk`)。 ```python word_vector = model.wv['word'] ``` 3. **融合上下文**:如果是处理句子或文档级别的任务,可能需要对整个序列的词向量进行平均、加权或注意力机制来整合上下文信息。 4. **输入到模型**:词向量可以直接作为神经网络的输入层,用于文本分类、情感分析、机器翻译等任务。在深度学习模型中,通常是通过全连接层或者其他适当的层进行进一步处理。 5. **微调(Fine-tuning)**:对于一些特定的任务,特别是像情感分析、问答系统这样的下游应用,可能会选择在一个大型预训练模型上进行微调,让模型适应特定领域的术语和上下文。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值