NLP-文本向量训练及相似度计算

NLP-文本向量训练及相似度计算,第1张

NLP-文本向量训练及相似度计算

目录
    • 一、准备语料库
    • 二、代码
      • 1.词向量的训练及词语相似度
      • 2.段落向量的训练及文档相似度
      • 3.word2vec计算网页相似度
      • 4.doc2vec计算网页相似度

一、准备语料库

首先下载wiki中文语料(大约1.7G)
https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2
下载的文件名为“zhwiki-latest-pages-articles.xml.bz2”

开源语料库
https://github.com/brightmart/nlp_chinese_corpus
https://github.com/crownpku/Awesome-Chinese-NLP

维基中文语料库地址
https://dumps.wikimedia.org/zhwiki/latest/

wike百科语料
https://dumps.wikimedia.org/zhwiki/

二、代码 1.词向量的训练及词语相似度

本文训练词向量的步骤是:

  1. 运行data_pre_process.py脚本对原始中文语料库进行预处理,该脚本执行完毕后会产生reduce_zhiwiki.txt这个文档。
  2. 运行training.py脚本,执行完该脚本后会得到zhiwiki_news系列的四个文件,训练好的词向量就存在这几个文件里。

data_pre_process.py
文本预处理,jieba分词,繁转简

# -*- coding: utf-8 -*-
from gensim.corpora import WikiCorpus
import jieba
from langconv import *
 
 
def my_function():
    space = ' '
    i = 0
    l = []
    zhwiki_name = './data/zhwiki-latest-pages-articles.xml.bz2'
    f = open('./data/reduce_zhiwiki.txt', 'w')
    wiki = WikiCorpus(zhwiki_name, lemmatize=False, dictionary={})
    for text in wiki.get_texts():
        for temp_sentence in text:
            temp_sentence = Converter('zh-hans').convert(temp_sentence)
            seg_list = list(jieba.cut(temp_sentence))
            for temp_term in seg_list:
                l.append(temp_term)
        f.write(space.join(l) + 'n')
        l = []
        i = i + 1
        if(i % 200 == 0):
            print('Saved ' + str(i) + ' articles')
    f.close()
 
 
if __name__ == '__main__':
    my_function()

training.py
word2vec文本转向量

# -*- coding: utf-8 -*-
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
import logging
 
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
 
 
def my_function():
    wiki_news = open('D:\yangyang\wiki\wikipre\reduce_zhiwiki.txt', 'r', encoding='utf8')
    # sg = 0 表示用CBOW模型训练 1表示用SKIP-GRAM模型训练
    # size表示词向量的维度
    # window 表示当前词与预测词最大距离
    # min_count表示最小出现次数
    # workers 表示训练词向量时所使用的线程数
    model = Word2Vec(LineSentence(wiki_news), sg=0, size=192, window=5, min_count=5, workers=9)
    model.save('zhiwiki_news.word2vec')
 
 
if __name__ == '__main__':
    my_function()
 
# 2019/6/17 19:51
# 2019-06-18 11:15:10,509 : INFO : EPOCH 1 - PROGRESS: at 0.70% examples, 65 words/s, in_qsize 18, out_qsize 0
# 训练速度太慢,要用服务器才行 24小时还不到1% 单机训练完要100天

test
根据向量计算余弦相似度

# coding=utf-8
import gensim
 
 
def my_function():
 
    model = gensim.models.Word2Vec.load('./data/zhiwiki_news.word2vec')
    print(model.similarity('西红柿', '番茄'))  # 相似度为0.63
    print(model.similarity('西红柿', '香蕉'))  # 相似度为0.44
 
    word = '中国'
    if word in model.wv.index2word:
        print(model.most_similar(word))
 
 
if __name__ == '__main__':
    my_function()
2.段落向量的训练及文档相似度
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import gensim.models as g
from gensim.corpora import WikiCorpus
import logging
from langconv import *
 
 
# enable logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
 
docvec_size = 192
 
 
class TaggedWikidocument(object):
    def __init__(self, wiki):
        self.wiki = wiki
        self.wiki.metadata = True
 
    def __iter__(self):
        import jieba
        for content, (page_id, title) in self.wiki.get_texts():
            yield g.doc2vec.LabeledSentence(words=[w for c in content
                                                   for w in jieba.cut(Converter('zh-hans').convert(c))], tags=[title])
 
 
def my_function():
    zhwiki_name = './data/zhwiki-latest-pages-articles.xml.bz2'
    wiki = WikiCorpus(zhwiki_name, lemmatize=False, dictionary={})
    documents = TaggedWikidocument(wiki)
 
 # docs表示用于训练的语料文章。
 # size代表段落向量的维度。
 # window表示当前词和预测词可能的最大距离。
 # min_count表示最小出现的次数。
 # workers表示训练词向量时使用的线程数。
 # dm表示训练时使用的模型种类,一般dm默认等于1,这时默认使用DM模型;当dm等于其他值时,使用DBOW模型训练词向量。
    model = g.Doc2Vec(documents, dm=0, dbow_words=1, size=docvec_size, window=8, min_count=19, iter=5, workers=8)
    model.save('data/zhiwiki_news.doc2vec')
 
 
if __name__ == '__main__':
    my_function()
3.word2vec计算网页相似度

word2vec计算网页相似度的基本方法是:抽取网页新闻中的关键词,接着将关键词向量化,然后将得到的各个词向量相加,最后得到的一个词向量总和代表网页新闻的向量化表示,利用这个总的向量计算网页相似度。包括的步骤是:

  1. 关键词提取
  2. 关键词向量化
  3. 相似度计算

基本方法:抽取文本中的关键词(结巴工具包里面的tfidf关键字提取),将关键词向量化,然后将得到的各个词向量相加,最后得到一个词向量总和代表文本的向量化表示,利用总的向量计算文本相似度。

# -*- coding: utf-8 -*-
import jieba.posseg as pseg
from jieba import analyse
 
def keyword_extract(data, file_name):
   tfidf = analyse.extract_tags
   keywords = tfidf(data)
   return keywords
 
def getKeywords(docpath, savepath):
 
   with open(docpath, 'r') as docf, open(savepath, 'w') as outf:
      for data in docf:
         data = data[:len(data)-1]
         keywords = keyword_extract(data, savepath)
         for word in keywords:
            outf.write(word + ' ')
         outf.write('n')
def word2vec(file_name,model):
    with codecs.open(file_name, 'r') as f:
        word_vec_all = numpy.zeros(wordvec_size)
        for data in f:
            space_pos = get_char_pos(data, ' ')
            first_word=data[0:space_pos[0]]
            if model.__contains__(first_word):
                word_vec_all= word_vec_all+model[first_word]
 
            for i in range(len(space_pos) - 1):
                word = data[space_pos[i]:space_pos[i + 1]]
                if model.__contains__(word):
                    word_vec_all = word_vec_all+model[word]
        return word_vec_all
 
def simlarityCalu(vector1,vector2):
    vector1Mod=np.sqrt(vector1.dot(vector1))
    vector2Mod=np.sqrt(vector2.dot(vector2))
    if vector2Mod!=0 and vector1Mod!=0:
        simlarity=(vector1.dot(vector2))/(vector1Mod*vector2Mod)
    else:
        simlarity=0
    return simlarity
 
if __name__ == '__main__':
    model = gensim.models.Word2Vec.load('data/zhiwiki_news.word2vec')
    p1 = './data/P1.txt'
    p2 = './data/P2.txt'
    p1_keywords = './data/P1_keywords.txt'
    p2_keywords = './data/P2_keywords.txt'
    getKeywords(p1, p1_keywords)
    getKeywords(p2, p2_keywords)
    p1_vec=word2vec(p1_keywords,model)
    p2_vec=word2vec(p2_keywords,model)
 
    print(simlarityCalu(p1_vec,p2_vec))
4.doc2vec计算网页相似度

跟word2vec计算网页相似度类似,doc2vec计算网页相似度也主要包括如下三个步骤:①预处理;②文档向量化;③计算文本相似。

import gensim.models as g
import codecs
import numpy
import numpy as np
 
model_path = './data/zhiwiki_news.doc2vec'
start_alpha = 0.01
infer_epoch = 1000
docvec_size = 192
 
 
def simlarityCalu(vector1, vector2):
    vector1Mod = np.sqrt(vector1.dot(vector1))
    vector2Mod = np.sqrt(vector2.dot(vector2))
    if vector2Mod != 0 and vector1Mod != 0:
        simlarity = (vector1.dot(vector2)) / (vector1Mod * vector2Mod)
    else:
        simlarity = 0
    return simlarity
 
 
def doc2vec(file_name, model):
    import jieba
    doc = [w for x in codecs.open(file_name, 'r', 'utf-8').readlines() for w in jieba.cut(x.strip())]
    doc_vec_all = model.infer_vector(doc, alpha=start_alpha, steps=infer_epoch)
    return doc_vec_all
 
 
if __name__ == '__main__':
    model = g.Doc2Vec.load(model_path)
    p1 = './data/P1.txt'
    p2 = './data/P2.txt'
    P1_doc2vec = doc2vec(p1, model)
    P2_doc2vec = doc2vec(p2, model)
    print(simlarityCalu(P1_doc2vec, P2_doc2vec))

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5594992.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存