python词嵌入_文本向量系列-词嵌入理论和实践

系列文章

这个是系列博客, 所有文章链接都列在这里, 并持续更新中。

概念

神经网络的词向量表示法是基于一个哲学: 词的上下文环境决定了词的意义, 所以在训练词向量的时候, 是通过词的上下文来计算词向量, 因而这样的词向量也具有了上下文的语义信息。

基于神经网络生成的词表示一般称为词向量、词嵌入(wordembeding),狭义上,与分布表示(distributional representation)相对,也称为分布式表示(distributed representation)。该表示将每一单词映射到一个低维、稠密的实数向量上,向量的每一维代表单词的潜在特征,且该特征能够捕捉到有用的语法和语义属性。词向量的最大优势在于我们可以相对快速、有效地根据向量间的距离(比如余弦距离)判断单词的相似性,原因在于语义或语法相似的单词拥有相似的向量表示。词向量的构建主要依赖于神经网络模型,神经网络能够非常灵活地以线性组合方式表示任意n-gram词组,且参数以线性速度増长,相对于基于矩阵和聚类的分布表示,词向量能够捕捉到更多复杂、有用的语义信息。

word2vec

深度学习word2vec是Google的一款将词表征为实数值向量的高效工具, 其利用深度学习的思想, 通过训练把对文本内容的处理简化为K维向量空间中的向量运算, 而向量空间上的相似度可以用来表示文本语义上的相似度。在实际应用场景中, word2vec可以用于计算词的相似度、文档的相似度等, 也可以用来对文档进行情感分析等。

深度学习word2vec中有CBOW和Skip-gram两种神经网络框架可用于训练并得到参数, 参数迭代更新后得到的就是每个字的词向量。其中, CBOW模型是利用词wt上下文中的c个词去预测当前词;而Skip-gram模型恰好相反, 它是利用词wt去预测上下文中的c个词。本文采用CBOW架构训练模型, 其数学表达式为:

其中, wt为词典D中的一个词, 即通过和该词相邻的窗口T来预测wt出现的概率。p (wt/Contexti) 代表前后c个词出现的概率。该框架可表示为下图所示模型。

上述符号中, INPUT代表输入层, PROJECTION代表投影层, OUTPUT代表输出层, wt代表当前词语 (向量) , wt-2、wt-1、wt+1、wt+2代表当前词语的上下文, SUM代表上下文的累加和。输出层是以词典D中出现过的N个词作为叶节点, 并以词在语料库中出现的次数作为权值构造出的巨大二叉树, 该二叉树的构建算法为霍夫曼 (Huffman) 树。

训练流程把word表示成one-hot向量

one-hot词向量乘以W得到embeding的词向量

W的形状是VxN, 其中V是语料库的词典大小, N是词向量的维度, W中的数都是我们要训练的参数

训练神经网络, 输入是目标词的上下文的词向量, 输出是目标词的词向量, 或者相反

词向量相加:

乘以权重矩阵, 得到向量

经过softmax函数, 得到输出的词向量y, 优化目标是让向量y无限接近目标词的one-hot向量

最后的效果就是, 得到的词向量具有语义相关, 这些词向量其实都是嵌入在权重向矩阵W中的

实战:使用word2vec训练词向量

其实在这里有一篇文章已经非常详细的介绍了词向量的训练, 有兴趣的可以去看看:http://mlln.cn/2018/06/21/大数据揭示心理学规律(利用gensim训练词向量) 。这里只是为了文章完整性, 再演示一遍如何使用word2vec训练词向量。

语料库

这次我们使用中英文语料库, 语料库可以从这里下载:机器翻译语料库大全(免费下)), 我这里用的是中英文翻译语料, 下面是一些语料的例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16Hi.嗨。

Hi.你好。

Run.你用跑的。

Wait!等等!

Hello!你好。

I try.让我来。

I won!我赢了。

Oh no!不会吧。

Cheers!乾杯!

He ran.他跑了。

Hop in.跳进来。

I lost.我迷失了。

I quit.我退出。

I'm OK.我沒事。

Listen.听着。

No way!不可能!

这些语料需要经过一些处理才能进行训练:

英文都转小写

中文需要分词

中文分词有很多工具可以用, tcharacters 模块是我们自己开发的, 利用了pyltp的分词功能, 大家可以访问这个页面(http://www.mlln.cn/2018/01/31/pyltp在windows下的编译安装/ )看pyltp的用法, 我这里就不再赘述。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23from tcharacters.ltp import ltp

from pathlib import Path

from itertools import chain

from gensim.models import Word2Vec

def fenci(line):

ci = ltp.fenci(line)

ci = chain(*ci)

return list(ci)

def xiaoxie(line):

return line.lower().split(' ')

def clean_data(fpath):

fpath = Path(fpath)

lines = fpath.read_text('utf8').split('\n')

lines = [l.split('\t') for l in lines]

lines = [xiaoxie(l[0])+fenci(l[1]) for l in lines]

return lines

print("测试分词:", fenci('我跳进来没事了'))

print("测试小写:", xiaoxie("I'm OK"))

输出(stream):

d:\mysites\deeplearning.ai-master\.env\lib\site-packages\gensim\utils.py:1197: UserWarning: detected Windows; aliasing chunkize to chunkize_serial

warnings.warn("detected Windows; aliasing chunkize to chunkize_serial")

输出(stream):

测试分词: ['我', '跳', '进来', '没事', '了']

测试小写: ["i'm", 'ok']

读取数据1

2fpath = './data/cmn.txt'

sentences = clean_data(fpath)

训练词向量1

2

3model = Word2Vec(min_count=1)

model.build_vocab(sentences) # prepare the model vocabulary

model.train(sentences, total_examples=model.corpus_count, epochs=model.iter) # train word vectors

输出(stream):

d:\mysites\deeplearning.ai-master\.env\lib\site-packages\ipykernel_launcher.py:3: DeprecationWarning: Call to deprecated `iter` (Attribute will be removed in 4.0.0, use self.epochs instead).

This is separate from the ipykernel package so we can avoid doing imports until

输出(plain):

(1053714, 1354925)

获取词向量1

2model['我']

输出(stream):

d:\mysites\deeplearning.ai-master\.env\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: Call to deprecated `__getitem__` (Method will be removed in 4.0.0, use self.wv.__getitem__() instead).

"""Entry point for launching an IPython kernel.

输出(plain):

array([-0.3515351 , -1.3118509 , -0.6156184 , 0.15516779, 1.1383128 ,

-0.07251779, 0.23020045, -0.52926725, -0.76866174, -1.0467764 ,

-0.31507614, -0.15950103, -0.52083683, -0.36872956, -0.8011314 ,

0.4902281 , -0.5143664 , 0.3182344 , 0.8374854 , -0.3608164 ,

0.03827107, 0.406259 , 0.43838248, 0.21362059, 0.8257452 ,

-0.5523492 , 0.45621607, -0.8586342 , 1.0493718 , 0.11673231,

0.53156763, 0.01687986, 0.29621682, 0.13253698, 0.64017475,

-0.33693016, -0.7375661 , -0.7472176 , 0.8874524 , 0.5582712 ,

-0.89976597, 0.1379873 , 0.17002319, -1.0449922 , 0.23068163,

0.33250892, 0.13288185, -0.3183722 , 0.18426847, 0.31564566,

-0.17929862, -0.36949784, 0.4063392 , -0.38051793, 1.1805166 ,

0.40641445, -0.77273184, 1.2720692 , -0.04576248, -0.02152266,

-0.33833855, -0.59893143, 0.7793325 , 0.6381986 , -0.7024244 ,

0.03128409, -0.18902263, -0.14734915, 1.2367837 , -0.1975445 ,

0.02902468, 0.3363272 , 0.73686606, -0.05201327, -0.33830413,

0.6940766 , 0.10825578, 0.04985462, 0.20522375, -0.07374723,

0.31967226, 0.9696962 , -1.058341 , 1.0477684 , -0.47876847,

1.7466705 , 0.8541186 , 0.63398683, -0.48192078, 0.3477193 ,

0.05898082, -0.76784873, 0.5714927 , -0.16609748, -0.4489299 ,

-0.55590814, 0.4317831 , 0.38580045, -1.0079336 , -0.6381117 ],

dtype=float32)

获取相近的词1model.wv.similar_by_word('我', topn=20)

输出(plain):

[('汤姆', 0.9596410989761353),

('湯姆', 0.9314063787460327),

('我們', 0.8994365930557251),

('understand.', 0.895287811756134),

('說謊', 0.8948416709899902),

('擺脫', 0.8923969864845276),

('我们', 0.8902699947357178),

('明白', 0.8879507780075073),

('当然', 0.8863658905029297),

('feelings.', 0.8862991333007812),

('让', 0.8845858573913574),

('喜', 0.8840827941894531),

('肯定', 0.8825405240058899),

('有时', 0.8797551989555359),

('讓', 0.8797382116317749),

('記', 0.8793071508407593),

('korea.', 0.8779969811439514),

('不', 0.8774625062942505),

('样子', 0.8769326210021973),

('喜歡狗', 0.8766648173332214)]

词向量的可视化

先把数据保存到文件中

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15import numpy as np

data = np.zeros((len(model.wv.vocab), 100))

i = -1

words = []

for word in model.wv.vocab:

i += 1

data[i] = model[word]

words.append(word)

tsv_path='./data/wordvec.tsv'

np.savetxt(tsv_path, data, delimiter='\t')

words = '\n'.join(words)

# words = '词\n' + words

with open('./data/words.tsv', 'w', encoding='utf8') as f:

f.write(words)

输出(stream):

d:\mysites\deeplearning.ai-master\.env\lib\site-packages\ipykernel_launcher.py:7: DeprecationWarning: Call to deprecated `__getitem__` (Method will be removed in 4.0.0, use self.wv.__getitem__() instead).

import sys

上传刚才生成的数据文件, 不必担心数据泄密, 因为这里所有的数据都只是上传到了网页, 并没有回传到服务器, 数据只存在于你的电脑。

注意

本文由jupyter notebook转换而来, 您可以在这里下载notebook

有问题可以直接在下方留言

或者给我发邮件675495787[at]qq.com

请记住我的网址: mlln.cn 或者 jupyter.cn

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值