新版Gensim里Word2Vec的相关用法

 好久没用这个包了,新版和旧版有出入,转载的知乎上一篇文章做备忘学习资料使用。

#导入需要的包
import pandas as pd
import csv
import jieba
from pprint import pprint
import gensim


sentence = pd.read_csv("love.txt",header=None,quoting = csv.QUOTE_NONE,delimiter="\n") #读取文件,记住取名不要用中文
sentence.columns = ["内容"]
sentence["内容"] = sentence["内容"].str.replace("\(.*\)","")  #因为括号里有很多作者英文名和年份,去掉这部分的杂树据
sentence = sentence["内容"].tolist() #转换为列表格式

stopwords = pd.read_csv("stop_words_ch.txt",header=None,quoting = csv.QUOTE_NONE,delimiter="\t")
stopwords = stopwords[0].tolist()
stopwords.append("时")  #后面发现还有这几个漏网之鱼,继续加到停用词里去
stopwords.append("一种")
stopwords.append("请")
stopwords.append("●")

sentence_cut = [ " ".join(jieba.lcut(line)) for line in sentence] 
sentence_no_stopwords = [[word for word in line.split() if word not in stopwords] for line in sentence_cut]
from collections import defaultdict
frequency =defaultdict(int)
for line in sentence_no_stopwords:
    for token in line:
        frequency[token] +=1
sentence_morethan1time= [[token for token in line if frequency[token]>3]for line in sentence_no_stopwords]
pprint(sentence_morethan3times) 

频率大于3的词汇

#训练模型
model =gensim.models.Word2Vec(sentence_morethan1time,min_count=2,window=5)  
#min_count是最低出现数,默认数值是5;
#size是gensim Word2Vec将词汇映射到的N维空间的维度数量(N)默认的size数是100;
#iter是模型训练时在整个训练语料库上的迭代次数,假如参与训练的文本量较少,就需要把这个参数调大一些。iter的默认值为5;
#sg是模型训练所采用的的算法类型:1 代表 skip-gram,0代表 CBOW,sg的默认值为0;
#window控制窗口,如果设得较小,那么模型学习到的是词汇间的组合性关系(词性相异);如果设置得较大,会学习到词汇之间的聚合性关系(词性相同)。模型默认的window数值为5;

#重要常用方法
model.wv.key_to_index #1.获得所有词汇组

获得所有词汇

# 得到词的向量
model.wv['爱情']

获取词对应向量

# # 计算两个词之间的余弦相似度
model.wv.similarity('爱情', '疯狂') #0.16419926
model.wv.similarity('爱情', '痛苦') ## 0.35352513
model.wv.similarity('爱情', '迷恋') # 0.178708
model.wv.similarity('爱情', '爱恋') #0.1147006


model.wv.most_similar("爱情")
model.wv.most_similar(positive=["情感","痛苦"],negative=["疯狂"],topn=10) #得出的是第一个是爱人,第二个是激情,第三个是爱情哈哈哈哈,有点悲观
# 如果输入的是model.most_similar(positive=['女人', '先生'], negative=['男人'], topn=1),那得到的应该是类似于女人+先生-男人的结果 

# 找出不太合群的词
model.wv.doesnt_match("疯狂 痛苦 包含".split()) #这个结果是包含,但是我发现有时候另外一些词并不能正确判断,所以估计还是语料库不够大

# 返回与爱情最近的词和相似度
model.wv.similar_by_word("爱情", topn=10, restrict_vocab=30)
# 其中的参数restrict_vocab ,它是可选的整数,它限制了向量的范围,搜索最相似的值。 例如,restrict_vocab = 10000会,只检查词汇顺序中的前10000个词汇向量。

 #查看词向量的维度,109个词汇,维度为100
model.wv.vectors.shape

# 接近词汇A更甚于词汇B接近词汇A的【所有】词汇,按相似度由高到低降序排列
model.wv.closer_than('迷恋','爱情')  #'迷恋'是词汇A,'爱情'是词汇B
#结果是['作用', '一位', '两个'],好像没什么意义哈哈

#给定上下文词汇作为输入,可以获得中心词汇的概率分布
pprint(model.predict_output_word(['痛苦', '疯狂', '狂热'], topn=10))

跟爱情最相关的10个词语

#训练损失计算(Training Loss Computation),当训练Word2Vec模型时,将其中的参数compute_loss设置为True,则可计算训练Word2Vec模型时所得到的损失(Training Loss),它可以衡量模型的训练质量。
# 计算出的损失存储在模型的属性running_trai型本身丢掉,只留下这个词向量的结果

from gensim.models import KeyedVectors

wv = model.wv # 得到训练之后的词向量
del model # 删除占用大内存的model
wv.save('word_vector') # 保存word vectors
loaded_wv = KeyedVectors.load('word_vector', mmap='r') # 加载保存的word vectors

#可视化,还没有学过tsne所以这里还是先用PCA
from sklearn.decomposition import PCA
from matplotlib import pyplot
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签

X = model.wv[words]
pca = PCA(n_components=2)
result = pca.fit_transform(X)
# 可视化展示
pyplot.scatter(result[:, 0], result[:, 1])
for i, word in enumerate(words):
	pyplot.annotate(word, xy=(result[i, 0], result[i, 1]))
pyplot.show()  #有点太丑了,下次再继续精进哈哈

最后为了实验一下增量学习部分,我又去下载亲密关系性爱的这一章来做试验。

class MySentences(object):
  def __init__(self, fname):        
    self.fname = fname 
  def __iter__(self):        
    print('正在处理文件{}'.format(self.fname))
    for line in open(self.fname,'r',encoding='utf-8'):
        yield [word for word in jieba.lcut(line) if word not in stopwords and len(word) > 1]
#我在补充完这一部分之前已经补充了语料库流的内容
#因为只是为了做试验,所以没有做很多预处理内容

old_data = MySentences('love.txt')  #爱情那一章
new_data = MySentences('sex.txt')  #性爱那一章

%%time
oldmodel = Word2Vec(old_data, min_count = 3, window =5)
oldmodel.save('oldmodel')   #保存为旧模型 
#Wall time: 3.03 s

try:   
 print(oldmodel.wv.most_similar('性爱'))
except KeyError as e:    
 print(e)
#因为爱情那一章没有提到性爱这个单词所以这里的结果为没有
#结果为"Key '性爱' not present"

%%time
oldmodel.build_vocab(new_data, update=True) #把新的章节更新进去
oldmodel.train(new_data, total_examples=model.corpus_count, epochs=model.epochs) #进行训练
oldmodel.save('newmodel') #保存为新模型
newmodel = Word2Vec.load('newmodel') #分别导入
oldmodel = Word2Vec.load('oldmodel') 

for m in ['oldmodel', 'newmodel']: 
  print('该', m, '词汇量为', len(eval(m).wv.key_to_index)) #将字符串str当成有效的表达式来求值并返回计算结果
#该 oldmodel 词汇量为 371
#该 newmodel 词汇量为 643,可知更新了的模型词汇量比知道的大多了
#再来重新尝试一下新的模型

try:    
 pprint(newmodel.wv.most_similar('性爱',topn = 20))
except KeyError as e:    
 pprint(e)

性爱相关词汇

w = '爱情'
for m in ['oldmodel', 'newmodel']:
  print('The count of the word,'+w+', is', eval(m).wv.get_vecattr("爱情", "count"), 'in', m)  #获得词频
  pprint(eval(m).wv.most_similar(w,topn = 20))
  print('------------------------------------------------')
#从以下结果其实可以明显看得出已经有了变化

最好参考gensim的官网教学

GitHub - RaRe-Technologies/gensim: Topic Modelling for Humans​github.com/RaRe-Technologies/gensim​编辑

https://github.com/RaRe-Technologies/gensim/wiki/Migrating-from-Gensim-3.x-to-4​github.com/RaRe-Technologies/gensim/wiki/Migrating-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值