CS224W课程学习笔记(四):node2vec算法原理与说明

article/2025/11/6 17:56:49

引言

什么是图嵌入?

我想从上节的deepwalk中已经有一个十分完整的轮廓了,这里引出deepwalk论文中的一张很形象的图(当然,上节的一些实战演练,也将这种嵌入关系进行了模拟与可视化,前文为:):
在这里插入图片描述

总的来说图嵌入技术大致可以分为两种:节点嵌入和图嵌入。当需要对节点进行分类,节点相似度预测,节点分布可视化时一般采用节点的嵌入;当需要在图级别(graph-level)上进行预测或者整个图结构越策,需要将整个图表示为一个向量进行嵌入表示。

图嵌入的好处以及坏处?

图嵌入的好处我认为是可以将图数据转换为低维向量,从而方便进行机器学习、数据挖掘、可视化等任务。图嵌入的坏处是可能会损失图的一些信息,如节点的属性、边的类型、子图的结构等。不同的图嵌入方法有不同的优缺点,需要根据具体的应用场景和需求来选择合适的方法。

以上一篇的deepwalk为例,它的随机游走方式如果是完全随机,那么会出现很多极端情况,比如它就往前迈一步,再回到原点,以及绕着一个方向不改变得走等等,而我们加了 α \alpha α系数后,相当于给了一个向心力,让它能尽量以圆的方式运作,但也有坏处,就是更趋向于BFS,而不是DFS了。这里一个很形象的例子,就是数据结构中的链表,一个链表所代表的元素都是未知的,我们如果需要添加元素,那得遍历整条流程线,或者以头尾指针的方式才能达成需求,但随机游走里并没有安排指针,所以某种程度上,不具备泛化能力,过拟合程度比较高。

本节的另一种算法——Node2Vec,算是解决了deepwalk的一些缺点,可以看做是deepwalk的一种扩展,是结合了DFS和BFS随机游走的deepwalk。

Node2Vec

Node2Vec 介绍

DeepWalk可以说给大家带来了全新的思路,其意义远不止实验结果那么简单。理论上,对于任何图数据,或者是由关系型数据抽象出来的图数据,都可以利用DeepWalk得到Embedding,而且算法简单,易于扩展到大规模数据上;更为重要的,这启发了后续的研究者进行了更加深入的研究。

node2vec的作者针对DeepWalk不能用到带权图上的问题,提出了概率游走的策略,并使用AliasSampling进行采样,该算法在之后会尝试讲解,这里主要提及一下它的创新点。

在node2vec之前,deepwalk的游走是完全随机的,虽然也能获取到非常多的信息,但相对而言比较局部,包括deepwalk、line等算法,都是用中间词预测周围词的方式,缺少采样策略,于是node2vec提出了它的随机游走策略公式:

P ( c i = x ∣ c i − 1 = v ) = { π v x Z if  ( v , x ) ∈ E 0 otherwise  P\left(c_i=x \mid c_{i-1}=v\right)= \begin{cases}\frac{\pi_{v x}}{Z} & \text { if }(v, x) \in E \\ 0 & \text { otherwise }\end{cases} P(ci=xci1=v)={Zπvx0 if (v,x)E otherwise 

给定一个起始节点 u u u,模拟随机游走的固定长度 l l l,上面为下一个节点 x x x 对于当前节点 v v v 的条件概率公式,其中, π v x {\pi_{v x}} πvx 是未归一化转移概率, Z Z Z 是是归一化常数。

为了让随机游走能够反映网络的结构和特征,我们能产生相应的偏置(bias),来控制随机游走,这里引述了一下传统方法的不适用性,比如说最简单的偏置方法是根据边的权重来选择下一个节点,即边越重,选择该边连接概率越大,用 w v x w_{vx} wvx 代表当前节点 v v v 和 下一节点 x x x的权重,那么此时 w v x = π v x w_{vx}={\pi_{v x}} wvx=πvx ,但这种策略很显然太空洞与不切实际,所以加入了两个超参数 p p p q q q 策略,来控制游走。假设当前随机游走经过边 ( t , v ) (t,v) (t,v) 到达顶点 v v v π v x = a p q ( t , v ) ⋅ w v , x {\pi_{v x}}=a_{pq}(t,v)\cdot w_{v,x} πvx=apq(t,v)wv,x,其中 w v x w_{vx} wvx 一样是节点 v v v 和 下一节点 x x x的权重,那另一项系数可写为:

α p q ( t , x ) = { 1 p = if  d t x = 0 1 = if  d t x = 1 1 q = if  d t x = 2 \alpha_{p q}(t, x)=\left\{\begin{array}{ll} \frac{1}{p}= & \text { if } d_{t x}=0 \\ 1= & \text { if } d_{t x}=1 \\ \frac{1}{q}= & \text { if } d_{t x}=2 \end{array}\right. αpq(t,x)= p1=1=q1= if dtx=0 if dtx=1 if dtx=2

d t x d_{tx} dtx 为 当前节点与下一节点的最短路径距离,这里论文中也解释了两个超参数的含义, q q qIn-out parameter p p pReturn parameter ,跟单词表达的意思一样,即 p p p 控制重复访问刚刚访问过的顶点的概率,而 q q q 控制控向外还是向内走的概率,而上述公式中还有一个1,可以理解成不动,或者在当前节点徘徊。可能这有点抽象,所以论文中给出了一张图:
在这里插入图片描述
这就十分清晰了,这里可以举个例子,当 p p p q q q 小时,属于DFS深度优先搜索,节点会朝 x 2 、 x 3 x2、x3 x2x3等更远方前进,而反过来,则会朝来时的 t t t 回退,或者说BFS广度优先搜索,探索周围的区域。

那么到这里,是论文的创新点,将随机游走变成了一种概率游走的方式采样序列,并且对节点的采样也做了相应的优化,即AliasSampling算法。

AliasSampling算法(别名采样算法)

这里参考Alias Method:时间复杂度O(1)的离散采样方法 和 【数学】时间复杂度O(1)的离散采样算法—— Alias method/别名采样方法

首先我举个我认为还算比较贴切的例子,当然可能有点现实。包括我在内,其实对于彩票行业,都是充满了兴趣,每次买完都心生向往,即使过程中被一再剥削,在结果没有开出前都觉得心里有一块着落、期盼,幻想着鱼跃龙门,花开彼岸。因为彩票就是一张纸,一个号码,每个人都觉得权重都是一样的,都有中奖的机会,这就是等概率分布抽样复杂度为O(1),但现实往往不是的,有些人位高权重,那自然能让自己的一亿分之一的概率变为十分之一以内,这里考虑多部门利益交互情况,所以,没有关系的普通人权重进一步被缩小,在没有黑手的情况下,全部人加起来可能也才十分之一,如果开奖的号码没有落入这十分之一,那可以说成两个集体,有权利的0.9,没有权的0.1,这就是二项分布抽样,复杂度也可看成是O(1)

上述英文原文中,用的例子我可以理解为红球、白球和篮球,每个有相应的概率,然后进行抽签,经典的古典概型问题。alias method就是把这两种方法结合起来。

假设,初始情况下球的概率分布为:
在这里插入图片描述
现在,缩放所有这些矩形,但我们不再使用最大值去进行归一化,而是按照 1 N \frac{1}{N} N1来均值归一化, 这里的例子是1/4变为1的概率,即为所有概率乘以N,为:

在这里插入图片描述
这时候再画条线,将前两个多余出来的部分填补到后两个框上,即:

在这里插入图片描述
而这里需要注意的是,Alias Method一定要保证:每列中最多只放两个事件,即最终呈现的效果应该是这样的:

在这里插入图片描述
所以照着这种规则,就能将该算法拆成两部分,一部分是生成Alias Table,该table包括了上面的一系列预处理,另一部就是采样,产生两个随机数,具体步骤如下:

生成Alias Table的步骤是:

  1. 根据要求的概率分布计算累积分布,映射到[0,1]的线段上;
  2. 将N个事件的概率乘以N,得到一个新的概率数组q;
  3. 将q中小于1的元素放入一个队列smaller,将大于等于1的元素放入另一个队列larger;
  4. 从smaller中弹出一个元素i,从larger中弹出一个元素j;
  5. 在第i行第一列填入事件i,在第i行第二列填入事件j,在第j行第一列填入事件j;
  6. 将q[j]减去(1-q[i]),如果结果小于1,则将j放回smaller,否则将j放回larger;
  7. 重复步骤4-6,直到smaller或larger为空。

根据Alias Table采样的步骤是:

  1. 随机生成[1,N]之间的一个整数k,确定选中哪一行;
  2. 随机生成[0,1]之间的一个数p,根据概率判断是取样该行的第一列还是第二列;
  3. 如果p小于q[k],则输出该行第一列对应的事件;否则输出该行第二列对应的事件。

而上面我参考的知乎贴里,已经复现出来了该代码:

import numpy as np
def gen_prob_dist(N):p = np.random.randint(0,100,N)return p/np.sum(p)def create_alias_table(area_ratio):l = len(area_ratio)accept, alias = [0] * l, [0] * lsmall, large = [], []for i, prob in enumerate(area_ratio):if prob < 1.0:small.append(i)else:large.append(i)while small and large:small_idx, large_idx = small.pop(), large.pop()accept[small_idx] = area_ratio[small_idx]alias[small_idx] = large_idxarea_ratio[large_idx] = area_ratio[large_idx] - (1 - area_ratio[small_idx])if area_ratio[large_idx] < 1.0:small.append(large_idx)else:large.append(large_idx)while large:large_idx = large.pop()accept[large_idx] = 1while small:small_idx = small.pop()accept[small_idx] = 1return accept,aliasdef alias_sample(accept, alias):N = len(accept)i = int(np.random.random()*N)r = np.random.random()if r < accept[i]:return ielse:return alias[i]def simulate(N=100,k=10000,):truth = gen_prob_dist(N)area_ratio = truth*Naccept,alias = create_alias_table(area_ratio)ans = np.zeros(N)for _ in range(k):i = alias_sample(accept,alias)ans[i] += 1return ans/np.sum(ans),truthif __name__ == "__main__":alias_result,truth = simulate()

上面的步骤,我基本上就是对照着代码和参考文献里改写的,所以可以打印一下最后两个返回值,alias_result 即是分好类的Alias Table,而truth 即是原始值,即按最大值进行平均的全概率集合。

更详细的对于该种算法的存在性证明可以看参考中的推导。

Node2Vec算法详细步骤

在这里插入图片描述
其中PreprocessModifiedWeights是生成随机游走采样策略,然后生成随机游走序列,中间的node2vecWalk采样策略按照之前的全概率公式,即我上面所举的例子,14亿人买彩票,那时间复杂度是 O ( n ) O(n) O(n),而用了AliaSample采样后,时间复杂度变为了 O ( 1 ) O(1) O(1),具体原因在上一节,这里是用空间(预处理)换时间,适用于大量反复的抽样情况下,将离散分布抽样转化为均匀分布抽样。那么还是找个例子,我如果是个普通人,用该种采样策略,我的概率变了嘛?答案当然是没变,我依然是1/14亿,计算如下:
在这里插入图片描述
最开始的第二列的概率是1/3(1/2,1/3,1/12,1/12),然后改变了平均策略后,最终如上图,我的第二列概率为第二列本来的0.25 = 1/4,加上第一列被平均的1/3 * 1/4 = 1/12,最终结果依然是1/3,证必。

而根据随机(概率)游走策略后,即node2vecWalk,后面还有一部为 StochasticGradientDesc,论文中同样针对该优化策略进行了创新,引入了负采样的方式来减小计算量。

node2vec是一种图嵌入方法,它可以综合考虑深度优先搜索(DFS)邻域和广度优先搜索(BFS)邻域。它的优化目标是最大化每个节点与其采样邻居的相似度。

node2vec的目标函数是最大化给定一个节点 u u u,其邻域节点集合 N S ( u ) N_S(u) NS(u)出现的条件概率:

max ⁡ f ∑ u ∈ V log ⁡ P r ( N S ( u ) ∣ f ( u ) ) \max_f \sum_{u \in V} \log Pr(N_S(u)|f(u)) fmaxuVlogPr(NS(u)f(u))

其中 f ( u ) f(u) f(u)是将节点u映射为低维向量的函数, V V V是图中所有节点的集合,S是采样策略。

根据链式法则,上述条件概率可以分解为:

P r ( N S ( u ) ∣ f ( u ) ) = ∏ n i ∈ N S ( u ) P r ( n i ∣ f ( u ) , n 1 , … , n i − 1 ) Pr(N_S(u)|f(u)) = \prod_{n_i \in N_S(u)} Pr(n_i|f(u), n_1, …, n_{i-1}) Pr(NS(u)f(u))=niNS(u)Pr(nif(u),n1,,ni1)

其中 n i n_i ni是从节点 u u u开始的随机游走中第 i i i个访问的节点。

为了简化计算,node2vec提出了条件独立性假设,每个 n i n_i ni只依赖于前一个节点 n i − 1 n_{i-1} ni1,即:

P r ( n i ∣ f ( u ) , n 1 , … , n i − 1 ) ≈ P r ( n i ∣ f ( n i − 1 ) ) Pr(n_i|f(u), n_1, …, n_{i-1}) \approx Pr(n_i|f(n_{i-1})) Pr(nif(u),n1,,ni1)Pr(nif(ni1))

这样就可以使用word2vec中的skip-gram模型来估计这个概率。然后第二种假设为特征空间对称性假设,一个顶点作为源顶点和作为近邻顶点的时候共享同一套embedding向量。具体地,对于每个源节点 u u u和目标节点 v v v,定义一个得分函数 s ( f ( u ) , f ( v ) ) s(f(u), f(v)) s(f(u),f(v))来衡量它们在特征空间中的相似度。通常使用点积作为得分函数:

s ( f ( u ) , f ( v ) ) = f ( u ) T f ( v ) s(f(u), f(v)) = f(u)^T f(v) s(f(u),f(v))=f(u)Tf(v)

然后使用softmax函数将得分转换为概率:

P r ( n i = v ∣ f ( n i − 1 ) = u ) = exp ⁡ ( s ( f ( u ) , f ( v ) ) ) ∑ v ’ ∈ V exp ⁡ ( s ( f ( u ) , f ( v ’ ) ) ) Pr(n_i = v|f(n_{i-1}) = u) = \frac{\exp(s(f(u), f(v)))}{\sum_{v’ \in V} \exp(s(f(u), f(v’)))} Pr(ni=vf(ni1)=u)=vVexp(s(f(u),f(v)))exp(s(f(u),f(v)))

由于softmax函数涉及对所有可能的 v v v 求和,计算代价很高。因此node2vec采用了负采样技术来近似softmax。

负采样是一种提高训练速度并改善词向量质量的方法,它的思想是对每个正例(即真实存在于邻域中的节点对)采样 K K K 个负例(即随机选择不在邻域中的节点对),然后用二元逻辑回归来区分正例和负例,这其实只是更新一小部分权重,而不是所有权重。

具体地,对于每个正例 ( u , v ) (u, v) u,v,定义如下损失函数:

J p o s ( u , v ) = − log ⁡ ( σ ( s ( f ( u ) , f ( v ) ) ) ) − ∑ i = 1 K E v n P n ( v ) [ log ⁡ ( σ ( − s ( f ( u ) , f ( v n ) ) ) ) ] J_{pos}(u, v) = -\log(\sigma(s(f(u), f(v)))) - \sum_{i=1}^{K} E_{v_n ~ P_n(v)} [\log(\sigma(-s(f(u), f(v_n))))] Jpos(u,v)=log(σ(s(f(u),f(v))))i=1KEvn Pn(v)[log(σ(s(f(u),f(vn))))]

其中 σ \sigma σ是sigmoid函数, P n ( v ) P_n(v) Pn(v)是从图中抽取负例的分布(通常与度数成正比), v n v_n vn是第 i i i 个负例。

最终node2vec要优化如下目标函数:

max ⁡ f J = ∑ ( u , v ) ∈ D J p o s ( u , v ) \max_f J = \sum_{(u,v) \in D} J_{pos}(u,v) fmaxJ=(u,v)DJpos(u,v)

其中 D D D 是由随机游走产生的所有正例组成的数据集。

那么推导完毕,代码的复现依然还是上节中浅梦大佬的笔记:

【Graph Embedding】node2vec:算法原理,实现和应用

以及他此项目的GitHub:

https://github.com/shenweichen/GraphEmbedding

Node2Vec代码复现

这里采用他的代码复现一下。根据GitHub中的安装方式安装ge包,然后在examples目录下运行node2vec_wiki.py,该文件代码为:

import numpy as npfrom ge.classify import read_node_label, Classifier
from ge import Node2Vec
from sklearn.linear_model import LogisticRegressionimport matplotlib.pyplot as plt
import networkx as nx
from sklearn.manifold import TSNE# 定义一个函数来评估嵌入效果
def evaluate_embeddings(embeddings):# 从文件中读取节点标签X, Y = read_node_label('../data/wiki/wiki_labels.txt')# 设置训练集比例为80%tr_frac = 0.8print("Training classifier using {:.2f}% nodes...".format(tr_frac * 100))# 使用逻辑回归作为分类器,并用嵌入作为特征clf = Classifier(embeddings=embeddings, clf=LogisticRegression())# 划分训练集和测试集,并评估分类效果clf.split_train_evaluate(X, Y, tr_frac)# 定义一个函数来可视化嵌入结果
def plot_embeddings(embeddings):# 从文件中读取节点标签X, Y = read_node_label('../data/wiki/wiki_labels.txt')emb_list = []for k in X:emb_list.append(embeddings[k])emb_list = np.array(emb_list)# 使用TSNE降维到二维空间model = TSNE(n_components=2)node_pos = model.fit_transform(emb_list)color_idx = {}for i in range(len(X)):color_idx.setdefault(Y[i][0], [])color_idx[Y[i][0]].append(i)# 根据不同标签画出不同颜色的点   for c, idx in color_idx.items():plt.scatter(node_pos[idx, 0], node_pos[idx, 1], label=c)plt.legend()plt.show()if __name__ == "__main__":# 从文件中读取图数据,创建有向有权图对象   G=nx.read_edgelist('../data/wiki/Wiki_edgelist.txt',create_using = nx.DiGraph(), nodetype = None, data = [('weight', int)])# 创建node2vec模型对象,设置相关参数    model = Node2Vec(G, walk_length=10, num_walks=80,p=0.25, q=4, workers=1, use_rejection_sampling=0)# 训练模型,设置窗口大小和迭代次数    model.train(window_size = 5, iter = 3)# 获取节点嵌入结果    embeddings=model.get_embeddings()# 调用之前定义的函数,评估和可视化嵌入效果    evaluate_embeddings(embeddings)plot_embeddings(embeddings) 

其中wiki_label中是17类,即0到16,我们可以运行该文件,查看输出结果:

R740:/home/program/test/GraphEmbedding/examples# python3 node2vec_wiki.py
Preprocess transition probs...
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    3.7s finished
Learning embedding vectors...
Learning embedding vectors done!
Training classifier using 80.00% nodes...
/home/anaconda3/envs/open-mmlab/lib/python3.7/site-packages/sklearn/metrics/_classification.py:1580: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no true nor predicted samples. Use `zero_division` parameter to control this behavior._warn_prf(average, "true nor predicted", "F-score is", len(true_sum))
/home/anaconda3/envs/open-mmlab/lib/python3.7/site-packages/sklearn/metrics/_classification.py:1580: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no true nor predicted samples. Use `zero_division` parameter to control this behavior._warn_prf(average, "true nor predicted", "F-score is", len(true_sum))
-------------------
{'micro': 0.6756756756756757, 'macro': 0.5947126880104103, 'samples': 0.6756756756756757, 'weighted': 0.6743062291097495, 'acc': 0.6756756756756757}
/home/anaconda3/envs/open-mmlab/lib/python3.7/site-packages/sklearn/manifold/_t_sne.py:783: FutureWarning: The default initialization in TSNE will change from 'random' to 'pca' in 1.2.FutureWarning,
/home/anaconda3/envs/open-mmlab/lib/python3.7/site-packages/sklearn/manifold/_t_sne.py:793: FutureWarning: The default learning rate in TSNE will change from 200.0 to 'auto' in 1.2.FutureWarning,

日志输出中打印了几个评估函数,它们的具体分数为:

{'micro': 0.6756756756756757, 'macro': 0.5947126880104103, 'samples': 0.6756756756756757, 'weighted': 0.6743062291097495, 'acc': 0.6756756756756757}

相关的聚类图如下:
在这里插入图片描述

关于node2Vec的底层代码,可以查看上面提到的链接,有解释源码中的preprocess_transition_probsget_alias_edgenode2vec_walk,第一个函数是构造采样表,第二个函数是概率转换,即开头我所提到的创新,将随机游走变为了概率游走,第三个函数就是加入了alias sample算法的采样器。

当然,node2vec自己也创建了一个包,直接根据pip install node2vec下载,算是官方包,也是视频课程所用到的。

node2Vec包实战

本节根据B站视频同济子豪兄相关说明,代码参考自Task05 Node2Vec论文精读

1. 导入工具包与默认安装的数据集:

import networkx as nx
import numpy as np
import randomimport matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei']   
plt.rcParams['axes.unicode_minus']=False  # 《悲惨世界》人物数据集
G = nx.les_miserables_graph()

2. 构建Node2Vec模型

from node2vec import Node2Vec# 设置node2vec参数
node2vec = Node2Vec(G, dimensions=32,  # 嵌入维度p=1,            # 回家参数q=3,            # 外出参数walk_length=10, # 随机游走最大长度num_walks=600,  # 每个节点作为起始节点生成的随机游走个数workers=4       # 并行线程数
)# p=1, q=0.5, n_clusters=6。DFS深度优先搜索,挖掘同质社群
# p=1, q=2, n_clusters=3。BFS宽度优先搜索,挖掘节点的结构功能。# 训练Node2Vec
model = node2vec.fit(window=3,     # Skip-Gram窗口大小min_count=1,  # 忽略出现次数低于此阈值的节点(词)batch_words=4 # 每个线程处理的数据量
)
X = model.wv.vectors

在这里插入图片描述

3. 节点Embedding聚类可视化

# KMeans聚类
from sklearn.cluster import KMeans
import numpy as np
cluster_labels = KMeans(n_clusters=3).fit(X).labels_
print(cluster_labels)# 将networkx中的节点和词向量中的节点对应
colors = []
nodes = list(G.nodes)
# 按 networkx 的顺序遍历每个节点
for node in nodes:# 获取这个节点在 embedding 中的索引号idx = model.wv.key_to_index[str(node)] # 获取这个节点的聚类结果colors.append(cluster_labels[idx]) 
"""
[0 0 0 0 0 2 2 0 2 1 2 2 0 0 0 0 2 0 0 0 2 2 1 1 1 1 1 1 1 0 0 0 0 0 0 0 02 0 0 0 2 2 0 2 2 2 2 0 0 0 0 0 2 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0]
"""

4. 可视化聚类结果

plt.figure(figsize=(15,14))
pos = nx.spring_layout(G, seed=10)
nx.draw(G, pos, node_color=colors, with_labels=True)
plt.show()

在这里插入图片描述

node2vec降维可视化

# 将Embedding用PCA降维到2维
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
embed_2d = pca.fit_transform(X)plt.scatter(embed_2d[:, 0], embed_2d[:, 1])
plt.show()

在这里插入图片描述

还可以对Edge(连接)做Embedding:

from node2vec.edges import HadamardEmbedder# Hadamard 二元操作符:两个 Embedding 对应元素相乘
edges_embs = HadamardEmbedder(keyed_vectors=model.wv)# 查看 任意两个节点连接 的 Embedding
edges_embs[('Napoleon', 'Champtercier')]"""
array([-1.32887985e-03,  4.66461703e-02,  4.09327209e-01,  9.96602178e-02,6.26228750e-02,  5.16123235e-01,  3.31034124e-01,  8.28218937e-01,7.78538138e-02,  1.39643205e-02,  5.18605635e-02,  7.23598641e-04,3.80857401e-02,  2.59436034e-02,  2.91174115e-03,  2.69687593e-01,3.69817726e-02,  9.54697747e-03,  2.63099521e-01,  1.34550110e-01,8.09033439e-02,  6.05619431e-01,  3.74024451e-01,  8.45154063e-05,1.11978855e-02, -5.34820855e-02,  5.61549842e-01,  8.59113395e-01,1.65469334e-01,  6.88703060e-02,  1.19110994e-01,  6.94330484e-02],dtype=float32)
"""

计算# 计算所有 Edge 的 Embedding,查看与某两个节点最相似的节点对:

# 计算所有 Edge 的 Embedding
edges_kv = edges_embs.as_keyed_vectors()
# 查看与某两个节点最相似的节点对
edges_kv.most_similar(str(('Bossuet', 'Valjean')))

在这里插入图片描述


http://chatgpt.dhexx.cn/article/9rWiNgg4.shtml

相关文章

08-Node.js—nvm

目录 1、介绍2、使用2.1 下载安装2.2 常用命令2.2.1 nvm list available2.2.2 nvm list2.2.3 nvm install 18.12.12.2.4 nvm install latest2.2.5 nvm uninstall 18.12.12.2.6 nvm use 18.12.1 参考 1、介绍 nvm 全称 Node Version Manager 顾名思义它是用来管理 node 版本的工…

笔记︱基于网络节点的node2vec、论文、算法python实现

看到一个很有意思的算法&#xff0c;而且腾讯朋友圈lookalike一文中也有提及到&#xff0c;于是蹭一波热点&#xff0c;学习一下。论文是也发KDD2016 . . 一、主要论文&#xff1a;node2vec: Scalable Feature Learning for Networks 本节引用自 a、微博洪亮劼 &#xff1a…

论文阅读:node2vec: Scalable Feature Learning for Networks

node2vec: Scalable Feature Learning for Networks 摘要 基于网络中节点和边的预测任务中的特征工程总是很麻烦的。虽然表示学习的自动学习特征已经有很大的帮助&#xff0c;但现有的特征学习方式无法对网络中连接模式的多样性进行足够的捕捉。 node2vec是本论文提出的一种…

node2vec笔记

node2vec论文&#xff1a;https://dl.acm.org/citation.cfm?id2939754 node2vec作者KDD口头报告视频&#xff1a;https://www.youtube.com/watch?v1_QH5BEP5BM node2vec是deepwalk的一个扩展&#xff0c;主要考虑了两点&#xff1a;(1)邻近性&#xff0c;即节点在图上的距离…

图嵌入 Node2Vec

文章目录 图嵌入之 Node2Vec1 两个概念2 两种节点采样方法3 Node2Vec 中的二阶 Random Walk3.1 Random Walks 的定义3.2 搜索偏置 α \alpha α 4 二阶 Random Walk 的优势5 算法步骤 图嵌入之 Node2Vec 论文地址 https://arxiv.org/pdf/1607.00653.pdf 对 Random Walk 中随机…

node2vec的一些思考

概述 论文主要观点 本文将抽取网络中节点的特征转化成最优化一个“可能性”目标函数问题&#xff0c;这个“可能性”是该节点可以保存其邻居节点的信息。 成果 node2vec&#xff0c;如上述&#xff0c;利用SGD优化&#xff0c;高效“随机选择邻居”算法&#xff0c;可让node2v…

Node(二)

一、node的文件系统 1、二进制文件的读写&#xff08;按字节读写&#xff1a;一个字节是8个二进制位&#xff09; &#xff08;1&#xff09;读二进制文件 fs.read(fd&#xff0c;buffer&#xff0c;offset&#xff0c;length&#xff0c;position&#xff0c;callback) fd…

【论文精读】node2vec: Scalable Feature Learning for Networks

node2vec: Scalable Feature Learning for Networks 可扩展的 图嵌入 表示学习算法 可扩展&#xff1a;算法可用于互联网规模级别的数据&#xff0c;在有限的时间和空间中 图嵌入&#xff1a;将图的连接信息嵌入到连续、低维、稠密的D维空间中 表示学习&#xff1a;用数据驱…

Graph Embedding(DeepWalk,LINE,Node2vec)

为什么要对图进行嵌入&#xff1f; 直接在这种非结构的&#xff0c;数量不定&#xff08;可能数目非常多&#xff09;&#xff0c;属性复杂的 图 上进行机器学习/深度学习是很困难的&#xff0c;而如果能处理为向量将非常的方便。但评价一个好的嵌入需要&#xff1a; 保持图属…

深度学习 - 33.GraphEmbedding Node2vec 图文详解

一.引言 前面介绍了如何生成带权的图: GraphEmbedding - networkx获取图结构 从带权的图随机游走生成序列: GraphEmbedding - DeepWalk 随机游走 embedding 向量的评估与可视化: GraphEmbedding - embedding 向量的降维与可视化 以及复杂度O(1)的采样算法 Alias: GraphEmbe…

Node2Vec算法介绍

大家好&#xff0c;我是Linzhuo&#xff0c;今天又来给大家分享graph embedding的相关知识啦。 在上一篇文章中&#xff0c;我们介绍了graph embedding的经典方法&#xff1a;Deepwalk&#xff0c;其通过随机游走(Random walk)的方式将Graph embedding与Word embedding的方法(w…

KDD 2016 | node2vec:Scalable Feature Learning for Networks

目录 前言Abstract1.IntroductionPresent work 2.Related Work3.Feature Learning Framework3.1 Classic search strategies3.2 node2vec3.2.1 Random Walks3.2.2 Search bias α \alpha α3.2.3 The node2vec algorithm 3.3 Learning edge features 4.Experiments4.1 Case St…

PyG基于Node2Vec实现节点分类及其可视化

文章目录 前言一、导入相关库二、加载Cora数据集三、定义Node2Vec四、定义模型五、模型训练六、可视化完整代码前言 大家好,我是阿光。 本专栏整理了《图神经网络代码实战》,内包含了不同图神经网络的相关代码实现(PyG以及自实现),理论与实践相结合,如GCN、GAT、GraphS…

浅析 v-node

浅析 v-node &#x1f308; 本节我们来探索一下虚拟DOM&#xff0c;将会从以下4个方面进行阐述&#xff1a; 虚拟DOM的本质虚拟DOM的优势虚拟DOM转换真实DOM 过程虚拟DOM树 diff算法 虚拟DOM的本质 ⭐️虚拟DOM 本质上是一个 js 对象&#xff0c;用于描述页面的结构&#x…

deepwalknode2vec 代码实战

提示&#xff1a;笔记内容来自于B站up主同济子豪兄 文章目录 1. Embedding嵌入的艺术2. deepwalk2.1. 什么是图嵌入&#xff1f;2.2. deepwalk的步骤1、生成graph&#xff1b;2、利用random walk生成多个路径&#xff1b;3、训练表示向量的学习&#xff1b;4、为了解决分类个数…

Node2Vec

Node2Vec 论文名称&#xff1a;node2vec: Scalable Feature Learning for Networks 论文地址&#xff1a;https://www.kdd.org/kdd2016/papers/files/rfp0218-groverA.pdf Node2Vec是用于学习网络节点的连续特征表示。node2vec将节点映射为低维特征表示&#xff0c;最大化网…

node2vec python 实现和理解

1. 安装 pip install node2vec 2. 使用案例 import networkx as nx from node2vec import Node2Vec# Create a graph 这里可以给出自己的graph graph nx.fast_gnp_random_graph(n100, p0.5)# Precompute probabilities and generate walks - **ON WINDOWS ONLY WORKS WITH …

node2vec的一些理解

node2vec node2vec也是一种网络嵌入的表示方法&#xff0c;它是基于DeepWalk的基础上进行改进的。主要改进的地方在于它在随机游走的过程中加入了一个权重&#xff0c;使得游走可以采用深度优先和广度优先的策略进行游走。 Search bias α 使得随机游走产生片偏差的最简单的…

从word2vec到node2vec

word2vec 1. 什么是word2vec 在自然语言处理任务&#xff08;NLP&#xff09;中&#xff0c;最细粒度是词语&#xff0c;所以处理NLP问题&#xff0c;首先要处理好词语。 由于所有自然语言中的词语&#xff0c;都是人类的抽象总结&#xff0c;是符号形式的。而对于数学模型&a…

详解Node2vec以及优缺点

1. 论文介绍 首先介绍了复杂网络面对的几种任务&#xff1a; 网络节点的分类&#xff0c;通俗点说就是将网络中的节点进行聚类&#xff0c;我们关心的是哪些节点具有类似的属性&#xff0c;就将其分到同一个类别中。链接预测&#xff0c;就是预测网络中哪些顶点有潜在的关联。…