训练词向量实战

一曲冷凌霜 提交于 2020-02-21 19:18:08

基于gensim训练中文词向量

数据集

下载中文维基百科数据[维基百科数据链接](https://dumps.wikimedia.org/zhwiki/),在该目录下选择最新的数据,我下载的是zhwiki-latest-pages-articles.xml.bz2,数据比较难下,附上百度云盘链接

创建环境

conda install -n python35 python=3.5  #创建python35环境
conda install -n python35 jieba  #安装jieba分词工具
conda install -n python35 gensim  #安装gensim
conda install -n python35 hanziconv #安装hanziconv繁体->简体

实验步骤

  1. 获取语料
#文档根目录
ROOT_DIR = os.getcwd()
DATA_PATH = os.path.join(ROOT_DIR, "data")
MODEL_PATH = os.path.join(ROOT_DIR, "model")
#创建路径
wiki_articles_xml_file=os.path.join(DATA_PATH,"zhwiki-latest-pages-articles.xml.bz2")
wiki_txt_file=os.path.join(DATA_PATH,"wiki_txt")

#使用gensim.WikiCorpus来读取wiki xml中方的corpus
wiki_corpus=WikiCorpus(wiki_articles_xml_file,dictionary={})

#迭代取出词汇,写入到wiki_txt中
with open(wiki_txt_file,'w',encoding='utf-8')as fp:
    text_count=0  #文章数量计数
    for text in wiki_corpus.get_texts():
        fp.write(''.join(text)+'\n')
        text_count+=1
        if text_count%10000 ==0:
            print("目前已经处理了%d篇文章"%text_count)
print("共处理了%d篇文章"%text_count)

执行后截图
在这里插入图片描述
处理后的数据样式
在这里插入图片描述
2. 处理语料
定义了一个求文本行数的函数

#求文件有多少行
def get_num_lines(file_path):
    fp=open(file_path,'r+')
    buf=mmap.mmap(fp.fileno(),0)
    #mmap是一种虚拟内存映射文件的方法,即可以将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系
    lines=0
    while buf.readline():
        lines+=1
    return lines

繁体转化成简体,写入到路径wiki_txt_sf,得到wiki_txt_s.txt文件

#进行繁体转简体
wiki_txt_sf=os.path.join(DATA_PATH,"wiki_txt_s.txt")
wiki_txt_s=open(wiki_txt_sf,"w",encoding="utf-8")
with open(wiki_txt_file,"r",encoding="utf-8")as fp:
    for line in tqdm(fp,total=get_num_lines((wiki_txt_file))):#设置进度条
        wiki_txt_s.write(HanziConv.toSimplified(line))
print("成功转换成简体")
wiki_txt_s.close()

加载停用词表,得到stopwords

#加载停用词词表
stop_word_file=os.join(ROOT_DIR,"stopwords.txt")
#stopword字词集
stopwordset=set()
#读取stopword词典,保存在stopwordset中
with open(stop_word_file,'r',encoding='utg-8')as stopwords:
    for stopword in stopwords:
        stopwordset.add(stopword.strip('\n'))

进行分词,剔除掉停用词,得到wiki_seg.txt文件

#分词
wiki_seg_file=os.path.join(DATA_PATH,"wiki_seg.txt")
wiki_seg=open(wiki_seg_file,"w",encoding="utf-8")
with open(wiki_txt_sf,"r",encoding="utf-8")as f:
    for sentence in tqdm(f,total=get_num_lines(wiki_txt_sf)):
        sentence=sentence.strip("\n")#去掉转行
        pos =jieba.cut(sentence,cut_all=False)
        for item in pos:
            if item not in stopwordset:#若不是停用词,则加入wiki_seg中
                wiki_seg.write(item+" ")
print("jieba分词结束,并且过滤了停用词")
wiki_txt_sf.close()
  1. 训练模型
#训练词向量
print("word2vec模型训练中。。。")
#加载文件
sentence=word2vec.Text8Corpus(wiki_seg_file)
#模型参数
#min_count:若这个词出现的次数小于min_count,那他就不会被视为训练对象
#workers:线程数目,建议别超过 4
#window:还记得孔乙己的例子吗?能往左往右看几个字的意思
#sg:sg=1表示采用skip-gram,sg=0 表示采用cbow
model=word2vec.Word2Vec(sentence,size=300,windows=10,min_count=5,works=4,sg=1)
#保存模型
word2vec_model_file=os.path.join(MODEL_PATH,"wiki_word2vec.model")
model.wv.save_word2vec_format(word2vec_model_file,binary=True)
print("word2vec模型存储完毕")
  1. 测试模型
    –求和“校长”这个词相似的前五个词
    –求两个词“爸爸”“妈妈”之间的相似度
保存为二进制的词向量
word_vectors = KeyedVectors.load_word2vec_format(word2vec_model_file, binary = True)
print("词汇相似词前 5 排序")
query_list=['校长']
res = word_vectors.most_similar(query_list[0], topn = 5)
for item in res:
    print(item[0] + "," + str(item[1]))

print("计算2个词汇间的 Cosine 相似度")
query_list=['爸爸','妈妈']
res = word_vectors.similarity(query_list[0], query_list[1])
print(res)

参考:NLP词向量实战

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!