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训练中文词向量的更多相关文章

  1. 使用 DL4J 训练中文词向量

    目录 使用 DL4J 训练中文词向量 1 预处理 2 训练 3 调用 附录 - maven 依赖 使用 DL4J 训练中文词向量 1 预处理 对中文语料的预处理,主要包括:分词.去停用词以及一些根据实 ...

  2. word2vec 构建中文词向量

    词向量作为文本的基本结构——词的模型,以其优越的性能,受到自然语言处理领域研究人员的青睐.良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,本文 ...

  3. AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法

    AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法 2018-01-18 16:13蚂蚁金服/雾霾/人工智能 导读:词向量算法是自然语言处理领域的基础算法,在序列标注.问答系统和机 ...

  4. 在Keras模型中one-hot编码,Embedding层,使用预训练的词向量/处理图片

    最近看了吴恩达老师的深度学习课程,又看了python深度学习这本书,对深度学习有了大概的了解,但是在实战的时候, 还是会有一些细枝末节没有完全弄懂,这篇文章就用来总结一下用keras实现深度学习算法的 ...

  5. 开源共享一个训练好的中文词向量(语料是维基百科的内容,大概1G多一点)

    使用gensim的word2vec训练了一个词向量. 语料是1G多的维基百科,感觉词向量的质量还不错,共享出来,希望对大家有用. 下载地址是: http://pan.baidu.com/s/1boPm ...

  6. Windows下基于python3使用word2vec训练中文维基百科语料(二)

    在上一篇对中文维基百科语料处理将其转换成.txt的文本文档的基础上,我们要将为文本转换成向量,首先都要对文本进行预处理 步骤四:由于得到的中文维基百科中有许多繁体字,所以我们现在就是将繁体字转换成简体 ...

  7. gensim的word2vec如何得出词向量(python)

    首先需要具备gensim包,然后需要一个语料库用来训练,这里用到的是skip-gram或CBOW方法,具体细节可以去查查相关资料,这两种方法大致上就是把意思相近的词映射到词空间中相近的位置. 语料库t ...

  8. Windows下基于python3使用word2vec训练中文维基百科语料(三)

    对前两篇获取到的词向量模型进行使用: 代码如下: import gensim model = gensim.models.Word2Vec.load('wiki.zh.text.model') fla ...

  9. 利用 word2vec 训练的字向量进行中文分词

    最近针对之前发表的一篇博文<Deep Learning 在中文分词和词性标注任务中的应用>中的算法做了一个实现,感觉效果还不错.本文主要是将我在程序实现过程中的一些数学细节整理出来,借此优 ...

随机推荐

  1. Springboot 线程池配置

    最近的项目里要手动维护线程池,然后看到一起开发的小伙伴直接用Java了,我坚信Springboot不可能没这功能,于是查了些资料,果然有,这里给一下. 首先我们都知道@Async标签能让方法异步执行, ...

  2. div光标

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  3. 《Go学习笔记 . 雨痕》类型

    一.基本类型 清晰完备的预定义基础类型,使得开发跨平台应用时无须过多考虑符合和长度差异. 类型 长度 默认值 说明 bool 1 false   byte 1 0 uint8 int, uint 4, ...

  4. centos安装tomcat7

    转自:http://www.cnblogs.com/sixiweb/archive/2012/11/26/2789458.html 安装tomcat7: tomcat7下载主页: http://tom ...

  5. Snmp学习总结系列——开篇

    进入公司以来,一直参与到公司的产品研发工作当中去,在产品研发中有一个监控远程服务器CPU使用率,内存使用情况,硬盘的需求,技术总监提出了使用Snmp协议作为远程监控的技术解决方案,头一次听说Snmp这 ...

  6. AngularJS使用angular-formly进行表单验证

    当验证表单中有很多字段时,这时候可能希望把html的生成以及验证逻辑放到controller中,在页面,也许是这样的: <some-form fiedls="vm.someFields ...

  7. .net连mysql数据库汇总

    另外MySql官方出了一个在csharp里面连接MySql的Connector,可以试试 http://dev.mysql.com/downloads/#connector-net <add n ...

  8. ios测试宏指令出错:“Expected identefier”

    写了一个简单的测试宏指令,然后在下面代码中报错,不知道怎么修复?谢谢 #define test(condition) do{\ if (condition) {\ //// <-----Expe ...

  9. 培养iOS开发新人的一个思路

    坚持两个方法论: 1.发现问题的方法:(熟悉代码的过程) (1)照着一个完整的工程,从最基本的页面开始做起.不懂的地方就问,就查. (2)在阅读代码或拿到需求后要学会对问题进行分解.一个陌生的问题如果 ...

  10. java 8 stream特性

    在Java 8的新功能特性中,最棒的特性就是允许我们去表达我们想要完成什么而不是要怎样做.这正是循环的不足之处.要确保循环的灵活性是需要付出代价的.return.break 或者 continue都会 ...