Alink教程(Java版)

第31.5节 分类示例

首先是构造分类训练、测试集,使用Google Scholar的作者标签数据(访问网页https://ericdongyx.github.io/metapath2vec/m2v.html,下载其中的label.zip文件),通过作者名,将作者ID与标签连接起来。详细代码如下:

CsvSourceBatchOp author_name_label = new CsvSourceBatchOp()
	.setFilePath(DATA_DIR + "googlescholar.8area.author.label.txt")
	.setSchemaStr("author_labeled string, label int")
	.setFieldDelimiter(" ");

BatchOperator author_id_label = new JoinBatchOp()
	.setJoinPredicate("author = author_labeled")
	.setSelectClause("author_id, label")
	.linkFrom(id_author, author_name_label);

随后,将关联起来的作者ID、标签数据进行训练集和预测集划分,具体代码如下,划分结果分别保存到文件AUTHOR_LABEL_TRAINAUTHOR_LABEL_TEST

Utils.splitTrainTestIfNotExist(
	author_id_label,
	DATA_DIR + AUTHOR_LABEL_TRAIN,
	DATA_DIR + AUTHOR_LABEL_TEST,
	0.8
);

在执行分类前,还要将作者ID与其对应的Embedding向量关联起来,这个向量将作为分类特征。Alink中常用两种方式进行关联,一种是用Join方法,通过组建实现;另一种是使用组件,从Embedding模型表中查找对应向量。这里我们对于训练集和测试集分别使用了这两种方法,具体代码如下:

BatchOperator author_train = new JoinBatchOp()
	.setJoinPredicate("author_id = node")
	.setSelectClause("author_id, vec, label")
	.linkFrom(
		graph_embedding,
		new AkSourceBatchOp().setFilePath(DATA_DIR + AUTHOR_LABEL_TRAIN)
	);

BatchOperator author_test = new LookupBatchOp()
	.setSelectedCols("author_id")
	.setOutputCols("vec")
	.linkFrom(
		graph_embedding,
		new AkSourceBatchOp().setFilePath(DATA_DIR + AUTHOR_LABEL_TEST)
	);

注意:在批式处理场景,这两个组件的效果是一样的;但是如果需要部署到线上服务或者在流式场景中使用,Lookup都有对应的组件可以使用。

基于前面准备好的训练集和测试集,可以开始分类实验,这里选择了两个常用风分类器:SoftmaxKnnClassifier,并对预测结果进行评估,便于了解当前场景下,不同分类器的效果,及不用Embedding算法对分类结果的影响。

new Softmax()
	.setVectorCol("vec")
	.setLabelCol("label")
	.setPredictionCol("pred")
	.fit(author_train)
	.transform(author_test)
	.link(
		new EvalMultiClassBatchOp()
			.setLabelCol("label")
			.setPredictionCol("pred")
			.lazyPrintMetrics("[ Using Softmax ]")
	);

new KnnClassifier()
	.setVectorCol("vec")
	.setLabelCol("label")
	.setPredictionCol("pred")
	.fit(author_train)
	.transform(author_test)
	.link(
		new EvalMultiClassBatchOp()
			.setLabelCol("label")
			.setPredictionCol("pred")
			.lazyPrintMetrics("[ Using KnnClassifier ]")
	);

最后,构造完整的实验流程如下面代码所示,其中的classifyWithEmbedding()方法包装前面的Embedding向量关联及模型训练评估的流程。

for (String embedding_model_file :
	new String[] {DEEPWALK_EMBEDDING, NODE2VEC_EMBEDDING, METAPATH2VEC_EMBEDDING}
) {

	System.out.println("\n\n< " + embedding_model_file + " >\n");

	classifyWithEmbedding(
		new AkSourceBatchOp().setFilePath(DATA_DIR + embedding_model_file)
	);

}

运行结果汇总如下,我们看到KnnClassifier的分类效果比Softmax更好;SoftmaxDeepWalk Embedding上效果较好;KnnClassifierNode2Vec Embedding上效果较好。注意,是在当前参数的条件下,如果调整Embedding训练参数或者分类器训练参数,结果会不一样的。

Softmax

KnnClassifier

DeepWalk

Accuracy:0.5306 Kappa:0.2438

Accuracy:0.5593 Kappa:0.3651

Node2Vec

Accuracy:0.5229 Kappa:0.2294

Accuracy:0.5603 Kappa:0.3662

MetaPath2Vec

Accuracy:0.524 Kappa:0.2324

Accuracy:0.5419 Kappa:0.3284