Graph Embedding(SDNE,Graph2vec,GraphGAN)

在这里插入图片描述
SDNE
前一篇整理了3种常用的图嵌入方法,DeepWalk,LINE和Node2vec。Structural Deep Network Embeddings(结构深层网络嵌入,SDNE)的不同之处在于,它并不是基于随机游走的思想,在实践中比较稳定。

主要思路如上图,会将节点向量 si 作为模型的输入,通过自编码器对这个向量进行降维压缩 zi,然后再重建特征。其损失函数定义为:
O 2 = ∑ ∣ ∣ s i ′ − s i ∣ ∣ 2 2 O_2=\sum ||s_i'-s_i||^2_2 O2=sisi22

因为输入的是邻接矩阵,所以这样的重构能够使得结构相似的顶点具有相似的embedding表示向量。所以实际上通过重建学习到的是二阶相似度。
在这里插入图片描述
但是与LINE相似,SDNE也想保留一阶和二阶相似度,而且是想要同时优化,以同时捕获局部成对相似性和节点邻域结构的相似性。对于一阶相似度的计算,将架构变成如上图,由左右两个自编码器组成。一阶相似度的目标是计算节点间的相似性,那么可以利用起中间的嵌入得到的隐层向量z,然后计算左侧嵌入和右侧嵌z入间的距离。并可以用拉普拉斯矩阵优化一下计算:
O 1 = ∑ ∣ ∣ z 1 − z 2 ∣ ∣ 2 2 = = 2 t r ( Z T L Z ) O_1=\sum ||z_1-z_2||^2_2==2tr(Z^TLZ) O1=z1z222==2tr(ZTLZ)

再加上正则项reg,总损失为: L = O 2 + α O 1 + v O r e g L=O_2+\alpha O_1+vO_{reg} L=O2+αO1+vOreg论文出自KDD 2016的《Structural Deep network Embedding》,作者的完整代码code开源:https://github.com/suanrong/SDNE

def __make_loss(self, config):
        def get_1st_loss_link_sample(self, Y1, Y2):
            return tf.reduce_sum(tf.pow(Y1 - Y2, 2))
        def get_1st_loss(H, adj_mini_batch):
            D = tf.diag(tf.reduce_sum(adj_mini_batch,1))
            L = D - adj_mini_batch ## 拉普拉斯矩阵
            return 2*tf.trace(tf.matmul(tf.matmul(tf.transpose(H),L),H))

        def get_2nd_loss(X, newX, beta):
            B = X * (beta - 1) + 1
            return tf.reduce_sum(tf.pow((newX - X)* B, 2))
		#对w和b的正则化项
        def get_reg_loss(weight, biases):
            ret = tf.add_n([tf.nn.l2_loss(w) for w in weight.itervalues()])
            ret = ret + tf.add_n([tf.nn.l2_loss(b) for b in biases.itervalues()])
            return ret
            
        #总损失函数
        self.loss_2nd = get_2nd_loss(self.X, self.X_reconstruct, config.beta)
        self.loss_1st = get_1st_loss(self.H, self.adjacent_matriX)
        self.loss_xxx = tf.reduce_sum(tf.pow(self.X_reconstruct,2)) 
        self.loss_reg = get_reg_loss(self.W, self.b) 
        return config.gamma * self.loss_1st + config.alpha * self.loss_2nd + config.reg * self.loss_reg

其实似乎这个建模的思路和矩阵分解是差不多的,只是在降维时用的不是矩阵分解,而是自编码器,并融入了一阶与二阶的概念。

在这里插入图片描述
Graph2vec
出自MLGWorkshop 2017的《graph2vec: Learning Distributed Representations of Graphs》
直接对整个图进行嵌入。一般比较容易想到的做法是Graph Pooling,著名的方法有Graph Coarsening,即用其他处理节点Embedding的方法处理后,然后逐渐合并聚类节点比如同一个class就归为一个超节点,最后变成一个向量。还有一类方法是node selection,即选部分的节点来代替。还有更直接的方法是直接max或者mean咯。

而Graph2Vec原理上和DeepWalk差不多,也是尝试借用word2vec来训练,只是这次为了嵌入整张图,所以尝试利用子图来训练。类似文档嵌入doc2vec,通过最大化作为输入的文档,来预测随机单词的可能性,Graph2vec预测图中子图的概率。

  • 采样子图。为了提高效率,采样只选当前节点周围的邻接节点,构成子图sg。
  • skip-gram。最大化输入图子图的概率 J ( Φ ) = − l o g P ( s g n ( d ) ∣ Φ ( G ) ) J(\Phi)=-log P(sg_n^{(d)}|\Phi(G)) J(Φ)=logP(sgn(d)Φ(G)),d为度,sg为子图。
    在这里插入图片描述
#把图处理成doc2vec问题的形式就可以用gensim了
from gensim.models.doc2vec import Doc2Vec, TaggedDocument

#得到Wisfeiler-Lehman特征
def do_a_recursion(self):
        new_features = {}
        for node in self.nodes:
            nebs = self.graph.neighbors(node)
            degs = [self.features[neb] for neb in nebs]
            features = [str(self.features[node])]+sorted([str(deg) for deg in degs])
            features = "_".join(features)
            hash_object = hashlib.md5(features.encode())
            hashing = hash_object.hexdigest()
            new_features[node] = hashing
        self.extracted_features = self.extracted_features + list(new_features.values())
        return new_features

作者开源:https://github.com/benedekrozemberczki/graph2vec

在这里插入图片描述

Graph Generative Adversarial Nets(GraphGAN)
主要是将GAN的思想引入到图领域,简单来说也是和GAN一样,分为生成器和判别器:

  • 生成器:在找网络中一个节点邻居的概率分布,也就是一个节点的连接偏好。 G ( v ∣ v c ) = e x p ( g v T g v c ) ∑ v ≠ v c e x p ( g v T g v c ) G(v|v_c)=\frac{exp(g^T_v g_{v_c})}{\sum_{v \neq v_c}exp(g^T_v g_{v_c}) } G(vvc)=v=vcexp(gvTgvc)exp(gvTgvc)即用softmax函数,输出邻居是每个节点的概率
  • 判别器:以网络中的边为出发点,衡量两个节点之间是否有边关系。 D ( v , v c ) = σ ( d v T d v c ) D(v,v_c)=\sigma(d^T_v d_{v_c}) D(v,vc)=σ(dvTdvc)d分别代表两个节点的表示向量,如果v是采样的应该给高分,如果是生成的应该是低分。

值得注意的是在生成器的G中,如果要对每个节点都算一遍显然不划算,所以作者的解决方案是以某个节点为根节点BFS遍历形成一棵生成树(其实挺像随机游走的),然后计算树中两个节点之间的边对应的概率。


Graph Neural Network
图神经网络(Graph Neural Network, GNN)也是很好的图嵌入方法。GNN包括图卷积神经网络(GCN),图注意力网络(GAT),Graph LSTM等等,虽然技术上还是和CV,NLP领域内的方法很像。。。

图表征学习的局限

  • 参数量大,每个顶点都有唯一的标准向量
  • 不能给未出现的顶点生成表征向量
  • 部分图表征学习不能融合属性特征等信息

最后献上很全很全的论文集:https://github.com/benedekrozemberczki/awesome-graph-classification

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Graph Embedding是一种将中的节点映射到低维向量空间的技术。通过Graph Embedding,我们可以将中的节点表示为具有语义信息的向量,从而方便进行机器学习和数据挖掘任务。Graph Embedding可以用于数据的可视化、节点分类、链接预测等任务。 在给定的引用中,提到了两种Graph Embedding的方法:DeepWalk和Struc2Vec。 1. DeepWalk是一种基于随机游走的Graph Embedding方法。它通过在中进行随机游走来模拟节点之间的邻近关系,并将游走序列作为训练样本来学习节点的向量表示。具体步骤如下[^1]: - 从中的每个节点开始,进行多次随机游走,得到游走序列。 - 使用Skip-gram模型训练节点的向量表示,使得节点的向量能够预测其周围节点出现的概率。 - 得到节点的向量表示,可以用于节点分类、链接预测等任务。 2. Struc2Vec是一种基于的结构相似性的Graph Embedding方法。它通过考虑节点的邻居节点和邻居节点之间的关系来学习节点的向量表示。具体步骤如下: - 构建的邻接矩阵,表示节点之间的连接关系。 - 使用随机游走的方式获取节点的邻居节点序列。 - 使用Skip-gram模型训练节点的向量表示,使得节点的向量能够预测其邻居节点出现的概率。 - 得到节点的向量表示,可以用于节点分类、链接预测等任务。 以上是关于Graph Embedding的简要介绍和两种常见方法的说明。如果你对具体的实现细节或其他相关问题感兴趣,请告诉我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值