【NLP】之 Word2vec(将评论转为词向量)_将评论数据转化为向量模型_牧心.的博客-程序员秘密

技术标签: 自然语言处理 NLP  

1.Word2vec简介

Word2vec,为一些用来产生词向量的有关模型。这些模型是浅层的神经网络,经过训练可以重新建立语言文本。网络用文字表示,有必要猜测相邻位置的输入字。

训练完成后,word2vec模型可用于将每个单词映射到矢量,该矢量可用于表示单词和单词之间的关系。该向量为神经网络之隐藏层。总之,word2vec使用一层神经网络将one-hot 形式的单词向量映射到分布式形式的单词向量。word2vec涉及到很多自然语言处理的名词。第一个是单词vector。这可以很容易地用于各种后续计算,即单词矢量。词向量最简单的形式是one-hot形式;还有更复杂的分布式字矢量,而word2vec是用于学习该分布式字矢量的算法。

Word2vec是由Google开发的一个计算词向量的开源工具,它是一个浅层神经网络(如图1),神经网络模型包含输入层、输出层以及隐藏层。

                              

                                                                            图1 神经网络模型

Word2vec的实质是用来计算词向量的CBOW模型和Skip-gram模型。

CBOW是一种根据上下文的词语预测当前词语的出现概率的模型。训练CBOW模型的输入数据是某个特征词的上下文相关的词相对应的词向量,其输出数据是这个特定词的词向量。在训练CBOW模型时,词向量只是个副产品,换句话说,词向量是CBOW模型的一个参数。训练开始的时候,词向量初始化为一个随机值,在模型训练的过程中,词向量进行不断地更新。投影层对其求和,也就是简单的向量加法。对于输出层,由于语料库中的词汇量是固定的C个,所以可以将模型的训练看作是多分类问题:对于给定特征,模型从C个分类中输出一个最近的。CBOW模型中上下文距离是可以自定义的,使用的是词袋模型,所以上下文中的词都是平等的,不需考虑其与关注词的距离。

Skip-Gram模型和CBOW模型正好相反,其输入数据是一个特定词的词向量,输出结果是输入的词对应的上下文词向量。Skip-Gram模型的实质是计算输入的词的输入向量  和目标词的输出向量之间的余弦相似度,并进行softmax归一化。

CBOW模型和Skip-Gram模型的原理图如图2。

                                      

                                                     图2 CBOW模型和Skip-Gram模型的原理图

2.Word2vec训练

Word2vec在使用前需要线进行训练,本文训练使用的语料库是Wiki百科的中文语料库(1.61G,337336篇文章)。

语料库下载链接:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2

(1)数据抽取。

下载的原始语料数据包是*-articles.xml.bz2格式的,需要对其进行处理,提取数据存入*.txt文件中。本文使用的提取方式是gensim.corpora中的WikiCorpus。代码如下。

import logging
import os.path
import sys
import warnings
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')
from gensim.corpora import WikiCorpus

if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])  # 得到文件名
    logger = logging.getLogger(program)

    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))

    if len(sys.argv) < 3:
        print(globals()['__doc__'] % locals())
        sys.exit(1)
    inp, outp = sys.argv[1:3]
    space = " "
    i = 0
    output = open("out.txt", "w", encoding='utf-8')
	# gensim里的维基百科处理类WikiCorpus
    wiki = WikiCorpus(inp, lemmatize=False, dictionary=[])  
	# 通过get_texts将维基里的每篇文章转换位1行text文本
	# 并且去掉了标点符号等内容
    for text in wiki.get_texts():  
        output.write(space.join(text) + "\n")
        i = i + 1
        if (i % 1000 == 0):
            logger.info("Saved " + str(i) + " articles.")
    output.close()
    logger.info("Finished Saved " + str(i) + " articles.")

(2)数据预处理。

提取后的预料中包含很多繁体字,需要将其转化为简体字;然后再对其进行结巴分词及去停用词处理。

中文繁体转成中文简体,使用的是OpenCC,它是一款开源的中文处理工具,支持字符级别的转换。该工具下载成功之后,双击opencc.exe文件,在当前目录下打开dos窗口,输入如下命令行:

opencc -i wiki_zh_1.6g.txt -o wiki_zh_simp.txt -c t2s.json

对语料库进行分词,采用的结巴分词与去停留词等方法与https://blog.csdn.net/Aibiabcheng/article/details/105778642相同,在此不在赘述。

使用上述处理完毕的语料库对Word2vec进行训练,本文设置词向量维度为200维,上下文窗口大小为5,最小词频为5。核心代码如下。

import logging
import os.path
import sys
import multiprocessing
from gensim.corpora import WikiCorpus
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence

if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)
    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))
    # check and process input arguments
    if len(sys.argv) < 4:
        print (globals()['__doc__'] % locals())
        sys.exit(1)
    inp, outp1, outp2 = sys.argv[1:4]
    model = Word2Vec(LineSentence(inp), size=200, window=5, min_count=5, workers=2)
    model.save(outp1)
    model.wv.save_word2vec_format(outp2, binary=False)

然后运行如下命令

python word2vec_model.py out.txt out.model out.vector

3.用Word2vec将评论转为词向量

利用维基百科将Word2vec训练完成后,就得到了语料库中的相应词的词向量,将评论信息转化为词向量的实质是利用“键值对”的原理,将特定词的词向量取出。将评论中的中文词全部转化为词向量后,整条评论的向量值就是其所有分词向量的平均值。核心代码如下。

from gensim.models import Word2Vec
import codecs, sys
import pymysql
import numpy
numpy.set_printoptions(suppress=True)

fcoms = codecs.open('coms_all.txt', 'r', encoding="utf8")
w2v_model = Word2Vec.load('wiki.zh.1.6gr.model')
w = codecs.open('vec_all.txt', 'w', encoding="utf8")
size = 200

def count_vec_sentence():
    line = fcoms.readline()
    i = 0
    id = 0
    while line :
        words = line.split(' ')
        vec = numpy.zeros(size).reshape((1, size))
        vec0 = numpy.zeros(size).reshape((1, size))
        count = 0
        flag = True
        for item in words :
            word = item.strip()
            if word.__len__() > 0 :
                if flag :
                    attitude = word
                    flag = False
                else :
                    try :
                        vec += w2v_model[word].reshape((1, size))
                        count += 1
                    except KeyError :
                        # print('==== fault: ', word)
                        continue
        if i % 100 == 0 :
            print(i)
        i += 1
        line = fcoms.readline()
        if count != 0 :
            vec /= count
            w.write(attitude + ' ')
            w.write(str(vec)[2:-2])
            w.write('$')

if '__main__' == __name__:
    count_vec_sentence()

词向量结果

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Aibiabcheng/article/details/105777969

智能推荐

C# 经典排序算法大全_c# point 排序_NetSuite - 张老师的博客-程序员秘密

C# 经典排序算法大全选择排序using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace sorter{ public class SelectionSorter { private int min; pub

讲课专用——线段树——最长上升子序列_weixin_30325487的博客-程序员秘密

题目链接:https://www.luogu.org/problemnew/show/P4198题解:能用线段树解的关键:从第一个位置开始的LIS所以说左子区间一定有效,只考虑如何将右子区间与左子区间衔接线段树维护从节点区间左端点开始的LIS3种情况:1、右子区间全都能衔接——右子区间的LIS最小值(第一个位置)&gt; 左子区间LIS最大值2、右子区间...

雷果国:从1.5K到18K 一个程序员的5年成长之路_csu_小王子的博客-程序员秘密

CSDN雷果国专访:http://www.csdn.net/article/2013-05-13/2815252雷果国《从1.5K到18K,一个程序员的5年成长之路》原文:http://blog.csdn.net/lgg201/article/details/8637763

kali 2.0 默认mysql_kali 2.0下搭建DVWA环境_蚕月拾肆的博客-程序员秘密

DVWA (Dam Vulnerable Web Application)DVWA是用PHP+Mysql编写的一套用于常规WEB漏洞教学和检测的WEB脆弱性测试程序。包含了SQL注入、XSS、盲注等常见的一些安全漏洞,在kali linux下搭建DVWA非常方便,因为所需的apache2、mysql、php等环境在kali linux中默认已经安装好了搭建步骤:1. 首先去github上下载DVW...

Android实现部分文字可点击及变色_android 部分文字点击_Joven0的博客-程序员秘密

可以使用SpannableString和ClickableSpan: TextView userAgreement = findViewById(R.id.user_agreement); SpannableString agreement = new SpannableString("Agree to the User Agreement and Privac...

随便推点

WWDC20 Session 清单(06-23)_李发展的博客-程序员秘密

又一年 WWDC。今年 session 的数量多达 200+,是往年的 2 倍。小集继续为您整理每天的 session 清单,方便您根据自己的喜好来选择内容。Adopt the new look of macOS改造 Mac 应用程序:探索如何拥抱 macOS Big Sur 的新设计并采用其视觉层次结构、设计模式和行为。我们将围绕结构项和通用控件探索 AppKit 的最新更新,并向您展示如何仅需一点点工作就能适应更多自定义的界面。了解如何结合使用自定义的颜色和符号来进一步个性化您的应用程序。

Debug | ‘wget‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。_wget' 不是内部或外部命令,也不是可运行的程序 或批处理文件。_买猫咪的小鱼干的博客-程序员秘密

报错信息'wget' 不是内部或外部命令,也不是可运行的程序 或批处理文件。分析在jupyter notebook使用!wget遇到了这个问题,查到发现wget是linux系统下,windows不自带。解决方法去wget官网下载,选择32位/64位,下载ZIP/EXE,将下载下来的EXE文件放到C:\Windows\System32即可。叨下后续:由于我用的是jupyter notebook。虽然windows的cmd可以用了,但是不能直接在jupyter cell里面使用!wget首先要说

Linux下的iwpriv(iwlist、iwconfig)的简单应用 ._sam0535的博客-程序员秘密

无线网络飞速发展的今天,许多设备都提供了连接无线网络的功能。那么Linux下的wifi到底该怎么配置、连接呢??开始配置之前,我们要说说iw家族。iw是linux下常用的wifi配置工具,网上有相应的库和源码。全名为wirelessTools。配置wifi模块,并连接相应的无线网络过程:主要使用iwpriv命令1. 扫描可用的无线网络:[cpp] view plai

【智能终端课程】五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程_android 系统终端开发_代码款款的博客-程序员秘密

引言 在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入Android浪潮的朋友们,为了确保大家能顺利完成开发环境的搭建,文章写的尽量详细,希望对准备进入Android开发的朋友有帮助。 本教程将分为五个步骤来完成Android开发环境的部署。第一步:安装JDK。第二步:配置Windows上JDK的变量环境 。第三...

LFilePicker---文件选择利器,各种样式有它就够了_leonDuHua的博客-程序员秘密

在 Android 开发中如果需要选择某个文件,可以直接调取系统的文件管理器进行选择,但是无法保证各个厂商的手机界面一致,而且解析Uri 还比较繁琐,如果还需要多选呢?需要文件类型过滤呢?老板说界面丑呢?那么福利来了,你可以使用LFilePicker,它都支持什么呢?还算漂亮的界面各种手机一致的体验多种界面风格自定义标题文字和颜色文件多选或者单选文件类型过滤Fragment启动国际

PCB拼板之多款矩形排样算法实现--学习_weixin_30723433的博客-程序员秘密

参考资料:《一种新型pcb合拼求解过程》拼版合拼问题描述和求解过程合拼问题描述Pcb合拼问题是通过二维矩形组合排样而演化与扩展而形成的一种新拼版问题,把每个零件都看成一个规则的矩形进行排样 。而PCB合拼问题中,Pcb种类多,数量大,需要多张模板拼版,母版上PCB的种类或数量不同,则母版拼版视为不同,最终优化为母版拼版种类数量。板子的加投数与板材利用率结合,在PCB投产时一般是...

推荐文章

热门文章

相关标签