用于网络嵌入的 Word2Vec 会忽略语料库中的单词(节点)(walks)

Word2Vec for network embedding ignores words (nodes) in corpus (walks)

我正在尝试 运行 word2vec (Skipgram) 到一组 walks 来训练网络嵌入模型,在我的图中我有 169343 个节点,即; Word2vec 上下文中的单词,对于每个节点 I 运行 一个长度为 80 的随机游走。因此,我有 (169343,80) 次游走,即; Word2vec 中的句子。在 运行 宁 SkipGram 3 个时期后,我只得到 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 参数非常有助于 丢弃 某些过度表达的词,防止它们冗余地垄断训练时间,确保不那么频繁的单词也得到很好的表示。 (这是一个参数,有时可以提供更少训练时间 更好结果的双重打击!)确保你的步行时间花在连接较少的区域可能会提供类似的优势,特别是如果您对矢量的下游使用对访问量较少的区域的矢量同样感兴趣。