Word2Vec训练模型计算词向量
加载text文件,对文件里面的文字进行分词,先进行停用词的处理,然后计算词频,用Word2Vec训练模型计算词向量,最后词向量可视化。
加载停用词
with open('stopwords.txt', encoding='utf-8') as f:
line_list = f.readlines()
stopword_list = [k.strip() for k in line_list]
stopword_set = set(stopword_list)
加载用于处理的文本,去除停用词,然后用dict.get
方法进行词频统计并排序
raw_word_list = []
di = {}
with open('第一章.txt','r',encoding = 'utf-8') as f:
line = f.readline()
while line:
if '\n' in line:
line = line.replace('\n','')
if ' ' in line:
line = line.replace(' ','')
if len(line)>0:
new_raw_words = []
raw_words = jieba.lcut(line,cut_all=False)
for word in raw_words:
if word not in stopword_set: # 去除停用词
new_raw_words.append(word)
di[word] = di.get(word,0)+1 # 词频统计
raw_word_list.append(new_raw_words)
line = f.readline()
d_order = sorted(di.items(),key=lambda x:x[1],reverse = True) # 排序
导入库训练模型根据词频统计结果设置min_count
值,出现次数小于1的词省略,size
控制输出词向量的维度大小,window
是当前词与预测词之间的最大距离
#训练模型
from gensim.models import Word2Vec
model = Word2Vec(raw_word_list,min_count=1, size=300, window=10,sg=1)
# min_count词频小于1的不会加入训练中去
# size词向量大小
训练出的模型可以进行增量训练,也就是在已有模型的基础上传入新的词并计算词向量。
同样,对要新增的文章进行分词和停用词的处理。
raw_word_list_2 = []
with open('第二章.txt','r',encoding = 'utf-8') as f:
line = f.readline()
while line:
if '\n' in line:
line = line.replace('\n','')
if ' ' in line:
line = line.replace(' ','')
if len(line)>0:
new_raw_words = []
raw_words = jieba.lcut(line,cut_all=False)
for word in raw_words:
if word not in stopword_set:
new_raw_words.append(word)
raw_word_list_2.append(new_raw_words)
line = f.readline()
更新词汇表
model.build_vocab(raw_word_list_2,update=True)
增量训练 ,在已有模型的基础上添加词 ,total_examples
为句子数,epochs为迭代次数
model.train(raw_word_list_2, total_examples = model.corpus_count, epochs = model.iter)
可视化
现将所有词向量放入一个list中形成一个二维数组
word_vec = []
for i in model.wv.index2word:
word_vec.append(model.wv[i])
用TSNE库对每个词向量进行降维,因为要在二维的坐标系中显示每个词的位置,然而每个词向量的长度300,所以长度要降为2
# TSNE降维
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2) # 降为2维
tsne.fit_transform(word_vec) # word_vec每个词的词向量
用matplotlib库画图,其中model.wv.index2word
里存的是训练的每一个词,tsne.embedding_
里是词向量降维的结果相当于是每个词的坐标
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
plt.figure(figsize = (12, 8)) # 画布大小
for i in range(len(tsne.embedding_)):
x = tsne.embedding_[i][0]
y = tsne.embedding_[i][1]
font = FontProperties(fname='C:\\Windows\\Fonts\\SIMLI.TTF',size=12)
plt.scatter(x,y)
plt.annotate(model.wv.index2word[i],xy=(x,y), fontproperties=font)