【发布时间】: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