HugeGraph-ML
HugeGraph-ML 从 HugeGraph 读取图数据并转换为 DGL 图,供节点嵌入、节点分类、图分类、链接预测和欺诈检测等任务使用。模型实现位于 hugegraph-ml/src/hugegraph_ml/models/。
环境要求
- Python 3.10 或更高版本
- HugeGraph Server 1.0 或更高版本,推荐 1.5 及以上版本
uv0.7 或更高版本
所有服务端访问都通过同一仓库中的 hugegraph-python-client(即 pyhugegraph 包)完成。HugeGraph2DGL 使用 Gremlin 接口的 g.V().hasLabel(...) 和 g.E().hasLabel(...) 拉取点边,数据集导入函数则通过 schema 接口和顶点、边的批量接口写入,每批 500 条。
ML 依赖在仓库根目录的 [tool.uv] constraint-dependencies 中固定版本:
| 依赖 | 版本约束 |
|---|---|
torch | ==2.2.0 |
dgl | ~=2.1.0 |
ogb | ~=1.3.6 |
torchdata | ~=0.7.0 |
catboost | ~=1.2.3 |
category-encoders | ~=2.6.3 |
numpy | ~=1.24.4 |
pandas | ~=2.2.3 |
上述约束安装的是 CPU 版本。每个任务都有 gpu 参数,默认值 -1 表示使用 CPU;只有自行安装 CUDA 版的 torch 和 dgl 之后,才可以传入设备编号。
安装
HugeGraph-ML 是根项目的路径依赖,但不属于 uv workspace members。应在仓库根目录选择 ml extra,不要在子目录建立另一套锁文件。
已实现模型
下列模块均位于 hugegraph-ml/src/hugegraph_ml/models/。models/__init__.py 不做任何再导出,需要直接从模块文件导入。
| 模型 | 模块 | 入口类 | 用途 | 论文 |
|---|---|---|---|---|
| AGNN | agnn.py | AGNN | 节点分类 | 1803.03735 |
| APPNP | appnp.py | APPNP | 节点分类 | 1810.05997 |
| ARMA | arma.py | ARMA4NC | 节点分类 | 1901.01343 |
| BGNN | bgnn.py | BGNNPredictor | 梯度提升与 GNN 结合处理节点特征,自带示例执行回归任务 | 2101.08543 |
| BGRL | bgrl.py | BGRL | 自监督节点嵌入 | 2102.06514 |
| CARE-GNN | care_gnn.py | CAREGNN | 欺诈检测 | 2008.08692 |
| Cluster-GCN | cluster_gcn.py | SAGE | 基于子图采样的节点分类 | 1905.07953 |
| C&S | correct_and_smooth.py | MLP、CorrectAndSmooth、LabelPropagation | 对基础预测结果做校正与平滑 | 2010.13993 |
| DAGNN | dagnn.py | DAGNN | 节点分类 | 2007.09296 |
| DeeperGCN | deepergcn.py | DeeperGCN | 带边特征的节点分类 | 2006.07739 |
| DGI | dgi.py | DGI | 自监督节点嵌入 | 1809.10341 |
| DiffPool | diffpool.py | DiffPool | 图分类 | 1806.08804 |
| GATNE | gatne.py | DGLGATNE | 异构网络嵌入 | 1905.01669 |
| GIN | gin_global_pool.py | GIN | 图分类 | |
| GRACE | grace.py | GRACE | 自监督节点嵌入 | 2006.04131 |
| GRAND | grand.py | GRAND | 节点分类 | 2005.11079 |
| JKNet | jknet.py | JKNet | 节点分类 | 1806.03536 |
| MLP | mlp.py | MLPClassifier | 基于已学习嵌入的下游分类器 | |
| P-GNN | pgnn.py | PGNN | 链接预测 | you19b |
| SEAL | seal.py | DGCNN、SEALData | 链接预测 | 1802.09691 |
GIN 的 pooling 参数可取 sum(默认)、mean、max、global_attention 和 set2set。
读取图数据
hugegraph-ml/src/hugegraph_ml/data/hugegraph2dgl.py 中的 HugeGraph2DGL 会创建 PyHugeClient,并把查询结果转换为 DGL 对象:
| 方法 | 返回值 | 说明 |
|---|---|---|
convert_graph(vertex_label, edge_label, feat_key="feat", label_key="label", mask_keys=None) | dgl.DGLGraph | mask_keys 为空时取 ["train_mask", "val_mask", "test_mask"] |
convert_hetero_graph(vertex_labels, edge_labels, feat_key="feat", label_key="label", mask_keys=None) | DGL 异构图 | 参数为标签列表 |
convert_graph_dataset(graph_vertex_label, vertex_label, edge_label, feat_key="feat", label_key="label") | HugeGraphDataset | info 中写入 n_graphs、max_n_nodes、n_feat_dim、n_classes |
convert_graph_nx(vertex_label, edge_label) | networkx.Graph | P-GNN 使用 |
convert_graph_with_edge_feat(vertex_label, edge_label, node_feat_key="feat", edge_feat_key="edge_feat", label_key="label", mask_keys=None) | dgl.DGLGraph | 同时填充 edata["feat"] |
convert_graph_ogb(vertex_label, edge_label, split_label) | (dgl.DGLGraph, split_edge) | SEAL 使用 |
convert_hetero_graph_bgnn(vertex_labels, edge_labels, feat_key="feat", label_key="class", cat_key="cat_features", mask_keys=None) | DGL 异构图 | BGNN 使用 |
节点特征写入 ndata["feat"],标签写入 ndata["label"],各掩码写入 ndata[<mask key>]。NodeEmbed 只要求 feat;NodeClassify、NodeClassifyWithEdge 和 NodeClassifyWithSample 要求 feat、label、train_mask、val_mask 和 test_mask,缺少任意一项都会抛出 ValueError。
导入示例数据集
hugegraph_ml.utils.dgl2hugegraph_utils 负责把 DGL、OGB 和 NetworkX 数据集写入 HugeGraph,供转换层读取。这些函数都接受与 HugeGraph2DGL 相同的 url、graph、user、pwd 和 graphspace 参数,并且多数会先把数据集名转为大写再匹配。
| 函数 | 支持的数据集 | 创建的标签 |
|---|---|---|
import_graph_from_dgl | CORA、CITESEER、PUBMED | <NAME>_vertex、<NAME>_edge |
import_graphs_from_dgl | MUTAG、COLLAB、NCI1、PROTEINS、PTC、ENZYMES、DD | <NAME>_graph_vertex、<NAME>_vertex、<NAME>_edge |
import_hetero_graph_from_dgl | ACM | <NAME>_<ntype>_v、<NAME>_<etype>_e |
import_hetero_graph_from_dgl_no_feat | AMAZONGATNE | <NAME>_<ntype>_v、<NAME>_<etype>_e |
import_hetero_graph_from_dgl_bgnn | AVAZU | <NAME>_<ntype>_v、<NAME>_<etype>_e |
import_graph_from_nx | CAVEMAN | <NAME>_vertex、<NAME>_edge |
import_graph_from_dgl_with_edge_feat | CORA、CITESEER、PUBMED | <NAME>_edge_feat_vertex、<NAME>_edge_feat_edge |
import_graph_from_ogb | ogbl-collab,不做大写转换 | <NAME>_vertex、<NAME>_edge |
import_split_edge_from_ogb | ogbl-collab,不做大写转换 | <NAME>_split_edge |
传入其他名称会抛出 ValueError("dataset not supported")。import_split_edge_from_ogb 还需要顶点导入返回的 idx_to_vertex_id 映射和 max_nodes 上限。
clear_all_data() 会清空目标图中的全部点和边。测试 fixture 先调用它,再导入 CORA、MUTAG 和 ACM,结束时再次调用。
AMAZONGATNE 和 AVAZU 不会自动下载,压缩包地址写在 import_hetero_graph_from_dgl_no_feat 和 import_hetero_graph_from_dgl_bgnn 上方的注释里。
任务
任务类位于 hugegraph-ml/src/hugegraph_ml/tasks/,均接收转换后的图和模型实例。
| 类 | 模块 | 入口方法 |
|---|---|---|
NodeEmbed | node_embed.py | train_and_embed(add_self_loop=True, lr=1e-3, weight_decay=0, n_epochs=200, patience=inf, gpu=-1),返回 ndata["feat"] 被替换为嵌入结果的图 |
NodeClassify | node_classify.py | 先 train(lr, weight_decay, n_epochs, patience, early_stopping_monitor, gpu),再 evaluate() 返回 {"accuracy": ..., "loss": ...} |
NodeClassifyWithEdge | node_classify_with_edge.py | 结构相同,适用于同时读取 edata["feat"] 的模型 |
NodeClassifyWithSample | node_classify_with_sample.py | 基于 ClusterGCNSampler 分区的训练,仅使用 CPU,没有 gpu 参数 |
GraphClassify | graph_classify.py | train(batch_size=20, lr, weight_decay, n_epochs, patience, early_stopping_monitor, clip=2.0, gpu),在 HugeGraphDataset 上按 70/20/10 划分 |
DetectorCaregnn | fraud_detector_caregnn.py | CARE-GNN 训练,evaluate() 输出 recall 和 ROC AUC,并读取 ndata["feature"] 而非 ndata["feat"] |
HeteroSampleEmbedGATNE | hetero_sample_embed_gatne.py | train_and_embed(lr=1e-3, n_epochs=200, gpu=-1) |
LinkPredictionPGNN | link_prediction_pgnn.py | train(lr, weight_decay, n_epochs, gpu) |
LinkPredictionSeal | link_prediction_seal.py | 构造函数内部已调用 data_prepare(),随后执行 train(lr=1e-3, n_epochs=200, gpu=-1) |
patience 默认值为 float("inf")。utils/early_stopping.py 中的 EarlyStopping 可以监控 loss 或 accuracy,保存最优权重并在训练结束时恢复。
可运行示例
脚本位于 hugegraph-ml/src/hugegraph_ml/examples/。在 hugegraph-ml/src 目录下执行:
每个脚本同时提供同名函数,可以导入后用较小的 epoch 数调用。
| 脚本 | 模型 | 任务 | 读取的标签 |
|---|---|---|---|
agnn_example.py | AGNN | NodeClassify | CORA_vertex、CORA_edge |
appnp_example.py | APPNP | NodeClassify | CORA_vertex、CORA_edge |
arma_example.py | ARMA4NC | NodeClassify | CORA_vertex、CORA_edge |
bgnn_example.py | BGNNPredictor | 模型自带的 fit() | AVAZU__N_v、AVAZU__E_e |
bgrl_example.py | BGRL | NodeEmbed、NodeClassify | CORA_vertex、CORA_edge |
care_gnn_example.py | CAREGNN | DetectorCaregnn | AMAZON_user_v 以及 AMAZON_net_upu_e、AMAZON_net_usu_e、AMAZON_net_uvu_e |
cluster_gcn_example.py | SAGE | NodeClassifyWithSample | CORA_vertex、CORA_edge |
correct_and_smooth_example.py | correct_and_smooth 中的 MLP | NodeClassify | CORA_vertex、CORA_edge |
dagnn_example.py | DAGNN | NodeClassify | CORA_vertex、CORA_edge |
deepergcn_example.py | DeeperGCN | NodeClassifyWithEdge | 通过 convert_graph_with_edge_feat 读取 CORA_vertex、CORA_edge |
dgi_example.py | DGI | NodeEmbed、NodeClassify | CORA_vertex、CORA_edge |
diffpool_example.py | DiffPool | GraphClassify | MUTAG_graph_vertex、MUTAG_vertex、MUTAG_edge |
gatne_example.py | DGLGATNE | HeteroSampleEmbedGATNE | AMAZONGATNE__N_v、AMAZONGATNE_1_e、AMAZONGATNE_2_e |
gin_example.py | GIN | GraphClassify | MUTAG_graph_vertex、MUTAG_vertex、MUTAG_edge |
grace_example.py | GRACE | NodeEmbed、NodeClassify | CORA_vertex、CORA_edge |
grand_example.py | GRAND | NodeClassify | CORA_vertex、CORA_edge |
jknet_example.py | JKNet | NodeClassify | CORA_vertex、CORA_edge |
pgnn_example.py | PGNN | LinkPredictionPGNN | CAVEMAN_vertex、CAVEMAN_edge |
seal_example.py | DGCNN | LinkPredictionSeal | ogbl-collab_vertex、ogbl-collab_edge、ogbl-collab_split_edge |
DGI 节点嵌入示例
先把 DGL 的 Cora 数据集导入 HugeGraph。数据集名会先转为大写,因此 cora 和 CORA 都会生成 CORA_vertex 和 CORA_edge 标签:
读取图并训练 DGI:
evaluate() 返回类似 {'accuracy': 0.82, 'loss': 0.5714246034622192} 的字典。完整脚本是 hugegraph-ml/src/hugegraph_ml/examples/dgi_example.py。
GRAND 节点分类示例
GRAND 每次增强采样都会返回一组 logits,NodeClassify 会对列表中的每个元素分别应用掩码后再计算损失。完整脚本是 hugegraph-ml/src/hugegraph_ml/examples/grand_example.py。
排查问题
- 连接失败:检查 HugeGraph Server 地址、端口和认证信息。
- Schema 不匹配:示例默认使用
CORA_vertex和CORA_edge,自有数据需要传入实际标签。 ValueError: Graph is missing required node attribute ...:节点分类任务需要ndata中包含feat、label、train_mask、val_mask和test_mask。请导入带掩码的数据集,或给convert_graph传入自定义的mask_keys。ValueError: dataset not supported:导入函数只接受上表列出的名称,且import_graph_from_ogb匹配ogbl-collab时不做大写转换。- DGL 或 PyTorch 导入失败:回到仓库根目录重新执行
uv sync --extra ml,并确认当前 Python 来自根目录.venv。 bgrl_example.py目前在导入阶段就会失败:它从hugegraph_ml.models.bgrl导入MLP_Predictor,而该模块中的类名是MLPPredictor。care_gnn_example.py读取AMAZON_user_v和三个AMAZON_net_*_e边标签,仓库内没有对应的导入函数,需要自行准备该数据集后再运行。