最近一直在折腾词向量的训练,之前是用HanLP来训练,不过这个框架的文件训练输入只能是单个文件,而我的需要求要输入一个文件路径,会进行递归的查询文件去加载,遗憾的是看了HanLp的源码之后发现并不行,他就没有考虑路径的问题,直接是读取文件了。因为公司有这个需求,我们的语料是按照表/年/月/日/id.txt这种格式保存的,因为这个语料是长期保存的,这是公司的硬性需求,所以就只能转向用gensim去训练我的词向量了。。因为听说gensim是可以读取路径的。。。
下面来看:
利用gensim.models.Word2Vec(sentences)建立词向量模型
该构造函数执行了三个步骤:建立一个空的模型对象,遍历一次语料库建立词典,第二次遍历语料库建立神经网络模型。可以通过分别执行
- model=gensim.models.Word2Vec(),
- model.build_vocab(sentences),
- model.train(sentences)来实现
也可以利用gensim.models.Word2Vec()一步到位
class gensim.models.word2vec.Word2Vec(sentences=None, size=100, alpha=0.025, window=5, min_count=5, max_vocab_size=None, sample=0.001, seed=1, workers=3, min_alpha=0.0001, sg=0, hs=0, negative=5, cbow_mean=1, hashfxn=<built-in function hash>, iter=5, null_word=0, trim_rule=None, sorted_vocab=1, batch_words=10000, compute_loss=False, callbacks=())
model = Word2Vec(sentences, min_count=10) # default value is 5
model = Word2Vec(sentences, size=200) # default value is 100
model = Word2Vec(sentences, workers=4) # default = 1 worker = no parallelization
附加,Cython安装方法:
cython 在linux(ubuntu)下安装:
sudo apt-get install cython
安装后 输入 cython 即可验证是否安装成功
model = Word2Vec(sentences, sg=1) # default value is 0
model = Word2Vec(sentences, window=5)
sentences这个参数需要根据文件或者路径去读取,然后才可以传入训练方法:
from gensim.models import word2vec
sentences = word2vec.PathLineSentences(path)
注意!!!坑来了!!!
当sentences = word2vec.PathLineSentences(path)
这个方法的path传入是文件的时候没问题,当传入是文件的第一个父目录是也没有问题!如下图
传入为:xxxxx\export\NI_NewsInfo\2017\1\2
,这样是没问题的;
但是!!!当传入为xxxxx\export\NI_NewsInfo\2017\1
或者是更上层目录的时候,就会报错,说不能识别。下面查看PathLineSentences
的源代码:
他的这个类的初始化方法def __init__(self, source, max_sentence_length=MAX_WORDS_IN_BATCH, limit=None)
中,,如果发现你的传入的参数是路径,他只是会去拿到该目录下的所有文件,而不会去递归,下面修改源码。
其中注释的是我去掉的源码,把elif的内容改成和我一样。
if os.path.isfile(self.source):
logger.debug('single file given as source, rather than a directory of files')
logger.debug('consider using models.word2vec.LineSentence for a single file')
self.input_files = [self.source] # force code compatibility with list of files
elif os.path.isdir(self.source):
self.source = os.path.join(self.source, '') # ensures os-specific slash at end of path
logger.info('reading directory %s', self.source)
self.input_files = []
#获取目录下的所有文件
for fpathe,dirs,fs in os.walk(self.source):
for f in fs:
self.input_files.append(os.path.join(fpathe,f))
# self.input_files = os.listdir(self.source)
# self.input_files = [self.source + filename for filename in self.input_files] # make full paths
self.input_files.sort() # makes sure it happens in filename order
这样就可以读取任意路径了。
model.save('/data/word2vec')
# model.save_word2vec_format('/data/word2vec.txt',binary=False)
# model.save_word2vec_format('/data/word2vec.bin'.binary=True)
model = gensim.models.Word2Vec.load('/data/word2vec')
model.train(more_sentences)
model = gensim.models.Word2Vec.load('/data/word2vec')