本文目录导读:

我来介绍如何使用NetworkX进行网络嵌入(Network Embedding),NetworkX本身没有直接实现网络嵌入的算法,但可以结合其他库来实现。
基础环境配置
# 安装必要的库 # pip install networkx # pip install node2vec # pip install gensim # pip install scikit-learn # pip install matplotlib import networkx as nx import numpy as np import matplotlib.pyplot as plt from sklearn.manifold import TSNE from sklearn.decomposition import PCA
创建示例图
# 方式1:创建随机图
G = nx.karate_club_graph() # 空手道俱乐部图
print(f"节点数: {G.number_of_nodes()}")
print(f"边数: {G.number_of_edges()}")
# 方式2:创建自定义图
def create_sample_graph():
G = nx.Graph()
edges = [
(1, 2), (1, 3), (2, 3), (2, 4), (3, 4),
(4, 5), (5, 6), (5, 7), (6, 7),
(7, 8), (8, 9), (8, 10), (9, 10)
]
G.add_edges_from(edges)
return G
# 可视化图
def visualize_graph(G, title="Graph Visualization"):
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(G, seed=42)
nx.draw(G, pos, with_labels=True, node_color='lightblue',
node_size=500, font_size=10, font_weight='bold')
plt.title(title)
plt.show()
G = create_sample_graph()
visualize_graph(G)
基于邻接矩阵的嵌入方法
def adjacency_embedding(G, dimensions=2):
"""
基于邻接矩阵的嵌入
"""
# 获取邻接矩阵
adj_matrix = nx.adjacency_matrix(G).toarray()
# 使用PCA降维
pca = PCA(n_components=dimensions)
embeddings = pca.fit_transform(adj_matrix)
return embeddings
# 使用Laplacian特征映射
def laplacian_embedding(G, dimensions=2):
"""
Laplacian特征映射
"""
# 计算拉普拉斯矩阵
L = nx.laplacian_matrix(G).toarray()
# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eigh(L)
# 选择最小的非零特征值对应的特征向量
idx = np.argsort(eigenvalues)
eigenvectors = eigenvectors[:, idx]
# 返回嵌入向量(跳过第一个特征向量)
embeddings = eigenvectors[:, 1:dimensions+1]
return embeddings
# 应用嵌入
adj_emb = adjacency_embedding(G, 2)
lap_emb = laplacian_embedding(G, 2)
print("邻接矩阵嵌入形状:", adj_emb.shape)
print("拉普拉斯嵌入形状:", lap_emb.shape)
Node2Vec嵌入方法
# 方式1:使用node2vec库
from node2vec import Node2Vec
def node2vec_embedding(G, dimensions=128, walk_length=30, num_walks=200):
"""
Node2Vec网络嵌入
"""
# 初始化Node2Vec模型
node2vec = Node2Vec(G, dimensions=dimensions,
walk_length=walk_length,
num_walks=num_walks,
workers=4) # 并行工作线程数
# 训练模型
model = node2vec.fit(window=10, min_count=1, batch_words=4)
return model
# 方式2:手动实现简单的随机游走嵌入
def random_walk_embedding(G, walk_length=20, num_walks=10, dimensions=128):
"""
基于随机游走的简单嵌入
"""
from gensim.models import Word2Vec
walks = []
nodes = list(G.nodes())
for _ in range(num_walks):
for node in nodes:
walk = [node]
current = node
for _ in range(walk_length - 1):
neighbors = list(G.neighbors(current))
if neighbors:
current = np.random.choice(neighbors)
walk.append(current)
else:
break
walks.append([str(n) for n in walk])
# 使用Word2Vec训练嵌入
model = Word2Vec(walks, vector_size=dimensions,
window=5, min_count=0, sg=1, workers=4)
return model
# 应用Node2Vec
node2vec_model = node2vec_embedding(G, dimensions=64, walk_length=20, num_walks=100)
# 获取节点嵌入
def get_node_embeddings(model, nodes):
embeddings = {}
for node in nodes:
embeddings[node] = model.wv[str(node)]
return embeddings
embeddings = get_node_embeddings(node2vec_model, G.nodes())
print("节点嵌入维度:", len(embeddings[1]))
print("节点1的嵌入向量:\n", embeddings[1][:10], "...")
完整示例:网络嵌入可视化
class NetworkEmbeddingDemo:
def __init__(self):
self.G = None
self.embeddings = None
def load_graph(self, graph_type='karate'):
"""加载图数据"""
if graph_type == 'karate':
self.G = nx.karate_club_graph()
elif graph_type == 'erdos':
self.G = nx.erdos_renyi_graph(20, 0.15, seed=42)
elif graph_type == 'watts':
self.G = nx.watts_strogatz_graph(30, 3, 0.1, seed=42)
return self.G
def compute_node2vec_embedding(self, dimensions=64):
"""计算Node2Vec嵌入"""
if self.G is None:
raise ValueError("请先加载图数据")
# 节点重命名为字符串
G_str = nx.Graph()
G_str.add_nodes_from([str(n) for n in self.G.nodes()])
G_str.add_edges_from([(str(u), str(v)) for u, v in self.G.edges()])
node2vec = Node2Vec(G_str, dimensions=dimensions,
walk_length=30, num_walks=200, workers=4)
model = node2vec.fit(window=10, min_count=1)
self.embeddings = model
return model
def visualize_embeddings(self, method='tsne'):
"""可视化嵌入结果"""
if self.embeddings is None:
raise ValueError("请先计算嵌入")
# 获取所有节点嵌入
nodes = list(self.G.nodes())
vectors = np.array([self.embeddings.wv[str(n)] for n in nodes])
# 降维到2D
if method == 'tsne':
reducer = TSNE(n_components=2, random_state=42)
else:
reducer = PCA(n_components=2)
vectors_2d = reducer.fit_transform(vectors)
# 可视化
plt.figure(figsize=(12, 5))
# 子图1:原始图
plt.subplot(121)
pos = nx.spring_layout(self.G, seed=42)
nx.draw(self.G, pos, with_labels=True, node_color='lightblue',
node_size=200, font_size=8)
plt.title("原始图结构")
# 子图2:嵌入空间
plt.subplot(122)
plt.scatter(vectors_2d[:, 0], vectors_2d[:, 1], c='blue', alpha=0.6)
for i, node in enumerate(nodes):
plt.annotate(str(node), (vectors_2d[i, 0], vectors_2d[i, 1]))
plt.title(f"嵌入空间 ({method.upper()})")
plt.xlabel("维度1")
plt.ylabel("维度2")
plt.tight_layout()
plt.show()
def find_similar_nodes(self, node_id, top_k=5):
"""找相似节点"""
similar = self.embeddings.wv.most_similar(str(node_id), topn=top_k)
return similar
# 使用示例
demo = NetworkEmbeddingDemo()
demo.load_graph('karate')
demo.compute_node2vec_embedding(dimensions=64)
demo.visualize_embeddings('tsne')
# 找相似节点
similar_nodes = demo.find_similar_nodes(1, top_k=5)
print("与节点1最相似的节点:")
for node, score in similar_nodes:
print(f" 节点 {node}: 相似度 {score:.4f}")
高级应用:节点分类
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
def node_classification_example():
"""使用嵌入向量进行节点分类"""
# 加载数据
G = nx.karate_club_graph()
# 计算嵌入
G_str = nx.Graph()
G_str.add_nodes_from([str(n) for n in G.nodes()])
G_str.add_edges_from([(str(u), str(v)) for u, v in G.edges()])
node2vec = Node2Vec(G_str, dimensions=64, walk_length=30,
num_walks=200, workers=4)
model = node2vec.fit(window=10, min_count=1)
# 准备特征和标签
nodes = list(G.nodes())
X = np.array([model.wv[str(n)] for n in nodes])
# 使用俱乐部分类作为标签
y = np.array([G.nodes[n]['club'] for n in nodes])
y = (y == 'Mr. Hi').astype(int) # 二分类
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 训练分类器
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)
# 预测和评估
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"节点分类准确率: {accuracy:.4f}")
return accuracy
# 运行分类示例
acc = node_classification_example()
这些示例展示了如何使用NetworkX进行网络嵌入的完整流程,你可以根据具体需求选择不同的嵌入方法,并应用于节点分类、链接预测、可视化等任务中。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播