Alink教程(Java版)

第31.3节 计算Embedding

图中的边是由两部分组成的,论文与作者的联系,以及论文与会议的联系。这里使用Union操作,将描述两种对应关系的表合并起来。需要注意的是,合并时需要两个数据表有相同的数据列名和类型。具体实现代码如下:

BatchOperator <?> edges = new UnionBatchOp().linkFrom(
   paper_author.select("paper_id AS source_id, author_id AS target_id"),
   paper_conf.select("paper_id AS source_id, conf_id AS target_id")
);

使用DeepWalk计算Embedding的代码如下,直接将边的数据接入DeepWalk组件,设置边的起始节点列名称与目标节点列名称;如果需要将图看作是无向图,可以通过设置参数IsToUndigraphture实现;指定生成向量的维度(VectorSize),游走路径的长度(WalkLength),每个节点作为游走的初始节点,生成游走路径的数量(WalkNum);参数NumIter是对训练数据迭代训练的次数。训练出的Embedding模型会被保存到文件路径TEMP_DIR + DEEPWALK_EMBEDDING

edges
	.link(
		new DeepWalkBatchOp()
			.setSourceCol("source_id")
			.setTargetCol("target_id")
			.setIsToUndigraph(true)
			.setVectorSize(100)
			.setWalkLength(10)
			.setWalkNum(20)
			.setNumIter(1)
	)
	.link(
		new AkSinkBatchOp()
			.setFilePath(DATA_DIR + DEEPWALK_EMBEDDING)
			.setOverwriteSink(true)
	);
BatchOperator.execute();

使用Node2Vec组件与使用DeepWalk组件类似,不同的是需要设置参数PQ,关于这两个参数的介绍详见前面Node2Vec算法的介绍部分。具体代码如下,训练出的Embedding模型会被保存到文件路径TEMP_DIR + NODE2VEC_EMBEDDING

edges
	.link(
		new Node2VecBatchOp()
			.setSourceCol("source_id")
			.setTargetCol("target_id")
			.setIsToUndigraph(true)
			.setVectorSize(100)
			.setWalkLength(10)
			.setWalkNum(20)
			.setP(2.0)
			.setQ(0.5)
			.setNumIter(1)
	)
	.link(
		new AkSinkBatchOp()
			.setFilePath(DATA_DIR + NODE2VEC_EMBEDDING)
			.setOverwriteSink(true)
	);
BatchOperator.execute();

最后,我们来尝试MetaPath2Vec算法,需要事先构造一个映射表,每个节点赋予一个类型值,论文节点对应类型“P”、作者节点对应类型“A”、会议节点对应类型“C”。并使用UnionBatchOp组件将三部分数据合并在一起。

BatchOperator id_type = new UnionBatchOp()
	.linkFrom(
		paper.select("paper_id AS node_id, 'P' AS node_type"),
		id_author.select("author_id AS node_id, 'A' AS node_type"),
		id_conf.select("conf_id AS node_id, 'C' AS node_type")
	);

MetaPath2VecBatchOp组件需要设置参数MetaPath,就是由节点类型表示的路径模版,模版的最后一个类型与第一个类型相同,相当于尾首连接,重复此模式。譬如:“APA”就表示路径以类型为“A”的节点开始,然后选择的是类型“P”的节点,随后是类型“A”节点,第四个节点类型为“P……。对应到路径的实际意义,选择一个作者1,选择作者1的一篇论文1,在论文1的共同作者中选择作者2,然后选择作者2的一篇论文2,在论文2的共同作者中选择作者3……。相比前两种算法,多一个节点类型的数据输入,并在参数中设置节点列名VertexCol和类型列名TypeCol,如下面代码所示:

new MetaPath2VecBatchOp()
	.setMetaPath("APA,APCPA")
	.setVertexCol("node_id")
	.setTypeCol("node_type")
	.setSourceCol("source_id")
	.setTargetCol("target_id")
	.setIsToUndigraph(true)
	.setVectorSize(100)
	.setWalkLength(10)
	.setWalkNum(20)
	.setNumIter(1)
	.linkFrom(edges, id_type)
	.link(
		new AkSinkBatchOp()
			.setFilePath(DATA_DIR + METAPATH2VEC_EMBEDDING)
			.setOverwriteSink(true)
	);
BatchOperator.execute();