使用word2vec训练中文词向量
https://www.jianshu.com/p/87798bccee48
一、文本处理流程
通常我们文本处理流程如下:
- 1 对文本数据进行预处理:数据预处理,包括简繁体转换,去除xml符号,将单词条内容处理成单行数据,word2vec训练原理是基于词共现来训练词之间的语义联系的。不同词条内容需分开训练
- 2 中文分词:中文NLP很重要的一步就是分词了,分词的好坏很大程度影响到后续的模型训练效果
- 3 特征处理:也叫词向量编码,将文本数据转换成计算机能识别的数据,便于计算,通常是转换成数值型数据,常用的编码方式有one hot编码(BOW词袋模型离散表示方式,另外文章我们讲解TF-IDF模型时候会介绍)和基于word2vec等深度学习模型训练得到的低维稠密向量,通常称为word embedding的Distributed representation
- 4 机器学习:词向量进行编码之后,便可以将文本数据转换成数值数据,输入到我们的机器学习模型进行计算训练了
文本处理流程图如下:
文本处理流程
二、训练过程
- 模型:gensim工具包word2vec模型,安装使用简单,训练速度快
- 语料:百度百科500万词条+维基百科30万词条+1.1万条领域数据
- 分词:jieba分词,自定义词典加入行业词,去除停用词
- 硬件:8核16g虚拟机
数据预处理
- 维基百科数据量不够大,百度百科数据量较全面,内容上面百度百科大陆相关的信息比较全面,港澳台和国外相关信息维基百科的内容比较详细,因此训练时将两个语料一起投入训练,形成互补,另外还加入了1.1万公司行业数据
分词
- 1 准备一个停用词词典,训练时要去除停用词的干扰
- 2 分词工具有中科院分词,哈工大的LTP分词,jieba分词,分词效果中科院的分词效果不错,我们直接使用jieba进行分词,使用简单方便,分词速度快
- 3 自定义词典:由于百科数据有很多专属名词,很多比较长,如果直接分词,很大情况下会被切开,这不是我们想要的结果,比如:中国人民解放军,可能会被分成:中国 人民 解放军,jieba虽然有新词发现功能,为保证分词准确度,jieba的作者建议我们还是使用自定义词典。
- 4 自定义词典抽取:我从百度百科抽取了200万的词条,由于自定义词典包含英文单词时会导致jieba对英文单词进行分词,所以需要用正则表达式去除词条中的英文数据,并且去除一些单字词,还有一些词条里面较短词,如"在北京",这类词会导致分词出现问题,也需要使用正则去除,也有简单粗暴的方法,直接保留3个汉字及以上的中文词条,去除之后得到170万大小的自定义词典
- 5 分词过程
# 多线程分词
# jieba.enable_parallel()
#加载自定义词典
jieba.load_userdict("F:/baike_spider/dict/baike_word_chinese")
#加载停用词
def getStopwords():
stopwords = []
with open("stop_words.txt", "r", encoding='utf8') as f:
lines = f.readlines()
for line in lines:
stopwords.append(line.strip())
return stopwords
#分词
def segment():
file_nums = 0
count = 0
url = base_url + 'processed_data/demo/'
fileNames = os.listdir(url)
for file in fileNames:
logging.info('starting ' + str(file_nums) + 'file word Segmentation')
segment_file = open(url + file + '_segment', 'a', encoding='utf8')
with open(url + file, encoding='utf8') as f:
text = f.readlines()
for sentence in text:
sentence = list(jieba.cut(sentence))
sentence_segment = []
for word in sentence:
if word not in stopwords:
sentence_segment.append(word)
segment_file.write(" ".join(sentence_segment))
del text
f.close()
segment_file.close()
logging.info('finished ' + str(file_nums) + 'file word Segmentation')
file_nums += 1
- 由于python多线程只能单核多线程,如果是多核的机器并不能有效使用cpu,jieba是使用python写的,所以jieba只支持并行分词,并行分词指的是多进程分词,并且不支持windows
- 我们在linux试过jieba自带的并行分词,开启并行分词之后,jieba后台会自动开启多个进程,并且并行分词需要一次性将训练语料读取到内存并传入jieba.cut(file.read())中才会有效果,如果类似我代码中逐行传入,开启多进程是不起作用的,jieba多进程原理是,jieba后台会自动将语料切分分配给指定进程处理,分好词后再合并
- 我使用的是8核16g内存Linux虚拟机,发现开启jieba并行分词,1g的语料数据,很快就爆内存了
- 单进程的jieba分词,不需要一次性加载所有语料数据,可逐行读取语料,内存占用不大,运行稳定。因此我们将语料数据分成8份,手动开启8个进程分别分词,这样每个进程内存占用都很稳定,比jieba自带的并行分词性能好,20g的数据,开启HMM模式,分词大概花了10个小时
word2vec训练
- 使用gensim工具包的word2vec训练,使用简单速度快,效果比Google 的word2vec效果好,我自己用tensorflow来跑word2vec模型,16g的内存根本跑不动
gensim word2vec 训练代码如下,非常简答
import logging
import multiprocessing
import os.path
import sys
from gensim.models import Word2Vec
from gensim.models.word2vec import PathLineSentences
if __name__ == '__main__':
program = os.path.basename(sys.argv[0])
logger = logging.getLogger(program)
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
logging.root.setLevel(level=logging.INFO)
logger.info("running %s" % ' '.join(sys.argv))
# check and process input arguments
# if len(sys.argv) < 4:
# print(globals()['__doc__'] % locals())
# sys.exit(1)
# input_dir, outp1, outp2 = sys.argv[1:4]
input_dir = '../baike/segment'
outp1 = 'model/baike.model'
outp2 = 'model/word2vec_format'
fileNames = os.listdir(input_dir)
# 训练模型 输入语料目录 embedding size 256,共现窗口大小10,去除出现次数5以下的词,多线程运行,迭代10次
model = Word2Vec(PathLineSentences(input_dir),
size=256, window=10, min_count=5,
workers=multiprocessing.cpu_count(), iter=10)
model.save(outp1)
model.wv.save_word2vec_format(outp2, binary=False)
# 运行命令:输入训练文件目录 python word2vec_model.py data baike.model baike.vector
- 训练时输入运行命令即可训练,指定语料目录,模型保存目录,embedding工具保存目录
- 由于语料太大,不能一次性加载到内存训练,gensim提供了PathLineSentences(input_dir)这个类,会去指定目录依次读取语料数据文件,采用iterator方式加载训练数据到内存,
- 从训练日志可以看到,其过程是先依次读取每个文件,生成总的vocab词典,用来统计count,训练时用来过滤min_count小于我们制定数量的词,vocab总词典生成后,会依次读入语料进行model训练,训练速度非常快。
模型效果
- 之前使用维基百科数据训练得到模型效果还不错,这次采用更大的语料看下效果,目前还在训练,电脑烤机中,先写到这里,有空继续
作者:sudop
链接:https://www.jianshu.com/p/87798bccee48
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
使用word2vec训练中文词向量的更多相关文章
- 使用 DL4J 训练中文词向量
目录 使用 DL4J 训练中文词向量 1 预处理 2 训练 3 调用 附录 - maven 依赖 使用 DL4J 训练中文词向量 1 预处理 对中文语料的预处理,主要包括:分词.去停用词以及一些根据实 ...
- word2vec 构建中文词向量
词向量作为文本的基本结构——词的模型,以其优越的性能,受到自然语言处理领域研究人员的青睐.良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,本文 ...
- AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法
AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法 2018-01-18 16:13蚂蚁金服/雾霾/人工智能 导读:词向量算法是自然语言处理领域的基础算法,在序列标注.问答系统和机 ...
- 在Keras模型中one-hot编码,Embedding层,使用预训练的词向量/处理图片
最近看了吴恩达老师的深度学习课程,又看了python深度学习这本书,对深度学习有了大概的了解,但是在实战的时候, 还是会有一些细枝末节没有完全弄懂,这篇文章就用来总结一下用keras实现深度学习算法的 ...
- 开源共享一个训练好的中文词向量(语料是维基百科的内容,大概1G多一点)
使用gensim的word2vec训练了一个词向量. 语料是1G多的维基百科,感觉词向量的质量还不错,共享出来,希望对大家有用. 下载地址是: http://pan.baidu.com/s/1boPm ...
- Windows下基于python3使用word2vec训练中文维基百科语料(二)
在上一篇对中文维基百科语料处理将其转换成.txt的文本文档的基础上,我们要将为文本转换成向量,首先都要对文本进行预处理 步骤四:由于得到的中文维基百科中有许多繁体字,所以我们现在就是将繁体字转换成简体 ...
- gensim的word2vec如何得出词向量(python)
首先需要具备gensim包,然后需要一个语料库用来训练,这里用到的是skip-gram或CBOW方法,具体细节可以去查查相关资料,这两种方法大致上就是把意思相近的词映射到词空间中相近的位置. 语料库t ...
- Windows下基于python3使用word2vec训练中文维基百科语料(三)
对前两篇获取到的词向量模型进行使用: 代码如下: import gensim model = gensim.models.Word2Vec.load('wiki.zh.text.model') fla ...
- 利用 word2vec 训练的字向量进行中文分词
最近针对之前发表的一篇博文<Deep Learning 在中文分词和词性标注任务中的应用>中的算法做了一个实现,感觉效果还不错.本文主要是将我在程序实现过程中的一些数学细节整理出来,借此优 ...
随机推荐
- 20172319 2018.10.12《Java程序设计教程》第6周课堂实践(补写博客)
20172319 2018.10.12 <Java程序设计教程>第6周课堂测验 课程:<程序设计与数据结构> 班级:1723 学生:唐才铭 学号:20172319 指导老师:王 ...
- Codeforces Round #369 (Div. 2) C. Coloring Trees 动态规划
C. Coloring Trees 题目连接: http://www.codeforces.com/contest/711/problem/C Description ZS the Coder and ...
- 使用POI操作PPT文档(插入文本、图片)转
1)如果是创建新的PPT文档,直接使用SlideShow和Slide类就可以,其中SlideShow表示PPT文档,Slide表示某一张幻灯片如下代码创建空的PPT文档: SlideShow ppt ...
- Linux学习笔记04—IP配置
一.自动获取IP只有一种情况可以自动获取IP地址,那就是你的Linux所在的网络环境中有DHCP服务.只要你的真机可以自动获取IP,那么安装在虚拟机的Linux同样也可以自动获取IP. 方法很简单,只 ...
- LPC43xx SGPIO Camera interface design
AN11196: Camera interface design using SGPIO
- USB2.0 速度识别--区分低速-高速-全速
USB2.0是向下兼容USB1.X的,即USB2.0支持高速,全速,低速的USB设备 (HIGH-SPEED,FULL-SPEED,LOW-SPEED),而USB1.X不支持高速设备. 因此如果高速设 ...
- 在CentOS 6 的cron/crontab中使用wine运行exe程序
几个月前服务器的OS从Ubuntu 10.04转为CentOS 6.3,装好wine后手动运行shell脚本可以正常运行指定的exe程序(脚本和Ubuntu中的一样),于是就直接修改crontab定时 ...
- IEnumerable和IQueryable的区别以及背后的ExpressionTree表达式树
关于IEnumerable和IQueryable的区别,这事还要从泛型委托Func<T>说起.来看一个简单的泛型委托例子: class Program { static void Main ...
- WordPress基础:wp_title
使用标题格式:首页(网站标题 - 网站副标题),其他页面(页面标题 | 网站标题) wp_title(分隔符,是否直接显示,分隔符显示在哪里) wp_title用在首页是没效果的,需要自己格式化一下 ...
- Swift:playground
在介绍Playground之前,我先罗列一些本人认为有点重要然而零碎的知识点. 1. Swift语法.每句话之后不用加分号.但也能够加分号.但假设写在一行的话.必须加分号. 2. Swift严格要求变 ...
