最近一直在折腾词向量的训练,之前是用HanLP来训练,不过这个框架的文件训练输入只能是单个文件,而我的需要求要输入一个文件路径,会进行递归的查询文件去加载,遗憾的是看了HanLp的源码之后发现并不行,他就没有考虑路径的问题,直接是读取文件了。因为公司有这个需求,我们的语料是按照表/年/月/日/id.txt这种格式保存的,因为这个语料是长期保存的,这是公司的硬性需求,所以就只能转向用gensim去训练我的词向量了。。因为听说gensim是可以读取路径的。。。 下面来看: 利用gensim.models.Word2Vec(sentences)建立词向量模型 该构造函数执行了三个步骤:建立一个空的模型对象,遍历一次语料库建立词典,第二次遍历语料库建立神经网络模型。可以通过分别执行
- model=gensim.models.Word2Vec(), - model.build_vocab(sentences), - model.train(sentences)来实现也可以利用gensim.models.Word2Vec()一步到位
附加,Cython安装方法:
cython 在linux(ubuntu)下安装: sudo apt-get install cython 安装后 输入 cython 即可验证是否安装成功 sg sg=1是skip-gram算法,对低频词敏感;默认sg=0为CBOW算法。 model = Word2Vec(sentences, sg=1) # default value is 0 window window是句子中当前词与目标词之间的最大距离,3表示在目标词前看3-b个词,后面看b个词(b在0-3之间随机)。 model = Word2Vec(sentences, window=5) negative、sample negative和sample可根据训练结果进行微调,sample表示更高频率的词被随机下采样到所设置的阈值,默认值为1e-3。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这样就可以读取任意路径了。