word2vec可以直接在pairs上面进行训练,然而GloVe,PPMI以及SVD都需要在共现矩阵上面进行训练。从pairs得到共现矩阵是非常消耗计算资源的。hyperwords中生成共现矩阵的效率比较低,也没有进度的显示,而且把这个步骤放在了两个文件中(hyperwords中的pairs2counts是没有完全排序的)。GloVe中有一个C语言版本的生成共现矩阵的代码,能很高效的得到共现矩阵。ngram2vec中的pairs2counts在把GloVe中的生成共现矩阵的代码改成python版本的同时,进行了一些改进,能够更加充分的利用内存,从而能更高效的生成共现矩阵代码。生成共现矩阵用python写的话代码比C语言简短的多,而且易读很多。在效率上面比C语言差,但是加上一些技巧和改进措施,粗略的尝试了一下,ngram2vec工具包生成共现矩阵的效率不比GloVe中的差。当然这个ngram2vec的pairs2counts好像还是半成品,项目上说还会有很多改进,能进一步的提升共现矩阵建立的效率。ngram2vec建立共现矩阵的过程和ngram2vec基本一样,分成两个步骤,第一步是局部排序,第二步是对局部排序的内容进行汇总。如果之前看了GloVe中共现矩阵的建立,看这个代码就会容易的多。我们知道GloVe中用了两种数据结构(mixed策略),用二维数组去存共现矩阵左上角内容,用pairs去存共现矩阵其他部分的内容。ngram2vec工具包同样用了mixed策略,同时它不再用pairs去存共现矩阵其他部分了,而是用词典去存(词典的value还是词典,stripes策略,比如<apple,<eat:17,and:12...>>,apple收是中心词,eat是上下文单词,17是eat和apple共现次数。),词典能比pair更加高效的利用内存,同时在第二步汇总的时候也更高效。
wi, iw =load_vocabulary(args['<vocab_word>'])//读取中心词词典
ci, ic = load_vocabulary(args['<vocab_context>'])//读取上下文词典
max_product = 10000//和GloVe一样,使用mixed策略
memory_size = float(args['--memory_size']) * 1000**3
D = {} #store bottom-right part of co-occurrence matrix in dictionary//存词典左上角以外的部分
tmpfile_num = 1
memory_size_used = 0//词典中value占用的内存
#store top-left corner of co-occurrence matrix in array, which is the strategy used in GloVe//逻辑和GloVe是一样的