【导读】本文介绍了一个理由Keras和TensorFlow进行图数据学习、分类的工程。
Github链接:
https://github.com/CVxTz/graph_classification
使用步骤
从网站下载cora数据集:https://linqs.soe.ucsc.edu/data
解压到input/cora 文件夹
执行以下命令:
python eda.py
python word_features_only.py # for baseline model 53.28% accuracy
python graph_embedding.py # for model_1 73.06% accuracy
python graph_features_embedding.py # for model_2 76.35% accuracy
动机
在现实世界的应用中,有很多数据可以以图的形式表示,如引用网络、社交网络(关注者图、朋友网络……)、生物网络或电信等。
利用图数据特征的提取,可以借助节点间的信息传递来提高预测模型的性能。然而,图数据的表示并不简单。
在这篇文章中,我们将探讨一些处理泛型图的方法,直接从数据中学习到的图表示进行节点分类。
数据集
我们使用Cora引用网络作为实验数据集。每个节点表示一篇科学论文,节点之间的边表示两篇论文之间的引用关系。
每个节点都由一组特征(BagOfWords)和一组连接到其他节点的边来表示。
数据集有2708个节点,分为七类。该网络有5429个链接。总的来说,每个节点有1433个二进制(稀疏)特性。以下我们只使用140个样本进行训练,其余的用于验证/测试。
问题设置
问题:在少量训练样本的情况下,将一个类标签分配给图中的节点。
直觉/假设:图中靠近的节点更可能有相似的标签。
解决方案:找到从图中提取特征的方法,以帮助对新节点进行分类。
提出方法
简单的基准模型
我们首先使用最简单的模型进行实验,该模型仅使用二进制特征并抛弃所有图数据信息来预测节点类。
该模型是一个全连接神经网络,以二进制特征为输入,输出每个节点的类概率。
简单的基线模型精度:53.28%
添加图信息:
一种自动学习图形特征的方法是,通过训练网络执行辅助任务,预测两个输入节点之间最短路径长度的倒数,将每个节点嵌入到一个向量中。
下一步是使用预先训练好的节点嵌入作为分类模型的输入。我们还利用学习嵌入向量的距离增加了一个额外的输入,即相邻节点的平均二进制特征。
def get_graph_embedding_model(n_nodes):
in_1 = Input((1,))
in_2 = Input((1,))
emb = Embedding(n_nodes, 100, name="node1")
x1 = emb(in_1)
x2 = emb(in_2)
x1 = Flatten()(x1)
x1 = Dropout(0.1)(x1)
x2 = Flatten()(x2)
x2 = Dropout(0.1)(x2)
x = Multiply()([x1, x2])
x = Dropout(0.1)(x)
x = Dense(1, activation="linear", name="spl")(x)
model = Model([in_1, in_2], x)
"mae", optimizer="adam") =
model.summary()
return model
图嵌入分类模型准确率:73.06%
我们可以看到添加了图特性作为分类模型的输入有助于显著提高分类精度相对于基线模型从53.28%至73.06%。
改进图形特征学习
我们可以进一步改进之前的模型,进一步推进预训练,利用节点嵌入网络中的二进制特征,除了利用节点嵌入向量外,还可以重用来自二进制特征的预训练权值。
def get_graph_embedding_model(n_nodes, n_features):
in_1 = Input((1,))
in_2 = Input((1,))
in_3 = Input((n_features,))
in_4 = Input((n_features,))
emb = Embedding(n_nodes, 50, name="node1")
x1 = emb(in_1)
x2 = emb(in_2)
x1 = Flatten()(x1)
x1 = Dropout(0.02)(x1)
x2 = Flatten()(x2)
x2 = Dropout(0.02)(x2)
x = Multiply()([x1, x2])
d = Dense(10, kernel_regularizer=l2(0.0005), name="features")
x1_ = d(in_3)
x2_ = d(in_4)
x_ = Multiply()([x1_, x2_])
x = Concatenate()([x, x_])
x = Dropout(0.02)(x)
x = Dense(1, activation="linear", name="spl")(x)
model = Model([in_1, in_2, in_3, in_4], x)
"mae", optimizer="adam") =
model.summary()
return model
改进的图嵌入分类模型精度:76.35%
与以前的方法相比,这个额外的改进增加了几个百分点的准确性。
结论
在这篇文章中我们看到,我们可以从图中吸取有用表示结构化数据,然后使用这些表示提高节点分类模型的泛化性能从😎53.28%至76.35%。