PaddleNLP训练和使用自定义词向量模型
2021-12-17 本文已影响0人
lodestar
为什么需要自定义训练词向量?比如医疗行业中,中英文混合比较多,专业名词多,而通用词向量模型不满足要求。
1.先选择paddle训练好的词向量,来比较相似度
from paddlenlp.embeddings import TokenEmbedding
# 初始化TokenEmbedding, 预训练embedding未下载时会自动下载并加载数据
# w2v.baidu_encyclopedia.target.word-word.dim300 为默认的词向量
# 源代码paddlenlp/embeddings/constant.py中可查看所有可用的词向量
token_embedding = TokenEmbedding(embedding_name="w2v.baidu_encyclopedia.target.word-word.dim300")
score1 = token_embedding.cosine_sim("女孩", "男孩")
print(score1)
结果:
[2021-12-17 22:09:11,586] [ INFO] - Loading token embedding...
[2021-12-17 22:09:21,149] [ INFO] - Finish loading embedding vector.
[2021-12-17 22:09:21,151] [ INFO] - Token Embedding info:
Unknown index: 635963
Unknown token: [UNK]
Padding index: 635964
Padding token: [PAD]
Shape :[635965, 300]
0.7981167
2.将文章语料库分词
import jieba.analyse
import codecs
#以写的方式打开原始的简体中文语料库
f=codecs.open('data/article.txt','r',encoding="utf8")
#将分完词的语料写入到seg.txt文件中
target = codecs.open("data/seg.txt", 'w',encoding="utf8")
print('open files')
line_num=1
line = f.readline()
#循环遍历每一行,并对这一行进行分词操作
#如果下一行没有内容的话,就会readline会返回-1,则while -1就会跳出循环
while line:
print('---- processing ', line_num, ' article----------------')
line_seg = " ".join(jieba.cut(line))
target.writelines(line_seg)
line_num = line_num + 1
line = f.readline()
#关闭两个文件流,并退出程序
f.close()
target.close()
3.训练词向量模型
import logging
import os.path
import sys
import multiprocessing
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
import numpy as np
if __name__ == '__main__':
# check and process input arguments
if len(sys.argv) < 4:
print (globals()['__doc__'] % locals())
sys.exit(1)
#inp:分好词的文本
#outp1:训练好的模型
#outp2:得到的词向量
inp, outp1, outp2 = sys.argv[1:4]
'''
LineSentence(inp):格式简单:一句话=一行; 单词已经过预处理并被空格分隔。
size:是每个词的向量维度;
window:是词向量训练时的上下文扫描窗口大小,窗口为5就是考虑前5个词和后5个词;
min-count:设置最低频率,默认是5,如果一个词语在文档中出现的次数小于5,那么就会丢弃;
workers:是训练的进程数(需要更精准的解释,请指正),默认是当前运行机器的处理器核数。这些参数先记住就可以了。
sg ({0, 1}, optional) – 模型的训练算法: 1: skip-gram; 0: CBOW
alpha (float, optional) – 初始学习率
iter (int, optional) – 迭代次数,默认为5
'''
model = Word2Vec(LineSentence(inp), vector_size=300, window=5, min_count=5, workers=multiprocessing.cpu_count())
model.save(outp1)
#不以C语言可以解析的形式存储词向量
model.wv.save_word2vec_format(outp2, binary=False)
# 将npy格式转化成npz格式
model.build_vocab(LineSentence(inp), update=True) #添加vocab
em = np.load('data/article.model.wv.vectors.npy')
np.savez('data/article.model.wv.vectors.npz', embedding=em, vocab=np.array(model.wv.index_to_key))
python train.py data/seg.txt data/article.model data/article.vector
4.将article.model.wv.vectors.npz模型复制到~/.paddlenlp/models/embeddings 路径下,使用词向量模型
from paddlenlp.embeddings import TokenEmbedding
token_embedding = TokenEmbedding(embedding_name="article.model.wv.vectors")
score1 = token_embedding.cosine_sim("女孩", "男孩")
print(score1)
结果:
Unknown index: 42490
Unknown token: [UNK]
Padding index: 42491
Padding token: [PAD]
Shape :[42492, 300]
0.20732212