写在前面
本来是想写“实战篇”的,感觉实验语料库不大,就算是一个"应用篇"吧。选取了中文语料,主要简单介绍jieba分词的使用,以及Gemsim模块中Word2Vec的使用。word2vec的原理可以参考之前的文章:华夏狼崽:word2vec学习笔记(原理篇)zhuanlan.zhihu.com
一、语料介绍
一直比较喜欢金庸的武侠小说,所以语料选取了金庸的十五部小说(精校版),最初的项目中只训练了一部《射雕英雄传》,内容太少不够爽,可以分析的关系也不多,所以一次性训练了十五部小说,看是否能得到不同小说之间一些人物、门派、武功的关系。
二、文本预处理
要训练词向量,首先就要得到词,原始的数据都是完整的文本、句子,怎样得到词语呢?这里用到一个很好用的模块:jieba。jieba模块是一个python中文分词模块,可以将输入的句子分为词语,有三种分词方式:精准模式,全模式和搜索引擎模式。安装方法和更细节的使用方式这里不做介绍,可以参考jieba的官方github:fxsjy/jieba
1. 导入jieba模块和其他相关模块并加载文件路径
import os
import jieba
import warnings
warnings.filterwarnings('ignore')
novel_path = "E:/Learn/WORD2VEC/金庸小说精校版/"
data_path = "E:/Learn/WORD2VEC/"
novel_path为小说原始文本路径,data_path为其他一些文件的路径(下文一一介绍)。
2. 过滤标点以及停用词
在分词中,标点符号是我们不需要的。还有一类词,是训练词向量时不需要的,这些词单独出现没有什么具体意义,比如"的","各位","什么"等等,这一类词称为停用词(stop word)。停用词表的选择需要根据实际应用环境调整,这里我的停用词表下载了网上比较通用的中文语料停用词表,根据词向量训练结果做了一点点调整,添加了几个在武侠小说中容易出现而我并不想得到它的词向量的词,比如"说道"等等。
由于下载的停用词表中包含了标点符号,所以这里可以把标点当作停用词合并一起处理。加载停用词表:
stop_words_file = open(data_path + "stop_words.txt", 'r')
stop_words = list()
for line in stop_words_file.readlines():
line = line.strip() # 去掉每行末尾的换行符
stop_words.append(line)
stop_words_file.close()
print(len(stop_words))
print(stop_words[300:320])
看一下一共几个停用词,抽一些出来随便看看有哪些词:
1903
['乘势', '乘机', '乘胜', '乘虚', '乘隙', '九', '也', '也好', '也就是说', '也是', '也罢', '了', '了解', '争取', '二', '二来', '二话不说', '二话没说', '于', '于是']
停用词表加载完毕,后面只需判断分出的词是否在表里即可,如果在表里则舍弃不要。
3. 添加自定义词汇
最开始的实验中,我是直接分词的,但是发现,很多想要的词汇都没能正确的分出来,包括一些重要人物的名称,一些重要的武功等,是因为这些词汇都是武侠小说这种特定环境下的专有名词,jieba的词汇表中并没有收录,所以我整理了三份txt文本,分别记录了武侠小说中的人物名称、武功名称和门派名称,参考来源:金庸网-金庸数据库。
将人名添加到词汇表中:
people_names_file = open(data_path + "金庸小说全人物.txt", 'r')
people_names = list()
for line in people_names_file.readlines():
line = line.strip() # 去掉每行末尾的换行符
jieba.add_word(line)
people_names.append(line)
stop_words_file.close()
print(len(people_names))
添加的人名数量:
1237
类似的,导入了389个武功名称和97个门派名称。
4. 分词
分词本来我以为是没有什么的,直接用精确模式逐本逐行的分就好了。实际操作时遇到了一点小问题。先看一下文件名:
novel_names = list(os.listdir(novel_path))
novel_names
输出: