拆分用于Stellargraph中Node2vec链接预测的训练测试集

问题描述

我试图了解如何使用stellargraphEdgeSplitter类。特别是,用于训练基于Node2Vec的链接预测模型的文档中的examples将图形分为以下几部分:

Distrution of samples across train,val and test set

按照文档上的examples,首先对完整图形的10%的链接进行采样,以获得测试集:

# Define an edge splitter on the original graph:
edge_splitter_test = EdgeSplitter(graph)

# Randomly sample a fraction p=0.1 of all positive links,and same number of negative links,from graph,and obtain the
# reduced graph graph_test with the sampled links removed:
graph_test,examples_test,labels_test = edge_splitter_test.train_test_split(
    p=0.1,method="global"
)

据我从文档中了解到,graph_test是原始图形,但是删除了测试链接。然后对训练集执行相同的操作,

# Do the same process to compute a training subset from within the test graph
edge_splitter_train = EdgeSplitter(graph_test)
graph_train,examples,labels = edge_splitter_train.train_test_split(
    p=0.1,method="global"
)

按照先前的逻辑,graph_train对应于graph_test,但训练链接删除

代码的下面,我的理解是我们使用graph_train训练嵌入,并使用训练样本(示例,标签)训练分类器。所以我在这里有几个问题:

  • 我们为什么要使用训练数据的不交集来训练模型的不同部分?我们不应该使用完整的训练链接集来训练嵌入和分类器吗?
  • 为什么测试集这么大?在训练集中拥有大多数样本会更好吗?
  • 使用EdgeSplitter类的正确方法是什么?

预先感谢您的帮助!

解决方法

为什么不相交集合: 这可能会或可能无关紧要,具体取决于嵌入算法。 嵌入算法和分类器都看到的边缘作为目标的风险是嵌入算法可能编码不可泛化的特征。

例如,理论上嵌入的一个特征可能是节点 id,然后您可以使用其他特征对节点的整个邻域进行编码。当以一种奇怪的方式将两个节点的嵌入组合成一个链接向量时,或者当使用多层模型时,因此可以创建一个二值特征,如果两个节点在嵌入训练期间连接,则为 1,否则为 0。 在这种情况下,分类器可能只会学习使用这个在您访问测试数据时不存在(即值为 0)的微不足道的特征。

上述情况在真实场景中不会发生,但更细微的特征可能会在较小程度上产生相同的效果。 最后,这只会使模型选择变得糟糕。 也就是说,第一次拆分是为了使测试可靠。第二个分裂是改进模型选择。因此,您可以根据需要省略第二个拆分。

为什么测试集这么大: 使用更大的火车组,您可能会获得更高的分数。只要以不同的分割重复实验并且方差在控制范围内,增加训练大小应该没问题。

EdgeSplitter 的正确使用方法是什么: 我不知道这里的“正确”是什么意思。我认为图分裂仍然是一个活跃的研究领域。