复现WordNet哺乳动物子树Poincaré嵌入图失败,求排查原因
问题:复现《Poincaré Embeddings for Learning Hierarchical Representations》图2失败的排查与解决
我看了你的代码,问题主要出在关系构建的完整性、层次信息的丢失以及训练参数设置这几个方面,下面一步步给你拆解和修正:
核心错误分析
1. 只保留了到根节点的直接关系,丢失了完整层次
你的代码里只生成了每个词到mammal的配对,但论文中的WordNet子树是完整的层级结构——每个下位词需要连接它的所有祖先上位词(比如dog要连canine、carnivore、mammal,而不是只连mammal)。没有中间层级的关系,模型根本学不到嵌套的层次结构,自然输出和论文图不符。
2. 用set去重lemma破坏了层次信息
WordNet里很多词对应多个synset(比如"cat"既可以指家猫,也可以指猫科动物这个大类),这些节点在层次中的位置完全不同。你用set去重后,把这些不同的节点合并成一个,直接打乱了原有的层次关系。
3. 训练参数不符合Poincaré嵌入的要求
你设置了negative=0,也就是关闭了负采样,但Poincaré嵌入的训练逻辑依赖负采样来区分正确的父子/祖孙关系,没有负采样模型很难收敛到合理的层次结构。同时50轮训练可能不够充分。
修正后的代码
第一步:构建完整的层次关系
from nltk.corpus import wordnet as wn root = wn.synset('mammal.n.01') relations = [] # 遍历mammal的所有下位synset(包括所有子节点、孙节点等) for synset in root.closure(lambda s: s.hyponyms()): # 遍历当前synset的所有上位synset(从直接上位一直到root) for hypernym in synset.hypernyms(): # 把当前synset的每个lemma和上位synset的每个lemma配对 for lemma in synset.lemma_names(): for hyper_lemma in hypernym.lemma_names(): relations.append((lemma, hyper_lemma)) # 去重重复的关系对(可选,但能减少训练冗余) relations = list(set(relations))
第二步:用正确参数训练并可视化
from gensim.models.poincare import PoincareModel from gensim.viz.poincare import poincare_2d_visualization # 设置符合论文逻辑的参数:负采样数设为5,训练轮次增加到100 model = PoincareModel(relations, size=2, negative=5, alpha=0.1) model.train(epochs=100) # 可视化时指定root节点,方便观察层次嵌套 fig = poincare_2d_visualization( model, relations, title='WordNet Poincaré Embeddings (Mammal Subtree)', root=root.lemma_names()[0] # 突出显示mammal节点 ) fig.show()
额外提示
- 如果还是觉得结果不够贴合论文,可以尝试调整
alpha(学习率)和negative的数值,或者增加训练轮次; - 如果你想避免lemma的歧义问题,可以直接用synset的名称(比如
dog.n.01)来构建关系,而不是用lemma,这样每个节点都是唯一的,层次结构更准确。
内容的提问来源于stack exchange,提问作者jds
相关产品推荐
相关产品推荐

