圖機器學習(11)——鏈接預測

圖機器學習(11)——鏈接預測

    • 0. 鏈接預測
    • 1. 基于相似性的方法
      • 1.1 基于指標的方法
      • 1.2 基于社區的方法
    • 2. 基于嵌入的方法

0. 鏈接預測

鏈接預測 (link prediction),也稱為圖補全,是處理圖時常見的問題。具體而言,給定一個部分觀測的圖(即某些節點對之間是否存在邊無法確定),我們的目標是預測未知狀態節點對之間是否存在邊,如下圖所示。

鏈接預測

設圖 G=(V,E)G=(V,E)G=(V,E) 的節點集為 VVV,邊集為 E=Eo∪EuE=E_o\cup E_uE=Eo?Eu?。其中,邊集 EoE_oEo? 表示已知邊(觀測到的鏈接),而邊集 EuE_uEu? 表示未知邊(待預測的鏈接)。鏈接預測的目標是利用 VVVEoE_oEo? 的信息來估計 EuE_uEu?。該問題在時序圖數據中同樣常見。在此設定下,假設 GtG_tGt? 是在時間點 ttt 觀測到的圖,我們的目標是預測該圖在時間點 t+1t+1t+1 的邊。
鏈接預測問題在各領域均有廣泛應用:在社交網絡中用于推薦好友關系,在電子商務平臺中用于推薦商品;在生物信息學中則用于分析蛋白質相互作用。接下來,我們將介紹解決鏈接預測問題的兩類方法——即基于相似性的方法和基于嵌入的方法。

1. 基于相似性的方法

本節介紹若干解決標簽預測問題的簡單算法,其核心思想是通過計算圖中節點對的相似度函數來預測連接概率:若節點相似度高,則它們有較高的概率通過一條邊連接。這些算法可分為兩類:基于索引的方法和基于社區的方法。前者通過簡單計算節點鄰居關系指標得出結果,后者則使用關于節點所屬社區的信息進行計算。接下來,以 networkx 庫(具體模塊為 networkx.algorithms.link_prediction )的標準實現為例進行演示。

1.1 基于指標的方法

本節介紹 networkx 中計算未連接節點間邊概率的算法,這些算法均通過分析兩節點鄰居關系來構建簡單指標。

資源分配指數 (resource allocation index)
該方法通過以下公式計算所有節點對的資源分配指數,進而估計節點 vvvuuu 之間存在連接的概率::
r(u,v)=∑w∈N(u)∩N(v)1∣N(w)∣r(u,v)=\sum_{w\in N(u)\cap N(v)}\frac 1{|N(w)|} r(u,v)=wN(u)N(v)?N(w)1?
在以上公式中,函數 N(v)N(v)N(v) 用于計算節點 vvv 的鄰居集合,www 代表同時是 uuuvvv 鄰居的節點。我們可以使用 networkx 計算該指數:

import networkx as nx
edges = [[1,3],[2,3],[2,4],[4,5],[5,6],[5,7]]
G = nx.from_edgelist(edges)
preds = nx.resource_allocation_index(G,[(1,2),(2,5),(3,4)])

resource_allocation_index 函數的第一個參數是輸入圖,第二個參數是待計算的潛在邊列表。代碼運行結果如下所示:

[(1, 2, 0.5), (2, 5, 0.5), (3, 4, 0.5)]

輸出結果是一個包含 (1,2)(2,5)(3,4) 等節點對的列表及其對應的資源分配指數值。根據輸出可知,這些節點對之間存在連接邊的概率均為 0.5

Jaccard 系數
該算法基于 Jaccard 系數計算節點 uuuvvv 之間的連接概率:
J(u,v)=∣N(u)∩N(v)∣∣N(u)∪N(v)∣J(u,v)=\frac {|N(u)\cap N(v)|}{|N(u)\cup N(v)|} J(u,v)=N(u)N(v)N(u)N(v)?
其中 N(v)N(v)N(v) 表示節點 vvv 的鄰居集合。在 networkx 中可通過以下代碼實現:

import networkx as nx
edges = [[1,3],[2,3],[2,4],[4,5],[5,6],[5,7]]
G = nx.from_edgelist(edges)
preds = nx.resource_allocation_index(G,[(1,2),(2,5),(3,4)])

代碼運行結果如下所示:

[(1, 2, 0.5), (2, 5, 0.25), (3, 4, 0.3333333333333333)]

根據輸出結果,節點 (1,2) 之間存在邊的概率為 0.5,節點 (2,5) 之間為 0.25,節點 (3,4) 之間為 0.333
除此之外,networkx 庫還提供了許多其他基于相似度得分的節點連接概率計算方法,例如 nx.adamic_adar_indexnx.preferential_attachment,分別基于 Adamic/Adar 指數和偏好連接指數計算。這些函數的參數格式與前述方法一致,均需輸入圖結構和待計算的節點對列表。

1.2 基于社區的方法

與基于指標的方法類似,本類算法同樣通過計算指數來評估未連接節點的連接概率。二者的核心區別在于:基于社區的方法在生成指數前,需先計算節點所屬社區信息,同時基于社區的算法邏輯融合了社區拓撲特征。接下來,我們將介紹一些常見的基于社區的方法。

社區公共鄰居 (community common neighbor)
為了估算兩個節點連接的概率,該算法計算公共鄰居的數量,并將屬于同一社區的公共鄰居數量加到該值中。對于兩個節點 uuuvvv,社區公共鄰居值的計算方式如下:
c(u,v)=∣N(u)∪N(v)∣+∑w∈N(u)∩N(v)f(w)c(u,v)=|N(u)\cup N(v)|+\sum_{w\in N(u)\cap N(v)}f(w) c(u,v)=N(u)N(v)+wN(u)N(v)?f(w)
其中,N(v)N(v)N(v) 表示節點 vvv 的鄰居集合,當節點 wwwuuu 屬于同一社區時 f(w)=1f(w)=1f(w)=1,否則為 000。在 networkx 中通過以下代碼計算:

import networkx as nx
edges = [[1,3],[2,3],[2,4],[4,5],[5,6],[5,7]]
G = nx.from_edgelist(edges)
G.nodes[1]["community"] = 0
G.nodes[2]["community"] = 0
G.nodes[3]["community"] = 0
G.nodes[4]["community"] = 1
G.nodes[5]["community"] = 1
G.nodes[6]["community"] = 1
G.nodes[7]["community"] = 1
preds = nx.cn_soundarajan_hopcroft(G,[(1,2),(2,5),(3,4)])

從上述代碼中可以看到,我們需要為圖中的每個節點分配社區屬性 (community property)。該屬性用于在計算前文定義的 f(v)f(v)f(v) 函數時,識別屬于同一社區的節點,社區屬性值也可以通過特定算法自動計算獲得。cn_soundarajan_hopcroft 函數接受輸入圖和我們希望計算得分的節點對。代碼執行結果如下所示:

[(1, 2, 2), (2, 5, 1), (3, 4, 1)]

與前述其它函數的主要區別在于指標值的范圍。可以看到,該函數的輸出值并不限定在 (0,1) 區間內。

社區資源分配 (community resource allocation)
與社區共同鄰居算法類似,社區資源分配算法將從節點鄰居處獲得的信息與節點所屬社區特征合并:
c(u,v)=∑w∈N(u)∩N(v)f(w)∣N(w)∣c(u,v)=\sum_{w\in N(u)\cap N(v)}\frac {f(w)}{|N(w)|} c(u,v)=wN(u)N(v)?N(w)f(w)?
其中,N(v)N(v)N(v) 表示節點 vvv 的鄰居集合,當節點 wwwuuuvvv 屬于同一社區時 f(w)=1f(w)=1f(w)=1,否則為 000。在 networkx 中的實現代碼如下:

import networkx as nx
edges = [[1,3],[2,3],[2,4],[4,5],[5,6],[5,7]]
G = nx.from_edgelist(edges)
G.nodes[1]["community"] = 0
G.nodes[2]["community"] = 0
G.nodes[3]["community"] = 0
G.nodes[4]["community"] = 1
G.nodes[5]["community"] = 1
G.nodes[6]["community"] = 1
G.nodes[7]["community"] = 1
preds = nx. ra_index_soundarajan_hopcroft(G,[(1,2),(2,5),(3,4)])

從以上代碼中可以看到,我們需要為圖中的每個節點分配社區屬性。該屬性在計算前文定義的函數時,用于識別屬于同一社區的節點,這些社區值也可以通過特定的算法自動計算獲得。ra_index_soundarajan_hopcroft 函數接受輸入圖和我們希望計算得分的節點對。代碼執行結果如下所示:

[(1, 2, 0.5), (2, 5, 0), (3, 4, 0)]

從輸出結果可以明顯看出社區屬性對指數計算的影響:同屬一個社區的節點 12 獲得了較高的指數值 0.5,相反,分屬不同社區的節點對 (2,5)(3,4) 則得分為 0
networkx 還提供了另外兩種結合社區信息的連接概率計算方法:nx.within_inter_cluster (基于集群內外連接分析)和 nx.common_neighbor_centrality (基于共同鄰居中心性)。
在下一節中,我們將介紹如何結合機器學習和邊嵌入 (edge embedding) 來預測未知邊。

2. 基于嵌入的方法

在本節中,我們將介紹一種更先進的鏈路預測方法。該方法的核心理念是將鏈路預測問題轉化為監督式分類任務。具體而言,對于給定圖數據,每對節點均通過特征向量 (xxx) 表示,并分配類別標簽 (yyy)。形式化定義為:設圖 G=(V,E)G=(V,E)G=(V,E),對于任意節點對 i,ji,ji,j,構建如下公式:
x=[f0,0,...,fi,j,...,fn,n]y=[y0,0,...,yi,j,...,yn,n]x=[f_{0,0},...,f_{i,j},...,f_{n,n}]\\ y=[y_{0,0},...,y_{i,j},...,y_{n,n}] x=[f0,0?,...,fi,j?,...,fn,n?]y=[y0,0?,...,yi,j?,...,yn,n?]
其中,fi,j∈xf_{i,j}\in xfi,j?x 表示節點對 i,ji,ji,j 的特征向量,yi,j∈yy_{i,j}\in yyi,j?y 為其對應標簽。yi,jy_{i,j}yi,j? 的取值規則為:若圖 GGG 中存在連接節點 i,ji,ji,j 的邊,則 yi,j=1y_{i,j}=1yi,j?=1;否則 yi,j=0y_{i,j}=0yi,j?=0。通過特征向量和標簽數據,我們可以訓練機器學習算法來預測特定節點對是否可能構成圖中的合理邊。
雖然節點對的標簽向量構建相對簡單,但特征空間的構建則更具挑戰性。為生成每對節點的特征向量,我們將采用嵌入技術(如 node2vecedge2vec)。這些嵌入算法能顯著簡化特征空間的生成過程。整個流程可概括為兩個核心步驟:

  1. 使用 node2vec 算法計算圖 GGG 中每個節點的嵌入向量
  2. 對圖中所有可能的節點對,使用 edge2vec 算法計算其嵌入表示

隨后,我們可以將生成的嵌入特征向量輸入通用機器學習算法來解決分類問題。為便于理解,我們通過代碼示例演示完整流程(從圖構建到鏈路預測),數據集采用論文引用網絡數據集 Cora。

(1) 首先,基于該數據集構建 networkx 圖結構:

import networkx as nx
import pandas as pd
from torch_geometric.utils import from_networkxedgelist = pd.read_csv("cora.cites", sep='\t', header=None, names=["target", "source"])
G = nx.from_pandas_edgelist(edgelist)
# 將圖轉換為PyG格式
pyg_data = from_networkx(G)
draw_graph(G, nx.spring_layout(G))

(2) 接下來,基于圖 G 創建訓練集和測試集。具體而言,數據集不僅需要包含圖 G 中真實邊的子集,還需包含不構成真實邊的節點對。真實邊對應的節點對將作為正樣本(類別標簽 1),而非真實邊的節點對作為負樣本(類別標簽 0):

from sklearn.model_selection import train_test_split
import numpy as npedges = list(G.edges())
non_edges = list(nx.non_edges(G))train_edges, test_edges = train_test_split(edges, test_size=0.1, random_state=42)
train_non_edges, test_non_edges = train_test_split(non_edges, test_size=0.1)# Rebuild train graph without test edges
graph_train = nx.Graph()
graph_train.add_nodes_from(G.nodes())
graph_train.add_edges_from(train_edges)

(3) 對于每個實例,需要生成它們的特征向量。在本節中,使用 node2vec 庫來生成節點嵌入:

from node2vec import Node2Vec
from node2vec.edges import HadamardEmbeddernode2vec = Node2Vec(graph_train)
model = node2vec.fit()
edges_embs = HadamardEmbedder(keyed_vectors=model.wv)# Create training data
samples_train = train_edges + train_non_edges
labels_train = [1]*len(train_edges) + [0]*len(train_non_edges)
train_embeddings = [edges_embs[str(x[0]), str(x[1])] for x in samples_train]# Create testing data
samples_test = test_edges + test_non_edges
labels_test = [1]*len(test_edges) + [0]*len(test_non_edges)
test_embeddings = [edges_embs[str(x[0]), str(x[1])] for x in samples_test]

(4) 使用 train_embeddings 特征空間和 train_labels 標簽分配,最終訓練機器學習算法來解決標簽預測問題:

from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics# Train classifier
rf = RandomForestClassifier(n_estimators=200)
rf.fit(train_embeddings, labels_train)# Predict and evaluate
y_pred = rf.predict(test_embeddings)print('Precision:', metrics.precision_score(labels_test, y_pred))
print('Recall:', metrics.recall_score(labels_test, y_pred))
print('F1-Score:', metrics.f1_score(labels_test, y_pred))

在本節中,使用了一個簡單的 RandomForestClassifier 類,我們可以將訓練好的模型應用到 test_embeddings 特征空間中,以量化分類的質量:

print('Precision:', metrics.precision_score(labels_test, y_pred))
print('Recall:', metrics.recall_score(labels_test, y_pred))
print('F1-Score:', metrics.f1_score(labels_test, y_pred))

結果輸出如下:

Precision::0.8557114228456913
Recall:0.8102466793168881
F1-Score:0.8323586744639375

上述方法只是一個通用的框架,流程中的每個部分——例如訓練/測試拆分、節點/邊嵌入和機器學習算法——都可以根據具體問題進行修改。該方法在處理時序圖的鏈接預測時尤為有效,此時在時間點 ttt 獲取的邊信息可用于訓練模型,進而預測時間點 t+1t+1t+1 可能出現的邊。
本節我們系統闡述了鏈接預測問題,通過多種示例詳細介紹了鏈接預測的不同解決方案,展示了從基于簡單指標的技術到基于嵌入的復雜技術的多元解決路徑。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91753.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91753.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91753.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單2步配置CadenceSkill開發編輯器,支持關鍵字高亮

Cadence 使用過程中難免會與skill打交道,有時候網上找到的開源skill,想要查看或者編輯一下,常規的txt編輯器沒有關鍵字高亮,看起來極為不方便。 利用Sublime Text可以很快速配置出支持skill關鍵字高亮的編輯器。 一、安裝 Sublime…

Leetcode刷題營第三十三題:對稱二叉樹

101. 對稱二叉樹 給你一個二叉樹的根節點 root , 檢查它是否軸對稱。 示例 1: 輸入:root [1,2,2,3,4,4,3] 輸出:true示例 2: 輸入:root [1,2,2,null,3,null,3] 輸出:false 提示:…

day055-Dockerfile與常用指令

文章目錄0. 老男孩思想-女性的第一需求1. Dockerfile1.1 Dockerfile的基本結構1.2 案例-制作小鳥飛飛鏡像1.2.1 編寫Dockerfile文件1.2.2 構建鏡像1.2.3 啟動容器1.3 Dockerfile常用指令1.4 面試題:Dockerfile中CMD和ENTRYPOINT的區別?1.5 案例-制作zrlo…

Spring Boot 應用優雅停機與資源清理:深入理解關閉鉤子

在開發和部署 Spring Boot 應用程序時,除了關注其啟動和運行,理解如何實現**優雅停機(Graceful Shutdown)**也同樣至關重要。優雅停機意味著在應用程序關閉時,能夠有序地釋放資源、完成正在進行的任務,并避…

淘寶扭蛋機小程序開發:重構電商娛樂化體驗的新范式

在電商行業同質化競爭加劇的當下,消費者對購物體驗的期待已從“功能滿足”轉向“情感共鳴”。淘寶扭蛋機小程序憑借“盲盒式隨機獎勵游戲化交互”的創新模式,成為撬動年輕用戶消費力的新支點。其開發邏輯不僅是對傳統電商的升級,更是對“娛樂…

YOLO演變史(一)

在YOLOV1發布后,作者并沒有滿足于此,而是持續對YOLO進行了改進。 YOLOV2:Better, Faster, Stronger YOLOv2(又稱YOLO9000)發表于2017年CVPR,是YOLO系列的第二代版本。其論文標題“Better, Faster, Stronger…

專題:2025智能體研究報告|附70份報告PDF、原數據表匯總下載

原文鏈接:https://tecdat.cn/?p43035 智能體正在改寫商業規則:某城商行的智能客服用公有云部署,把單筆交互成本從5.7元砍到1.2元,投訴率直降42%(《賽迪智庫:2025全球智能體進展報告》P24)&…

Axios 完整功能介紹和完整示例演示

Axios 是一個基于 Promise 的現代化 HTTP 客戶端庫,用于瀏覽器和 Node.js 環境。它提供了簡潔的 API 和強大的功能,是前端開發中最常用的網絡請求工具之一。核心功能 瀏覽器 & Node.js 雙平臺支持 瀏覽器中使用 XMLHttpRequestNode.js 中使用 http 模…

math.h函數

math.c函數作用 1. 基本三角函數(參數為弧度) sin(double x):計算正弦值。cos(double x):計算余弦值。tan(double x):計算正切值。asin(double x):反正弦(返回值范圍:[-π/2, π/2]&…

在Next.js里玩轉pdf預覽

1.背景在項目開發中,pdf預覽是一個很常見的業務。各大公司為了保護自己的知識產權,也會對pdf預覽進行限制,比如:不允許下載、打印,不允許提取文字等等。要想在實現預覽功能的基礎上還要附加這些限制,有很多…

算法競賽備賽——【圖論】求最短路徑——Floyd算法

floyd算法 基于動態規劃 應用:求多源最短路 時間復雜度:n^3 dijkstra:不能解決負邊權 floyd:能解決負邊權 不能解決負邊權回路問題 求最短路徑:dijkstra bfs floyd 思路 1.讓任意兩點之間的距離變短:引入…

雙指針(滑動窗口)相關算法題

雙指針算法有時候也叫尺取法或者滑動窗口,是?種優化暴力枚舉策略的手段:當我們發現在兩層 for 循環的暴力枚舉過程中,兩個指針是可以不回退的,此時我們就可以利用兩個指針不回退的性質來優化時間復雜度。因為雙指針算法中&#x…

ScratchCard刮刮卡交互元素的實現

效果展示 刮刮卡是?種常見的網頁交互元素,通過模擬物理世界的刮涂層來揭示下方的內容。這種效果主要依賴于HTML5的 元素來實現。以下是?個基于TypeScript的刮刮卡實現示例,包括配置項、初始化方法和核心的刮開邏輯。下面是展示的效果部分刮開效果&…

【Python LeetCode 專題】熱題 100,重在思路

哈希1. 兩數之和49. 字母異位詞分組128. 最長連續序列雙指針283. 移動零11. 盛最多水的容器15. 三數之和42. 接雨水滑動窗口3. 無重復字符的最長子串438. 找到字符串中所有字母異位詞子串560. 和為 K 的子數組239. 滑動窗口最大值普通數組53. 最大子數組和56. 合并區間189. 輪轉…

openEuler 22.03 LTS Rootless Docker 安裝指南

openEuler 22.03 LTS Rootless Docker 安裝指南 1.創建普通用戶(用于無根模式) sudo useradd -m docker-user sudo passwd docker-user # 設置密碼 sudo usermod --add-subuids 100000-165535 docker-user sudo usermod --add-subgids 100000-165535 do…

CMake指令:常見內置命令行工具( CMake -E )

目錄 1.簡介 2.核心作用 3.常用命令介紹 3.1.文件操作命令 3.2.系統命令執行 3.3.校驗與哈希 3.4.流程控制與等待 3.5.路徑與文件處理 3.6.歸檔與壓縮 3.7.網絡與下載 3.8.實用工具 4.使用示例 5.與 shell 命令的對比 6.在 CMake 腳本中使用 7.總結 相關鏈接 1…

YOLO融合CAF-YOLO中的ACFM模塊

YOLOv11v10v8使用教程: YOLOv11入門到入土使用教程 YOLOv11改進匯總貼:YOLOv11及自研模型更新匯總 《CAF-YOLO: A Robust Framework for Multi-Scale Lesion Detection in Biomedical Imagery》 一、 模塊介紹 論文鏈接:https://arxiv.org…

Webpack 項目構建優化詳解

1. 相關面試題 1.1. 做過哪些Webpack打包構建優化? 代碼分割:使用 Webpack 的 SplitChunksPlugin 進行代碼分割,將第三方庫、公共代碼與業務代碼分離,提高緩存利用率和加載速度。 Tree Shaking:通過配置 mode: production 或使用 TerserPlugin,移除未引用的代碼,減少…

【深度學習基礎】張量與Tensor的區別?從標量到深度學習的多維世界

目錄引言一、張量(Tensor)的定義與特性1. 數學中的張量2. 深度學習中的Tensor二、標量(Scalar)是什么?三、深度學習中的其他核心量1. 向量(Vector)2. 矩陣(Matrix)3. 高階…

設計模式一: 模板方法模式 (Template Method Pattern)

模板方法模式是一種行為設計模式,它通過定義一個算法的骨架,而將一些步驟延遲到子類中實現。Template Method 使得子類可以不改變(復用)一個算法結構 即可重定義(override 重寫)該算法的某些特定步驟。基本…