其他分享
首页 > 其他分享> > word2vec实战:词云应用

word2vec实战:词云应用

作者:互联网

word2vec实战:获取处理中文维基百科(Wikipedia)语料库,训练成word2vec模型,并实现词云的应用

背景

word2vec 谷歌开源项目,主要理论有Tomas Mikolov团队2篇论文组成,下载链接如下:

https://arxiv.org/pdf/1301.3781.pdf

https://arxiv.org/pdf/1310.4546.pdf

传统方法

传统的方法是将词汇作为离散的单一符号

缺点

1、这些符号编码毫无规则
2、无法提供词汇之间可能存在的关联关系,而词汇的向量表示将克服上述难题。  

向量空间模型(vsm)

将词汇表示在一个连续的向量空间中,语义近似的词被映射为相邻的数据点。

VSM依赖于分布式假设思想,该思想的核心是:出现于相同的上下文情景中的词汇都有相似的语义。

研究方法:

基于VSM假设有2种研究方法:

1,基于计数的方法:
    计算某词汇极其临近词在一个大型语料库中共同出现的频率,然后将其映射到一个小而稠密的向量中。
2,预测方法:
    该方法试图直接从某词汇的临近词对其进行预测,此过程利用学习到的向量。
    word2vec是一种可以进行高效率词嵌套学习的预测模型,该模型有2种具体的形式:

        a、CBOW模型:根据上下文词汇“the cat sits on the”,来预测目标词“mat”。
        b、skip-gram模型:通过目标词来预测源词汇。

实战训练

实验环境: win10/ python3.8(Anaconda版)

1、Wikipedia 原始数据下载

数据下载地址: https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2

下载的文件是一个大小为1.3G的压缩包,解压后是个5.8G左右的xml文件,内容是网页标签形式的。我们需要抽取出其中的有效信息

2、使用wikipedia Extractor抽取正文

Wikipedia Extractor是意大利人用Python写的一个维基百科抽取器,使用非常方便。
下载安装之后直接使用这条命令即可完成抽取,运行时间很快。执行以下命令:

直接安装

pip install wikiextractor
python -m wikiextractor.WikiExtractor filename -b 1024M -o extracted

例如:filename = zhwiki-latest-pages-articles.xml.bz2

提取完成后资料:

https://www.icode9.com/i/ll/?i=20200910100756810.png

3、繁体转简体

维基百科的中文数据是繁简混杂的,里面包含大陆简体、台湾繁体、港澳繁体等多种不同的数据。有时候在一篇文章的不同段落间也会使用不同的繁简字

参考windows使用opencc中文简体和繁体互转 一文,该文作者提供的百度云下载链接
链接:https://pan.baidu.com/s/10yI1lPRKNOYJ2aSbl4YegA 密码:2kv9

下载完成之后,解压到本地即可。解压之后可以将OpenCC下的bin目录添加到系统环境变量中

https://www.icode9.com/i/ll/?i=20200910101335755.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25jdV9ocGs=,size_16,color_FFFFFF,t_70

share-->opencc中有需要的json文件就是opencc的配置文件

https://www.icode9.com/i/ll/?i=20200910101410502.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25jdV9ocGs=,size_16,color_FFFFFF,t_70

转换操作:

opencc -i 需要转换的文件路径 -o 转换后的文件路径 -c 配置文件路径

opencc -i D:\data\extracted\AA\wiki_00 -o D:\data\extracted\AA\swiki_00 –c D:\data\opencc-1.0.4\share\opencc\t2s.json 

https://www.icode9.com/i/ll/?i=20200910101549250.png

4、符号处理

由于Wikipedia Extractor抽取正文时,会将有特殊标记的外文直接剔除。我们最后再将「」『』这些符号替换成引号,顺便删除空括号,就大功告成了!代码如下:

将下面文件保存为exec.py

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
Train my own word2vec, basing of  Wikipedia
由于Wikipedia Extractor抽取正文时,会将特殊标记的外文直接删除。
我们最后将特殊符号替换成引号,同时删除空括号
"""

#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import sys
import codecs
from importlib import reload


def myfun(input_file):
    p1 = re.compile(r'-\{.*?(zh-hans|zh-cn):([^;]*?)(;.*?)?\}-')
    p2 = re.compile(r'[(\(][,;。?!\s]*[)\)]')
    p3 = re.compile(r'[「『]')
    p4 = re.compile(r'[」』]')
    outfile = codecs.open('std_' + input_file, 'w', 'utf-8')
    with codecs.open(input_file, 'r', 'utf-8') as myfile:
        for line in myfile:
            line = p1.sub(r'\2', line)
            line = p2.sub(r'', line)
            line = p3.sub(r'“', line)
            line = p4.sub(r'”', line)
            outfile.write(line)
    outfile.close()


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print("Usage: python script.py inputfile")
        sys.exit()
    reload(sys)

    # sys.setdefaultencoding('utf-8')
    input_file = sys.argv[1]
    myfun(input_file)

并将该文件放到与数据文件相同的目录

执行命令:python exec.py wiki_00

依次执行得到预料数据。

5、中文分词

中文分词工具有很多种, 这里我们使用python版本的结巴分词:https://github.com/fxsjy/jieba

安装很简单:$ pip install jieba

安装好后根据需要编写分词脚本:
eg:

import jieba
import jieba.analyse
import jieba.posseg as pseg
import codecs, sys


def cut_words(sentence):
    return " ".join(jieba.cut(sentence)).encode('utf-8')


f = codecs.open(r"D:\workplace\ml\extracted\AA\std_zh_wiki_00", 'r', encoding="utf8")

target = codecs.open(r"D:\workplace\ml\extracted\AA\cut_std_zh_wiki_00", 'w', encoding="utf8")
print('open files')
line_num = 1
line = f.readline()
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()
exit()

while line:
    curr = []
    for oneline in line:
        print(oneline)
        curr.append(oneline)
    after_cut = map(cut_words, curr)
    target.writelines(after_cut)
    print ('saved ',line_num,' articles')
    exit()
    line = f.readline1()
f.close()
target.close()

在分词脚本执行完之后,可以将所有的预料合并到一个文件:
eg:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import os


output = open(r"D:\workplace\ml\extracted\AA\wiki_corpus", "w", encoding="utf-8")
input_dir = r"D:\workplace\ml\extracted\AA"
for i in range(2):
    print(i)
    file_path = os.path.join(input_dir, str("cut_std_zh_wiki_0%s" % str(i)))
    file = open(file_path, "r", encoding="utf-8")
    line = file.readline()
    while line:
        output.writelines(line)
        line = file.readline()
    file.close()
output.close()

6、训练word2vec模型

训练模型我们使用python的gensim库提供的方法,gensim官网。

安装非常简单:$ pip install gensim

接下来,我们用1.21G的大文件进行训练,训练代码也很简单:

from gensim.models import word2vec
import logging

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.LineSentence(u'./cut_std_zh_wiki_00')
model = word2vec.Word2Vec(sentences,vector_size=200,window=5,min_count=5,workers=4)
model.save('./word2vecModel/WikiCHModel')

7、模型调用和测试

调用模型也很简单,同样使用gensim库。

from gensim.models import word2vec

model = word2vec.Word2Vec.load('./word2vecModel/WikiCHModel')

print(model.wv.similarity('奥运会','金牌')) #两个词的相关性

print(model.wv.most_similar(['伦敦','中国'],['北京'])) # 北京is to中国 as 伦敦is to?

到此,基于中文Wikipedia 的word2vec词向量模型基本训练完毕

8、Word2vec应用

词云应用
计算文本相似度

代码实例:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#
import logging
from gensim import models
import numpy as np
import matplotlib.pyplot as plt
from wordcloud import WordCloud
# 声成词云


def get_circle_mask():
    """
    获取一个圆形
    :return:
    """
    x, y = np.ogrid[:300, :300]
    mask = (x - 150) ** 2 + (y - 150) ** 2 > 130 ** 2
    mask = 255 * mask.astype(int)

    return mask


def draw_word_cloud(word_cloud):
    wc = WordCloud(font_path=r"D:\workplace\data\tensorflow\word2vec\extracted\myfont.ttf",
                   background_color='white', mask=get_circle_mask())
    wc.generate_from_frequencies(word_cloud)

    # 隐藏x轴y轴
    plt.axis("off")
    plt.imshow(wc, interpolation='bilinear')
    plt.show()
    wc.to_file('demo.png')


def test():
    logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s", level=logging.INFO)
    model = models.Word2Vec.load(r'D:\workplace\ml\extracted\AA\word2vecModel_Wiki')

    one_corpus = ['人工智能']
    reslut = model.wv.most_similar(one_corpus[0], topn=100)
    print(reslut)

    word_cloud = dict()
    for sim in reslut:
        word_cloud[sim[0]] = sim[1]
    draw_word_cloud(word_cloud)


if __name__ == '__main__':
    test()

结果:

参考博客:
https://blog.csdn.net/sinat_29957455/article/details/81432846?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0-81432846-blog-68942216.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3

标签:实战,word2vec,https,utf,词云,file,import,line
来源: https://www.cnblogs.com/01black-white/p/16407704.html