python gensim训练 word2vec的中文语料格式是什么样的呢?很多经验贴或是忽略了这个地方,或是没有详细说明,此博文详细说明及实践语料的处理方式,并汇总数种语料加载方式。
从文章word2vec词向量训练使用(python gensim)对word2vec的介绍,我们了解到Word2Vec第一个参数sentences要求是是预处理后的训练语料库,需要输入一个可迭代的列表,但是对于较大的语料库,可以考虑直接从磁盘/网络传输句子的迭代。
中文语料处理
如果是句子,需要进行分词
如果是文件,需要将文件处理为每一行对应一个句子(已经分词,以空格隔开),实例处理过程见文末。
法一:语料处理为列表
from gensim.models import Word2Vec sentences = [["Python", "深度学习", "机器学习"], ["NLP", "深度学习", "机器学习"]] model = Word2Vec(sentences, min_count=1)
把Python内置列表当作输入很方便,但当输入量很大的时候,大会占用大量内存。
法二:语料是文件(处理为迭代器)
Gensim需要输入一个可迭代的列表,可以是迭代器,没有必要把一切东西都保存在内存中,提供一个语句,加载处理它,忘记它,加载另一个语句。
一般我们的语料是在文件中存放的,首先,需要保证语料文件内部每一行对应一个句子(已经分词,以空格隔开),方法见上。
对一个目录下的所有文件生效(法1)
这些文件已经被分词好了,如果还需要进一步预处理文件中的单词,如移除数字,提取命名实体… 所有的这些都可以在MySentences 迭代器内进行,保证给work2vec的是处理好的迭代器。
class MySentences(object): def __init__(self, dirname): self.dirname = dirname def __iter__(self): for fname in os.listdir(self.dirname): for line in open(os.path.join(self.dirname, fname)): yield line.split() sentences = MySentences('/some/directory') # a memory-friendly iterator model = gensim.models.Word2Vec(sentences)
对一个目录下的所有文件生效(法2)
class : gensim.models.word2vec.PathLineSentences gensim.models.word2vec.PathLineSentences(source, max_sentence_length=10000, limit=None) Bases: object 作用同下一个类,对一个目录下的所有文件生效,对子目录无效 Works like word2vec.LineSentence, but will process all files in a directory in alphabetical order by filename. 该路径下的文件 只有后缀为bz2,gz和text的文件可以被读取,其他的文件都会被认为是text文件 The directory can only contain files that can be read by LineSentence: .bz2, .gz, and text files. Any file not ending with .bz2 or .gz is assumed to be a text file. Does not work with subdirectories. 一个句子即一行,单词需要预先使用空格分隔 The format of files (either text, or compressed text files) in the path is one sentence = one line, with words already preprocessed and separated by whitespace. 源处填写的必须是一个目录,务必保证该目录下的文件都能被该类读取。如果设置了读取限制,那么只读取限定的行数。 Example: sentences = PathLineSentences(path) 目录下的文件应该是如此种种。 The files in the directory should be either text files, .bz2 files, or .gz files.
对于单个文件语料,使用LineSentence
class: gensim.models.word2vec.LineSentence
每一行对应一个句子(已经分词,以空格隔开),我们可以直接用LineSentence把txt文件转为所需要的格式。
LineSentence功能解释:Iterate over a file that contains sentences: one line = one sentence. Words must be already preprocessed and separated by whitespace(对包含句子的文件进行迭代:一行=一句话。单词必须经过预处理,并由空格分隔)
from gensim import Word2Vec from gensim.Word2Vec import LineSentence from gensim.test.utils import common_texts, get_tmpfile # inp为输入语料 inp = 'wiki.zh.text.jian.seg.txt' sentences = LineSentences(inp) path = get_tmpfile("word2vec.model") #创建临时文件 model = Word2Vec(sentences, size=100, window=5, min_count=1) model.save("word2vec.model")
gensim.models.word2vec.LineSentence(source, max_sentence_length=10000, limit=None)
预处理类,限制句子最大长度,文档最大行数
拿到了分词后的文件,在一般的NLP处理中,会需要去停用词。由于word2vec的算法依赖于上下文,而上下文有可能就是停词。因此对于word2vec,我们可以不用去停词。
语料库获取语料
class gensim.models.word2vec.Text8Corpus
class gensim.models.word2vec.Text8Corpus(fname, max_sentence_length=10000)
Bases: object
从一个叫‘text8’的语料库中获取数据,该语料来源于以下网址,参数max_sentence_length限定了获取的语料长度
Iterate over sentences from the “text8” corpus, unzipped from http://mattmahoney.net/dc/text8.zip .
word2vec中文语料处理及模型训练实践
(实践部分代码改编自链接)原始小说语料下载《人民的名义》
import jieba import jieba.analyse from gensim.test.utils import common_texts, get_tmpfile from gensim.models import Word2Vec #文件位置需要改为自己的存放路径 #将文本分词 with open('C:\\Users\Administrator\Desktop\\in_the_name_of_people\in_the_name_of_people.txt',encoding='utf-8') as f: document = f.read() document_cut = jieba.cut(document) result = ' '.join(document_cut) with open('./in_the_name_of_people_segment.txt', 'w',encoding="utf-8") as f2: f2.write(result) #加载语料 sentences = word2vec.LineSentence('./in_the_name_of_people_segment.txt') #训练语料 path = get_tmpfile("word2vec.model") #创建临时文件 model = word2vec.Word2Vec(sentences, hs=1,min_count=1,window=10,size=100) # model.save("word2vec.model") # model = Word2Vec.load("word2vec.model") #输入与“贪污”相近的100个词 for key in model.wv.similar_by_word('贪污', topn =100): print(key) #输出了100个,示例前几个 ('地皮', 0.9542419910430908) ('高昂', 0.934522807598114) ('证', 0.9154356122016907) ('上强', 0.9113685488700867) ('一抹', 0.9097814559936523) ('得罪', 0.9082552790641785) ('屁股', 0.9072068929672241) ('能伸能屈', 0.9049990177154541) ('二十五万', 0.9045952558517456)