日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从Deepwalk到Node2vec

發布時間:2025/3/8 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从Deepwalk到Node2vec 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上篇談到了deepwalk,整體流程就是按均勻分布從當前節點走到下一個節點,從而采樣到一條條“句子”,但是這樣采樣方式一定是對的嗎?邊上是否有權重影響呢?走回頭路的概率也是等于選擇其他鄰居節點的.為了使得walk的更合理,node2vec這篇論文給了一個通用的“游走”框架.同樣是通過游走產生句子,然后通過w2v產出向量.

DOTA:大有可為的GNN:DeepWalk

Node2vec

BFS和DFS大家再熟悉不過,node2vec就是結合了這兩種方式進行采樣.為什么要結合這兩種方式呢?因為對于圖而言,我們希望每個節點最終學到的向量既表達了同質關系也表達了拓撲關系.比如上圖中u和S1是相似的,因為他們之間空間上相近.又比如u和S6是相似的,雖然u和S6之間距離較遠,但是因為u和S6周圍都圍繞了4個節點,所以他們從拓撲上看是類似的.所以如何才能讓學到的向量能表達這種信息呢?node2vec就提出了一種隨機游走的框架,如下圖:

每個邊都有權重,當前節點的所有邊權重歸一化后就是當前節點到其他節點的概率.從上圖中我們可以看到,一共有3種類型的邊權重,第一種是<v,t>表示當前節點v和上一個節點之間的邊權重為1/p,第二種是<v,x1>表示當前節點和臨接上一個節點t的邊權重為1,第三種就是<v, other>表示與其他節點的邊權重為1/q.聰明的煉丹師已經發現,只要p=q=1,就是deepwalk.通過這種框架,如果p在0~1表示算法偏向于走回頭路,如果p>1則算法偏向于遠離上一個節點.同理如果q在0~1之間,則算法偏向于選擇遠離t,否則傾向于接近t.整個算法表示如下所示:

雖然有了一個通用框架是好事,但是我們需要調的參數也多了,我們看看實驗中調了哪些參數,如下所示:

我們可以發現,參數對F1-score的影響較大,因此要用的煉丹師們要耐心去調.從實驗結果來看,node2vec也表現較優.

代碼

這里代碼相較于deepwalk要稍微復雜一些,圖用networkx進行構建,構建過程不再贅述.

# 核心代碼 # 先由這個函數得到計算好的邊權重 def preprocess_transition_probs(self):''' Preprocessing of transition probabilities for guiding the random walks. '''G = self.Gis_directed = self.is_directedalias_nodes = {}for node in G.nodes():unnormalized_probs = [G[node][nbr]['weight'] for nbr in sorted(G.neighbors(node))]norm_const = sum(unnormalized_probs)normalized_probs = [float(u_prob)/norm_const for u_prob in unnormalized_probs]alias_nodes[node] = alias_setup(normalized_probs)alias_edges = {}triads = {}if is_directed:for edge in G.edges():alias_edges[edge] = self.get_alias_edge(edge[0], edge[1])else:for edge in G.edges():alias_edges[edge] = self.get_alias_edge(edge[0], edge[1])alias_edges[(edge[1], edge[0])] = self.get_alias_edge(edge[1], edge[0])self.alias_nodes = alias_nodesself.alias_edges = alias_edges# 再由這個函數找到路徑 def node2vec_walk(self, walk_length, start_node):''' Simulate a random walk starting from start node. start_node 起點 walk_length 要走的步數 '''G = self.Galias_nodes = self.alias_nodesalias_edges = self.alias_edgeswalk = [start_node]while len(walk) < walk_length:cur = walk[-1]cur_nbrs = sorted(G.neighbors(cur))if len(cur_nbrs) > 0:# 如果是root,則沒有上一個節點# 兩種情況下計算概率的方式不同if len(walk) == 1:walk.append(cur_nbrs[alias_draw(alias_nodes[cur][0], alias_nodes[cur][1])])else:prev = walk[-2]next = cur_nbrs[alias_draw(alias_edges[(prev, cur)][0], alias_edges[(prev, cur)][1])]walk.append(next)else:breakreturn walk

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的从Deepwalk到Node2vec的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。