我在尝试使用Word2Vec(Skipgram)来训练一组路径上的网络嵌入模型,我的图中有169343个节点,即Word2Vec中的单词,对于每个节点,我运行长度为80的随机路径。因此,我有(169343,80)个路径,即Word2Vec中的句子。在运行了3个周期的SkipGram后,我只得到了28015个向量,而不是169343个。以下是我的网络嵌入代码。
def run_skipgram(walk_path): walks = np.load(walk_path).tolist() skipgram = Word2Vec(sentences=walks, vector_size=128, negative=5, window=8, sg=1, workers=6, epochs=3) keys = list(map(int, skipgram.wv.index_to_key)) keys.sort() vectors = [skipgram.wv[key] for key in keys] return np.array(vectors)
回答:
你确定你的walks
语料库是你期望的,并且符合Gensim的Word2Vec
的要求吗?
例如,len(walks)
是否等于169343?len(walks[0])
是否等于80?walks[0]
是否是一个包含80个字符串标记的列表?
另外请注意:默认情况下,Word2Vec
使用min_count=5
– 因此在训练过程中,出现次数少于5次的任何标记都会被忽略。在大多数情况下,这个最小值 – 甚至更高的值!- 是合理的,因为在通常的自然语言训练数据中,仅出现1次或几次的标记无法获得好的词向量(但总体上,可以作为稀释噪声,影响其他向量的质量)。
根据你的图形,从每个节点出发的一次路径可能无法确保该节点在所有路径中至少出现5次。因此,你可以尝试min_count=1
。
但更好的方法可能是从每个起始点进行5次路径,或者进行足够多的路径以确保所有节点至少出现5次。169,343 * 80 * 5
仍然只有67,737,200个训练词,词汇量为169,343,仍然是可管理的。(如果扩展整个训练集作为一个列表有问题,你可以创建一个可迭代对象,按需生成路径,一个接一个,而不是预先全部生成。)
或者,每个起始节点进行5次路径,但每次路径只有20步,这样可以保持语料库的大小基本不变,同时保证每个节点至少出现5次。
甚至可以:自适应地继续添加路径,直到确保每个节点都出现足够多次。例如,随机选择一个节点,进行一次路径,记录每个节点至今的出现次数 – 并持续增加每个节点的总数。你也可以尝试一个自适应语料库,持续添加路径,直到每个节点都达到最低出现次数。
对于某些偏远节点,可能需要很长时间才能遇到它们,因此另一个改进可能是:进行一些初始路径,然后统计每个节点的访问次数,当最不常见的节点低于目标min_count
时,从该节点开始另一个路径 – 确保它至少多一次访问。
这可以帮助过采样连接较少的区域,这可能是好事也可能是坏事。值得注意的是,对于自然语言文本,Word2Vec
的sample
参数非常有帮助,可以丢弃某些过度表示的词,防止它们冗余地垄断训练时间,确保不常见的词也能获得好的表示。(这是一个参数,有时可以提供更少的训练时间和更好的结果的双重优势!)确保你的路径在连接较少的区域花费更多时间可能会提供类似的优势,特别是如果你的下游使用对较少访问区域的向量同样感兴趣的话。