Python的gensim库可以训练和使用word2vec模型,R语言中也有与之对应的word2vec包
。word2vec是词嵌入技术中最常用的一种技术,如果对词嵌入不太了解,可以阅读前文
本文需要的R包
install.packages(c("word2vec", "jiebaR", "tidyverse", "readtext"))
word2vec包常用函数
- word2vec 使用文本数据训练word2vec模型
- as.matrix 获取词向量
- doc2vec 获取文档向量
- predict 获取
- write.word2vec 保存word2vec模型至文件
- read.word2vec 读取word2vec模型文件
准备数据
原始数据是从网站下载的 三体.txt
, 未分词处理,现在需要
- 读中文取txt数据
- 保留标点符号,进行分词处理
- 分词结果重新整理为类似英文(空格间隔词语的形式)字符串
- 结果存入新的txt
library(jiebaR)
library(tidyverse)
library(word2vec)
#导入数据
tri_body <- readtext::readtext('data/三体.txt')$text
#分词(保留标点符号)
tokenizer <- worker(symbol=T)
tri_words <- segment(tri_body, tokenizer)
# 整理为英文格式(词语之间加空格)
segmented_text <- stringr::str_c(tri_words, collapse = " ") %>% c()
#写入txt
readr::write_file(segmented_text, file='data/santi.txt')
训练word2vec模型
word2vec(
x,
type = c("cbow", "skip-gram"),
dim = 50,
window = ifelse(type == "cbow", 5L, 10L),
iter = 5L,
lr = 0.05,
min_count = 5L,
split = c(" \n,.-!?:;/\"#$%&'()*+<=>@[]\\^_`{|}~\t\v\f\r", ".\n?!"),
stopwords = character(),
threads = 1L,
...
)
- x 英文文本数据txt文件(中文数据txt文件是分词后的txt文件,空格间隔词语)
- type 训练方式,默认CBOW
- dim 词向量维度,默认50维
- window 词向量窗口,默认5
- iter 训练迭代次数,默认5
- split 分词、分句对应的分隔符。
- lr 学习率,默认0.05
- min_count 词语在语料中至少要出现5次(低于5次的词语,训练好的结果中没有该词语)
- stopwords 停用词表,默认空字符集
- threads 并行加速,cpu核数,默认1。为了加速训练过程,可以使用
parallel::detectCores()
获得本电脑的核数
#训练10维的词向量模型
model <- word2vec(x = 'data/santi.txt',
dim = 10,
iter = 20,
split = c(" ", "。?!;"),
threads = parallel::detectCores()) #并行,使用cpu多核加速
emb <- as.matrix(model)
#显示6个词
head(emb)
## [,1] [,2] [,3] [,4] [,5] [,6]
## 煮 -1.02566934 -0.9271542 -0.42417252 -0.54280633 1.8847700 0.41640753
## 报 -0.83992052 1.9440031 0.09093992 0.83522910 1.7909089 0.72149992
## 悬空 -0.06369513 -1.3519955 -2.13137460 -0.06198586 0.6096401 1.32933748
## 略 1.74687469 -0.4278547 -0.33822438 1.08505321 2.0168977 -0.07693915
## 伏 -0.68947995 -1.4147453 -1.95522511 -0.39963767 0.5269030 0.30352208
## 石柱 -0.40561640 -1.3643234 0.30329546 -0.94012892 2.1579018 0.79654717
## [,7] [,8] [,9] [,10]
## 煮 -1.1708908 -0.7624418 -0.6275516 1.2417521
## 报 0.5235919 0.8448864 -0.2960095 -0.0773837
## 悬空 0.1527163 -0.1337370 -0.1646384 1.1892601
## 略 -0.3246748 -0.9813624 0.5045205 0.2771466
## 伏 0.3166684 -1.4238008 -1.0167172 -0.0976937
## 石柱 0.2237919 0.6933151 0.7412233 -0.7918702
查看某词的vector
查看词语 汪淼
的vector
emb["汪淼",]
## [1] -0.77559733 -0.90021265 0.66555792 -0.10277803 1.89924443 -0.88817298
## [7] -1.32665634 -0.75938725 -0.09628224 1.18008399
查看词语 地球
的vector
emb["地球",]
## [1] 0.29645494 -0.61688840 0.91209215 -0.64530188 0.62816381 -0.72807491
## [7] 0.50655973 2.38137436 1.19238114 -0.09610342
predict()
找到语料中,词语 罗辑
最相似的 20个词
predict(model, '罗辑', type='nearest', top_n = 20)
## $罗辑
## term1 term2 similarity rank
## 1 罗辑 胡文 0.9744400 1
## 2 罗辑 申玉菲 0.9678891 2
## 3 罗辑 瓦季姆 0.9550550 3
## 4 罗辑 狄奥伦娜 0.9518393 4
## 5 罗辑 蓝西 0.9472395 5
## 6 罗辑 护士 0.9471439 6
## 7 罗辑 法扎兰 0.9458703 7
## 8 罗辑 白艾思 0.9451101 8
## 9 罗辑 坎特 0.9396626 9
## 10 罗辑 白蓉 0.9387447 10
## 11 罗辑 参谋长 0.9377206 11
## 12 罗辑 弗雷斯 0.9369408 12
## 13 罗辑 第一眼 0.9357565 13
## 14 罗辑 父亲 0.9350463 14
## 15 罗辑 多少次 0.9314436 15
## 16 罗辑 门去 0.9291503 16
## 17 罗辑 维德 0.9267251 17
## 18 罗辑 褐蚁 0.9203902 18
## 19 罗辑 刚 0.9200501 19
## 20 罗辑 吴岳 0.9191605 20
查看均值向量(多个词向量中心的)的10个近义词
vectors <- emb[c("汪淼", "罗辑", "叶文洁"), ]
centroid_vector <- colMeans(vectors)
predict(model, centroid_vector, type = "nearest", top_n = 10)
## term similarity rank
## 1 罗辑 0.9185568 1
## 2 狄奥伦娜 0.9104245 2
## 3 文洁 0.9088279 3
## 4 汪淼 0.9054156 4
## 5 白艾思 0.9046930 5
## 6 张翔 0.9026827 6
## 7 尴尬 0.8952187 7
## 8 庄颜 0.8952166 8
## 9 皇帝 0.8949283 9
## 10 父亲 0.8915347 10
doc2vec()
- doc2vec(object, newdata, split = ” “)
- object word2vec模型对象
- newdata 文档列表(用空格间隔的字符串列表)
- split 默认分隔符是空格
将文档转为向量
docs <- c("哦 , 对不起 , 汪 教授 。 这是 我们 史强 队长 。",
" 丁仪 博士 , 您 能否 把 杨冬 的 遗书 给 汪 教授 看 一下 ? ")
doc2vec(object=model, newdata = docs, split=' ')
## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,] -1.1769752 -0.1065619 0.1983950 1.734068 0.5478012 -0.8320528 -0.2387014
## [2,] -0.4827189 0.0664595 -0.2119484 1.895074 0.6729840 -0.3008853 -0.6857539
## [,8] [,9] [,10]
## [1,] -0.5519856 -2.007002 0.4182127
## [2,] -0.5976922 -2.130454 -0.4653725
保存word2vec模型
保存模型,一般有两个目的
- 为了分享word2vec模型
- 避免反复训练模型,节约数据分析时间
word2vec::write.word2vec(x = model,
#新建output文件夹,将模型存入output文件夹内
file = "output/santi_word2vec.bin")
## [1] TRUE
导入预训练模型
导入 output/santi_word2vec.bin
的预训练word2vec模型
pre_trained_model <- word2vec::read.word2vec(file = "output/santi_word2vec.bin")
pre_trained_emb <- as.matrix(pre_trained_model)
head(pre_trained_emb)
## [,1] [,2] [,3] [,4] [,5] [,6]
## 回荡 -1.9563367 -0.3099073 -1.2969902 -0.5719763 1.1507142 -0.05515177
## 听证会 0.2756990 1.3702289 -1.3303705 -0.1827691 0.6622804 -1.92008448
## 纲领 0.4495552 1.9311246 -0.5812275 -0.1470096 -0.2678985 -0.01694358
## 很亮 0.3621844 -1.0048453 0.7036168 -2.0917876 0.6459805 1.18436253
## 秒 1.9033701 1.6510324 -0.2616904 0.3671210 1.0618066 0.06588747
## 杰森 -1.2904713 -1.2501229 0.3380587 0.8590797 1.6798494 -0.58775252
## [,7] [,8] [,9] [,10]
## 回荡 1.1082711 -0.2064489 -0.9264346 -0.7816723
## 听证会 -1.0952694 0.6120903 -0.1326561 0.7252344
## 纲领 -0.6097277 2.1051276 -0.2405726 -0.8808851
## 很亮 0.1964065 -1.3926132 -0.4042619 -0.1645472
## 秒 -0.8347995 0.2591044 0.3594093 1.1929117
## 杰森 0.4941484 -1.1393189 -0.4687541 0.9951217