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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

node2vec的一些理解

發(fā)布時間:2023/12/31 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 node2vec的一些理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

node2vec

node2vec也是一種網(wǎng)絡嵌入的表示方法,它是基于DeepWalk的基礎上進行改進的。主要改進的地方在于它在隨機游走的過程中加入了一個權重,使得游走可以采用深度優(yōu)先和廣度優(yōu)先的策略進行游走。

Search bias α

使得隨機游走產生片偏差的最簡單的方法是根據(jù)靜態(tài)邊緣權重WvxW_vxWv?x進行采樣,在未加權圖的情況下Wvx=1W_{vx}=1Wvx?=1,但是這并不能解釋我們的網(wǎng)絡結構,并且指導我們探索不同的網(wǎng)絡鄰居。此外,與BFS和DFS不同,BFS和DFS是分別適用于結構等價性和同質性的極端抽樣范式,我們的隨機游動應該適應這樣一個事實:這些等價性的概念不是競爭的或排他的,而現(xiàn)實世界的網(wǎng)絡通常表現(xiàn)出兩者的混合。
所以我們定義了一個2階隨機游走,并且定義了兩個參數(shù)分別是p和q用來指導我們進行隨機游走。

假設我們有一個隨機游走已經(jīng)穿過了(t,v)節(jié)點并且現(xiàn)在暫時居住在如圖所示的V節(jié)點。我們現(xiàn)在要考慮下一步怎么走,那么我們可以使用邊(v,x)的轉移概率ΠvxΠ_{vx}Πvx?用來引導我們從v的下一步怎么走。我們假定了一個轉移概率Πvx=αpq(t,x)?WvxΠ_vx=α_{pq}(t,x)*W_{vx}Πv?x=αpq?(t,x)?Wvx? 其中αpq(t,x)α_{pq}(t,x)αpq?(t,x)定義如下:

其中dtxd_{tx}dtx?表示t和x之間的最短路徑,注意的是dtxd_{tx}dtx?的取值一定是{0,1,2}的其中一個,所以p,q兩個參數(shù)能夠很好的指導游走。
例如當終點為t時,我們相當于往回走了,不為t時我們則是向外游走或是向深游走。
返回參數(shù) p:p代表我們游走時重復游走的可能性,如果我們把p設置為一個很高的值(> max(q,1))則可以用來確保我們有極小的可能性重復游走一個節(jié)點(除非下一個節(jié)點沒有其他鄰居)。這個策略鼓勵我們適度探索,而不是產生冗余。另一方面,如果我們把p的值設為很小(< min(q,1)),則他會使得walk接近我們的起始位置。
In-Out參數(shù) q:他更傾向于訪問距離節(jié)點t更遠的節(jié)點,這種行為反映了鼓勵向外探索的DFS。然而,這里的一個本質區(qū)別是,我們在隨機行走框架中實現(xiàn)了類似DFS的探索。

node2vec 算法流程


如上圖所示,我們一開始主要是要進行我們的靜態(tài)權重的賦值,用它來引導我們繼續(xù)隨機游走得到隨機游走序列,然后我們將得到的序列利用skip-gram模型進行嵌入,最后得到嵌入矩陣。

def _precompute_probabilities(self):"""Precomputes transition probabilities for each node."""d_graph = self.d_graphnodes_generator = self.graph.nodes() if self.quiet \else tqdm(self.graph.nodes(), desc='Computing transition probabilities')for source in nodes_generator:# Init probabilities dict for first travelif self.PROBABILITIES_KEY not in d_graph[source]:d_graph[source][self.PROBABILITIES_KEY] = dict()for current_node in self.graph.neighbors(source):# Init probabilities dictif self.PROBABILITIES_KEY not in d_graph[current_node]:d_graph[current_node][self.PROBABILITIES_KEY] = dict()unnormalized_weights = list()d_neighbors = list()# Calculate unnormalized weightsfor destination in self.graph.neighbors(current_node):p = self.sampling_strategy[current_node].get(self.P_KEY,self.p) if current_node in self.sampling_strategy else self.pq = self.sampling_strategy[current_node].get(self.Q_KEY,self.q) if current_node in self.sampling_strategy else self.qif destination == source: # Backwards probabilityss_weight = self.graph[current_node][destination].get(self.weight_key, 1) * 1 / pelif destination in self.graph[source]: # If the neighbor is connected to the sourcess_weight = self.graph[current_node][destination].get(self.weight_key, 1)else:ss_weight = self.graph[current_node][destination].get(self.weight_key, 1) * 1 / q# Assign the unnormalized sampling strategy weight, normalize during random walkunnormalized_weights.append(ss_weight)d_neighbors.append(destination)# Normalizeunnormalized_weights = np.array(unnormalized_weights)d_graph[current_node][self.PROBABILITIES_KEY][source] = unnormalized_weights / unnormalized_weights.sum()# Save neighborsd_graph[current_node][self.NEIGHBORS_KEY] = d_neighbors# Calculate first_travel weights for sourcefirst_travel_weights = []for destination in self.graph.neighbors(source):first_travel_weights.append(self.graph[source][destination].get(self.weight_key, 1))first_travel_weights = np.array(first_travel_weights)d_graph[source][self.FIRST_TRAVEL_KEY] = first_travel_weights / first_travel_weights.sum()

具體代碼實現(xiàn)如圖所示,我們首先進入函數(shù)利用d_graph生成一個字典,在其中加入概率標簽,然后我們通過循環(huán)節(jié)點以及節(jié)點的鄰居對權重進行賦值,同時對我們的p,q進行策略的更改。最后的d_graph則是我們修改之后的帶有我們設置的權重的重要參數(shù),然后我們將d_graph帶入到我們的游走序列生成的函數(shù)當中去。

def parallel_generate_walks(d_graph: dict, global_walk_length: int, num_walks: int, cpu_num: int,sampling_strategy: dict = None, num_walks_key: str = None, walk_length_key: str = None,neighbors_key: str = None, probabilities_key: str = None, first_travel_key: str = None,quiet: bool = False) -> list:"""Generates the random walks which will be used as the skip-gram input.:return: List of walks. Each walk is a list of nodes."""walks = list()if not quiet:pbar = tqdm(total=num_walks, desc='Generating walks (CPU: {})'.format(cpu_num))for n_walk in range(num_walks):# Update progress barif not quiet:pbar.update(1)# Shuffle the nodesshuffled_nodes = list(d_graph.keys())random.shuffle(shuffled_nodes)# Start a random walk from every nodefor source in shuffled_nodes:# Skip nodes with specific num_walksif source in sampling_strategy and \num_walks_key in sampling_strategy[source] and \sampling_strategy[source][num_walks_key] <= n_walk:continue# Start walkwalk = [source]# Calculate walk lengthif source in sampling_strategy:walk_length = sampling_strategy[source].get(walk_length_key, global_walk_length)else:walk_length = global_walk_length# Perform walkwhile len(walk) < walk_length:walk_options = d_graph[walk[-1]].get(neighbors_key, None)# Skip dead end nodesif not walk_options:breakif len(walk) == 1: # For the first stepprobabilities = d_graph[walk[-1]][first_travel_key]walk_to = np.random.choice(walk_options, size=1, p=probabilities)[0]else:probabilities = d_graph[walk[-1]][probabilities_key][walk[-2]]walk_to = np.random.choice(walk_options, size=1, p=probabilities)[0]walk.append(walk_to)walk = list(map(str, walk)) # Convert all to stringswalks.append(walk)if not quiet:pbar.close()return walks

生成游走的序列的代碼如上圖所示,我們可以看出將d_graph當中的概率取出,然后帶入到np.random.choice這個函數(shù)當中去,這樣我們就是按照一定的概率進行隨機游走,而游走的概率是可以通過修改p,q兩個參數(shù)進而進行修改的。最后我們則將我們得到的游走序列walks帶入skip-gram模型進行訓練,得到我們想要的嵌入矩陣。

def fit(self, **skip_gram_params):"""Creates the embeddings using gensim's Word2Vec.:param skip_gram_params: Parameteres for gensim.models.Word2Vec - do not supply 'size' it is taken from the Node2Vec 'dimensions' parameter:type skip_gram_params: dict:return: A gensim word2vec model"""if 'workers' not in skip_gram_params:skip_gram_params['workers'] = self.workersif 'size' not in skip_gram_params:skip_gram_params['size'] = self.dimensionsreturn gensim.models.Word2Vec(self.walks, **skip_gram_params)

總結

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

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