基于Word2Vec的相似度计算(python)

机器学习 专栏收录该内容
1 篇文章 0 订阅

前言

    此篇文章的基础知识部分总结了一些别人的文章解释,环境为Windows10下的python3.5版本,需要的包为gensim。代码很简要,不足之处请说明。

 

一. 背景知识

1.1词向量

词向量(word2vec)是一个将单词转换成向量形式的工具。可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相似度。

在自然语言处理(NLP)相关任务中,要将自然语言交给机器学习中的算法来处理,通常需要首先将语言数学化,因为机器不是人,机器只认数学符号。向量是人把自然界的东西抽象出来交给机器处理的东西,基本上可以说向量是人对机器输入的主要方式了。

词向量就是用来将语言中的词进行数学化的一种方式,顾名思义,词向量就是把一个词表示成一个向量。NLP 中最直观,也是到目前为止最常用的词表示方法是 One-hot Representation,这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个维度就代表了当前的词。 在word2vec中则采用分布式表征,在向量维数比较大的情况下,每一个词都可以用元素的分布式权重来表示,因此,向量的每一维都表示一个特征向量,作用于所有的单词,而不是简单的元素和值之间的一一映射。

word2vec中包含了对两种模型的训练,C-BOW模型和Gensim模型。在训练每种模型的时候又分HS和NEG两种方法。除了google自己的word2vec工具,也有其它各自不同的版本。其中比较好用的是Python Gensim主题模型包中的word2vec,但通过python版本只实现了skip-gram模型,并且只实现了通过分层softmax方法对其训练,并没有使用negative sampling。

1.2语言模型

语言模型包括文法语言模型和统计语言模型。一般我们指的是统计语言模型。统计语言模型: 统计语言模型把语言(词的序列)看作一个随机事件,并赋予相应的概率来描述其属于某种语言集合的可能性。给定一个词汇集合 V,对于一个由 V 中的词构成的序列S = 〈w1, · · · , wT 〉 ∈ Vn,统计语言模型赋予这个序列一个概率P(S),来衡量S 符合自然语言的语法和语义规则的置信度。用一句简单的话说,语言模型就是计算一个句子的概率大小。常见的统计语言模型有N元文法模型(N-gram Model),最常见的是unigram model、bigram model、trigram model等等。形式化讲,统计语言模型的作用是为一个长度为 m 的字符串确定一个概率分布 P(w1; w2; :::; wm),表示其存在的可能性,其中 w1 到 wm 依次表示这段文本中的各个词。本文所用到的语言模型为skip-gram,skip-gram模型的输入是一个单词wIwI,它的输出是wIwI的上下文wO,1,...,wO,CwO,1,...,wO,C,上下文的窗口大小为CC。

1.3 Gensim模块

本文用python进行预料的训练,其中用到模块Gensim,是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。它支持包括TF-IDF,LSA,LDA,和word2vec在内的多种主题模型算法,支持流式训练,并提供了诸如相似度计算,信息检索等一些常用任务的API接口。

二. 训练预料的预处理

练语料的预处理指的是将文档中原始的字符文本转换成Gensim模型所能理解的稀疏向量的过程。Gensim的word2vec的输入是句子的序列. 每个句子是一个单词列表。

通常,我们要处理的原生语料是一堆文档的集合,每一篇文档又是一些原生字符的集合。在交给Gensim的模型训练之前,我们需要将这些原生字符解析成Gensim能处理的稀疏向量的格式。由于语言和应用的多样性,Gensim没有对预处理的接口做出任何强制性的限定。通常,我们需要先对原始的文本进行分词、去除停用词等操作,得到每一篇文档的特征列表。

本文的语料来源为wiki百科,共2M大小,选用Hanlp汉语分词系统进行文档的分词,

原始数据分词后,并去除词性标注以及停用词。

得到的使用数据结果如下图:

  

Hanlp分词的主要代码如下图:

 

三. 模型训练

3.1 代码以及参数设置

模型训练用到了pythpn中的Gensim模块,Gensim只要求输入按顺序提供句子, 并不将这些句子存储在内存, 然后Gensim可以加载一个句子, 处理该句子, 然后加载下一个句子.

 Word2vec有很多可以影响训练速度和质量的参数:

(1) sg=1是skip-gram算法,对低频词敏感,默认sg=0为CBOW算法,所以此处设置为1。

(2) min_count是对词进行过滤,频率小于min-count的单词则会被忽视,默认值为5。

(3) size是输出词向量的维数,即神经网络的隐藏层的单元数。值太小会导致词映射因为冲突而影响结果,值太大则会耗内存并使算法计算变慢,大的size需要更多的训练数据, 但是效果会更好,在本文中设置的size值为300维度。

(4) window是句子中当前词与目标词之间的最大距离,即为窗口。本文设置窗口移动的大小为5。

(5) negative和sample可根据训练结果进行微调,sample表示更高频率的词被随机下采样到所设置的阈值,默认值为1e-3。

(6) hs=1表示层级softmax将会被使用,默认hs=0且negative不为0,则负采样将会被选择使用。

(7) 最后一个主要的参数控制训练的并行:worker参数只有在安装了Cython后才有效,由于本文没有安装Cython的, 使用的单核。

通过查看程序运行的日志记录,可看到参数设置如下所示:

 

实现代码如下:

 

# -*- coding: utf-8 -*-
import warnings
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')
from gensim.models import word2vec
import logging

# 主程序
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.Text8Corpus(u"D:\wiki\语料.txt")  # 加载语料
n_dim=300
 # 训练skip-gram模型; 
model = word2vec.Word2Vec(sentences, size=n_dim, min_count=5,sg=1) 
# 计算两个词的相似度/相关程度
y1 = model.similarity(u"陕西省", u"山西省")
print(y1)
print("--------")
# 寻找对应关系
print(u"计算机-智能,速度-")
y3 = model.most_similar([u'智能', u'速度'], [u'计算机'], topn=3)
for item in y3:
    print(item[0], item[1])

 

3.2存储和加载模型

存储、加载模型可以在加载模型之后继续使用句子来进一步训练模型。存储、加载模型的方法如下:

 

3.3实验

本文进行了两项实验,一个是计算两个词的相似度/相关程度,另一个是通过给定的词语序列关系去寻找其它词语间的对应关系。本文计算了“陕西省”和“山西省”的相关程度,并且给定(计算机-智能,速度-)这样的一组关系得到了另一组关系,根据原有预料所训练的模型,实验结果如下如所示,可以看出“山西省”和“陕西省”的相似度很高约为0.954,同时通过给定的关系得出(水资源—降水,明显)这样一组关系

 

 

四. 总结

通过本次实验,了解到神经网络在自然语言中的运用,通过将语言数学化,达到计算机可以识别的地步。向量是人把自然界的东西抽象出来交给机器处理的东西,基本上可以说向量是人对机器输入的主要方式了。在本次试验中用到word2vct工具来计算相似度和寻找对应关系组,Word2vec包换两种语言模型一个是词袋模型另一个是skip-gram模型,但是这里用python进行编程,python版本下只有skip-gram模型,所以本文通过skip-gram来输出词语的权重,即300维的词向量。在输入数据之前,要对数据进行分词处理并去除停用词。模型训练完毕后,保存模型以便后续的使用或者完善。此次试验,加深了我对词向量的理解和运用,对于计算相似度的方法有了新的认识。

 

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

Cuzur

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值