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
上一篇下一篇

猜你喜欢

热点阅读