【问题标题】:How to do link prediction with node embeddings?如何使用节点嵌入进行链接预测?
【发布时间】:2020-01-23 08:17:15
【问题描述】:

我目前正在研究推荐系统中的项目嵌入任务,我想评估新嵌入算法与旧嵌入算法的性能。我已经阅读了一些关于图嵌入的论文,几乎每篇论文都提到了一种评估嵌入的常规方法,即链接预测。但这些论文都没有准确描述你是如何做到的。所以我的问题是如何使用链接预测来评估嵌入?

我尝试应用的算法是: 首先在用户点击序列上建立一个有向图,图中的每个节点代表一个项目,如果用户曾经点击项目 A 再点击项目 B,则应该有两个节点 A 和 B 以及一条权重为 1 的边 AB。另一个用户点击A然后点击B,边AB的权重加1。 然后通过随机游走图生成一个新的序列数据集,使用出站权重作为传送概率。 最后对新序列执行 SkipGram 以生成节点嵌入。

正如许多论文所提到的,我在图中删除了一定比例的边作为测试集的正样本(例如 0.25),并随机生成了一些假边作为负样本。下一个是什么?我是否应该简单地为训练集中的真实边生成假边,连接每个边上两个节点的嵌入,并构建一个通用分类器(如逻辑回归)并在测试集上对其进行测试?或者我应该用两个节点的余弦相似度和一个 0/​​1 的标签来计算测试集上的 AUC,表明这两个节点是否真的连接?或者我应该用两个节点的嵌入的 sigmoided 点积和一个 0/​​1 的标签来计算 AUC,表明这两个节点是否真的连接,因为这是你计算最后一层概率的方式?

# these are example describing the three methods above
item_emb = np.random.random(400).reshape(100, 4)  # assume we have 100 items and have embedded them into a 4-dimension vector space.
test_node = np.random.randint(0, 100, size=200).reshape(100, 2)  # assume we have 100 pairs of nodes
test_label = np.random.randint(0, 2, size=100).reshape(100, 1)  # assume this is the label indicating if the pair of nodes are really connected

def test_A():
  # use logistic regression
  train_node = ...  # generate true and fake node pairs in a similar way
  train_label = ... # generate true and fake node pairs in a similar way

  train_feat = np.hstack(
    item_emb[train_node[:, 0]],
    item_emb[train_node[:, 1]])  # concatenate the embeddings
  test_feat = np.hstack(
    item_emb[test_node[:, 0]],
    item_emb[test_node[:, 1]])  # concatenate the embeddings
  lr = sklearn.linear_models.LogisticRegression().fit(train_feat, train_label)
  auc = roc_auc_score(test_label, lr.predict_proba(test_feat)[:,1])
  return auc

def test_B():
  # use cosine similarity
  emb1 = item_emb[test_node[:, 0]]
  emb2 = item_emb[test_node[:, 1]]
  cosine_sim = emb1 * emb2 / (np.linalg.norm(emb1, axis=1)*np.linalg.norm(emb2,axis=1)
  auc = roc_auc_score(test_label, cosine_sim)
  return auc

def test_C():
  # use dot product
  # here we extract the softmax weights and biases from the training network
  softmax_weights = ...  # same shape as item_emb
  softmax_biases = ...  # shape of (item_emb.shape[0], 1)
  embedded_item = item_emb[test_node[:, 0]]  # target item embedding
  softmaxed_context = softmax_weights[test_node[:, 1]] + softmax_biases
  dot_prod = np.sum(embeded_item * softmaxed_context, axis=1)
  auc = roc_auc_score(test_label, dot_prod)
  return auc

我在几个测试中尝试了这三种方法,但它们并不总是在说同样的事情。一些参数组合在 testA() 中表现更好,而在其他指标中表现不佳,有些则相反..等等。遗憾的是,没有这样一个参数组合在所有三个指标中都表现出色......问题是我应该使用哪个指标?

【问题讨论】:

  • 我也面临同样的问题。你找到任何解决方案了吗?我的主要问题是:我们什么时候应该提取节点嵌入?在训练/测试拆分之前还是之后?如果我们在拆分之前这样做,嵌入会保留网络的拓扑结构,因此它们会使链接预测产生偏差。另一方面,如果我们在拆分后提取嵌入,同一节点在训练集和测试集中可能具有不同的表示。
  • 对于您的问题,我的建议是您应该始终从训练集中提取嵌入并在测试集上测试嵌入,并且没有嵌入可从测试集中提取。没错,拆分前提取的嵌入会导致数据泄漏。

标签: machine-learning graph recommendation-engine word-embedding


【解决方案1】:

您应该调查一些实现:

  1. 恒星图:Link prediction with node2vec+Logistic regression
  2. AmpliGraph:Link prediction with ComplEx

简而言之,应该从原始图中采样边(不是节点!),删除它们,并在该截断图上学习嵌入。然后对移除的边缘进行评估。

另外,还有两种可能的情况:

  • 任何一对节点之间所有可能的边都被标记。在这种情况下,评估指标是 ROC AUC,当我们学习一个分类器来区分正边缘和负边缘时。
  • 仅观察到正(实际)边缘。我们不知道在现实世界中休息对是否相互关联。在这里,我们为每个正节点生成负(假)节点。该任务被视为实体排名,具有下一个评估指标:

可以在the paper,第 5.1-5.3 节中找到一个示例。

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2018-06-03
    • 1970-01-01
    • 2011-09-14
    • 2020-10-30
    • 2015-06-06
    相关资源
    最近更新 更多