手把手教你用 NebulaGraph AI 全家桶跑图算法

人工智能
0
0
![](https://nebula-website-cn.oss-cn-hangzhou.aliyuncs.com/nebula-blog/nebula-ai-suite-banner.jpg) 前段时间 [NebulaGraph 3.5.0 发布](https://docs.nebula-graph.com.cn/3.5.0/20.appendix/release-notes/nebula-comm-release-note/),@**[whitewum](https://github.com/whitewum)** 吴老师建议我把前段时间 NebulaGraph 社区里开启的新项目 [ng_ai](https://github.com/wey-gu/nebulagraph-ai) 公开给大家。 所以,就有了这个系列文章,本文是该系列的开篇之作。 ## ng_ai 是什么 ng_ai 的全名是:Nebulagraph AI Suite,顾名思义,它是在 NebulaGraph 之上跑算法的 Python 套件,希望能给 NebulaGraph 的用户一个自然、简洁的高级 API。简单来说,用很少的代码量就可以执行图上的算法相关的任务。 ng_ai 这个开源项目的目标是,快速迭代、公开讨论、持续演进,一句话概述便是: > Simplifying things in surprising ways. 这个 ng_ai 的专属 url:[https://github.com/wey-gu/nebulagraph-ai](https://github.com/wey-gu/nebulagraph-ai) 可以帮你了解更全面的它。 ## ng_ai 的特点 为了让 NebulaGraph 社区的小伙伴拥有顺滑的算法体验,ng_ai 有以下特点: - 与 NebulaGraph 紧密结合,方便从其中读、写图数据 - 支持多引擎、后端,目前支持 Spark(NebulaGraph Algorithm)、NetworkX,之后会支持 [DGL](https://www.dgl.ai/)、[PyG](https://pytorch-geometric.readthedocs.io/en/latest/) - 友好、符合直觉的 API 设计 - 与 NebulaGraph 的 UDF 无缝结合,支持从 Query 中调用 ng_ai 任务 - 友好的自定义算法接口,方便用户自己实现算法(尚未完成) - 一键试玩环境(基于 Docker Extensions) ## 你可以这么用 ng_ai ### 跑分布式 PageRank 算法 可以在一个大图上,基于 [nebula-algorithm](https://github.com/vesoft-inc/nebula-algorithm) 分布式地跑 PageRank 算法,像是这样: ```python from ng_ai import NebulaReader # scan 模式,通过 Spark 引擎读取数据 reader = NebulaReader(engine="spark") reader.scan(edge="follow", props="degree") df = reader.read() # 运行 PageRank 算法 pr_result = df.algo.pagerank(reset_prob=0.15, max_iter=10) ``` ### 写回算法结果到 NebulaGraph 假设我们要跑一个 Label Propagation 算法,然后把结果写回 NebulaGraph,我们可以这么做: 先确保结果中要写回图数据库的数据 Schema 已经创建好了,像是下面的示例,便是写到 label_propagation.cluster_id 字段里: ```sql CREATE TAG IF NOT EXISTS label_propagation ( cluster_id string NOT NULL ); ``` 下面,我们来看下具体流程。执行算法: ```python df_result = df.algo.label_propagation() ``` 再看一下结果的 Schema: ```python df_result.printSchema() root |-- _id: string (nullable = false) |-- lpa: string (nullable = false) ``` 参考下面的代码,把 lpa 的结果写回 NebulaGraph 中的 cluster_id 字段里(`{"lpa": "cluster_id"}`): ```python from ng_ai import NebulaWriter from ng_ai.config import NebulaGraphConfig config = NebulaGraphConfig() writer = NebulaWriter( data=df_result, sink="nebulagraph_vertex", config=config, engine="spark" ) # 将 lpa 同 cluster_id 进行映射 properties = {"lpa": "cluster_id"} writer.set_options( tag="label_propagation", vid_field="_id", properties=properties, batch_size=256, write_mode="insert", ) # 将数据写回到 NebulaGraph writer.write() ``` 最后,验证一下: ```shell USE basketballplayer; MATCH (v:label_propagation) RETURN id(v), v.label_propagation.cluster_id LIMIT 3; ``` 结果: ```SQL +-------------+--------------------------------+ | id(v) | v.label_propagation.cluster_id | +-------------+--------------------------------+ | "player103" | "player101" | | "player113" | "player129" | | "player121" | "player129" | +-------------+--------------------------------+ ``` 更详细的例子参考:[ng_ai/examples](https://github.com/wey-gu/nebulagraph-ai/blob/main/examples/spark_engine.ipynb) ### 通过 nGQL 调用算法 自 NebulaGraph v3.5.0 开始,用户可从 nGQL 中调用自己实现的函数。而 ng_ai 也用这个能力来实现了一个自己的 ng_ai 函数,让它从 nGQL 中调用 ng_ai 的算法,例如: ```sql -- 准备将要写入数据的 Schema USE basketballplayer; CREATE TAG IF NOT EXISTS pagerank(pagerank string); :sleep 20; -- 回调 ng_ai() RETURN ng_ai("pagerank", ["follow"], ["degree"], "spark", {space: "basketballplayer", max_iter: 10}, {write_mode: "insert"}) ``` 更详细的例子参考:[ng_ai/examples](https://github.com/wey-gu/nebulagraph-ai/blob/main/examples/ng_ai_from_ngql_udf.ipynb) ### 单机运行算法 在单机、本地的环境,ng_ai 支持基于 NetworkX 运行算法。 举个例子,读取图为 ng_ai graph 对象: ```python from ng_ai import NebulaReader from ng_ai.config import NebulaGraphConfig # query 模式,通过 NebulaGraph 或是 NetworkX 引擎读取数据 config_dict = { "graphd_hosts": "graphd:9669", "user": "root", "password": "nebula", "space": "basketballplayer", } config = NebulaGraphConfig(**config_dict) reader = NebulaReader(engine="nebula", config=config) reader.query(edges=["follow", "serve"], props=[["degree"], []]) g = reader.read() ``` 查看、画图: ```python g.show(10) g.draw() ``` 运行算法: ```python pr_result = g.algo.pagerank(reset_prob=0.15, max_iter=10) ``` 写回 NebulaGraph: ```python from ng_ai import NebulaWriter writer = NebulaWriter( data=pr_result, sink="nebulagraph_vertex", config=config, engine="nebula", ) # 待写入的属性 properties = ["pagerank"] writer.set_options( tag="pagerank", properties=properties, batch_size=256, write_mode="insert", ) # 将数据写回到 NebulaGraph writer.write() ``` 其他算法: ```python # 获取所有算法 g.algo.get_all_algo() # 获取相关算法的帮助信息 help(g.algo.node2vec) # 调用算法 g.algo.node2vec() ``` 更详细的例子参考:[ng_ai/examples](https://github.com/wey-gu/nebulagraph-ai/blob/main/examples/networkx_engine.ipynb) ### 可视化图算法结果 这里演示一个 NetworkX 引擎情况下,计算 Louvain、PageRank 并可视化的例子: 先执行两个图算法: ```python pr_result = g.algo.pagerank(reset_prob=0.15, max_iter=10) louvain_result = g.algo.louvain() ``` 再手写一个画图好看的函数: ```python from matplotlib.colors import ListedColormap def draw_graph_louvain_pr(G, pr_result, louvain_result, colors=["#1984c5", "#22a7f0", "#63bff0", "#a7d5ed", "#e2e2e2", "#e1a692", "#de6e56", "#e14b31", "#c23728"]): # 设定节点的位置 pos = nx.spring_layout(G) # 新建一个图形并设置坐标轴 fig, ax = plt.subplots(figsize=(35, 15)) ax.set_xlim(-1, 1) ax.set_ylim(-1, 1) # 从颜色列表中创建一个 colormap cmap = ListedColormap(colors) # 将图中的节点和边进行绘图 node_colors = [louvain_result[node] for node in G.nodes()] node_sizes = [70000 * pr_result[node] for node in G.nodes()] nx.draw_networkx_nodes(G, pos=pos, ax=ax, node_color=node_colors, node_size=node_sizes, cmap=cmap, vmin=0, vmax=max(louvain_result.values())) nx.draw_networkx_edges(G, pos=pos, ax=ax, edge_color='gray', width=1, connectionstyle='arc3, rad=0.2', arrowstyle='-|>', arrows=True) # 提取边数据中的 label 数据作为字典 edge_labels = nx.get_edge_attributes(G, 'label') # 在图中加入边的 label 数据 for edge, label in edge_labels.items(): ax.text((pos[edge[0]][0] + pos[edge[1]][0])/2, (pos[edge[0]][1] + pos[edge[1]][1])/2, label, fontsize=12, color='black', ha='center', va='center') # 在图中加入点的 label 数据 node_labels = {n: G.nodes[n]['label'] if 'label' in G.nodes[n] else n for n in G.nodes()} nx.draw_networkx_labels(G, pos=pos, ax=ax, labels=node_labels, font_size=12, font_color='black') # 为同社区数据添加相同颜色 sm = plt.cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=0, vmax=max(louvain_result.values()))) sm.set_array([]) cbar = plt.colorbar(sm, ax=ax, ticks=range(max(louvain_result.values()) + 1), shrink=0.5) cbar.ax.set_yticklabels([f'Community {i}' for i in range(max(louvain_result.values()) + 1)]) # 数据展示 plt.show() draw_graph_louvain_pr(G, pr_result=pr_result, louvain_result=louvain_result) ``` 效果如下所示: ![image.png](https://dev-media.amazoncloud.cn/f3ab1b6bb1dc4a79b3ea07d9e7f8cc99_image.png "image.png") 更详细的例子参考:[ng_ai/examples](https://github.com/wey-gu/nebulagraph-ai/blob/main/examples/ng_ai_networkx_plot.ipynb) ### 更方便的 Notebook 操作 NebulaGraph 结合 NebulaGraph 的 Jupyter Notebook 插件: [https://github.com/wey-gu/ipython-ngql](https://github.com/wey-gu/ipython-ngql),我们还可以更便捷地操作 NebulaGraph: 可通过 ng_ai 的 extras 在 Jupyter Notbook 中安装插件: ```python %pip install ng_ai[jupyter] %load_ext ngql ``` 当然,也可以单独安装插件: ```python %pip install ipython-ngql %load_ext ngql ``` 安装完成后,就可以在 Notebook 里直接使用 `%ngql` 命令来执行 nGQL 语句: ```python %ngql --address 127.0.0.1 --port 9669 --user root --password nebula %ngql USE basketballplayer; %ngql MATCH (v:player{name:"Tim Duncan"})-->(v2:player) RETURN v2.player.name AS Name; ``` > 注,多行的 Query 用两个百分号就好了 `%%ngql` 最后,我们还能在 Jupyter Notebook 里直接可视化渲染结果!只需要 `%ng_draw` 就可以啦! ```python %ngql match p=(:player)-[]->() return p LIMIT 5 %ng_draw ``` 效果如下: ![image.png](https://dev-media.amazoncloud.cn/097eb439b7b94f368ef65c373d1b86e6_image.png "image.png") ## 未来工作 现在 ng_ai 还在开发中,我们还有很多工作要做: - [ ] 完善 Reader 模式,现在 NebulaGraph / NetworkX 的读取数据只支持 Query-Mode,还需要支持 Scan-Mode - [ ] 实现基于 dgl(GNN)的链路预测、节点分类等算法,例如: ```python model = g.algo.gnn_link_prediction() result = model.train() # query src, dst to be predicted model.predict(src_vertex, dst_vertices) ``` - [ ] UDA,自定义算法 - [ ] 快速部署工具 ng_ai 完全 build in public,欢迎社区的大家们来参与,一起来完善 ng_ai,让 NebulaGraph 上的 AI 算法更加简单、易用! ## 试玩 ng_ai 我们已经准备好了一键部署的 NebulaGraph + NebulaGraph Studio + ng_ai in Jupyter 的环境,只需要大家从 Docker Desktop 的 Extension(扩展)中搜索 NebulaGraph,就可以试玩了。 - 安装 [NebulaGraph Docker 插件](https://www.docker.com/blog/distributed-cloud-native-graph-database-nebulagraph-docker-extension/) 在 Docker Desktop 的插件市场搜索 NebulaGraph,点击安装: ![image.png](https://dev-media.amazoncloud.cn/837b886f36a24f539f7c05fe65b8f368_image.png "image.png") - 安装 ng_ai Playground 进入 NebulaGraph 插件,点击 **Install NX Mode**,安装 ng_ai 的 NetworkX Playground,通常要等几分钟等待安装完成。 ![image.png](https://dev-media.amazoncloud.cn/445966c276ab4c359ab2ea710379b6c2_image.png "image.png") - 进入 NetworkX Playground 点击 **Jupyter NB NetworkX**,进入 NetworkX Playground。 ![image.png](https://dev-media.amazoncloud.cn/ad99d04969fd4699bd2be2d70683b48a_image.png "image.png") ## ng_ai 的架构 ng_ai 的架构如下,它的核心模块有: - Reader:负责从 NebulaGraph 读取数据 - Writer:负责将数据写入 NebulaGraph - Engine:负责适配不同运行时,例如 Spark、DGL、NetowrkX 等 - Algo:算法模块,例如 PageRank、Louvain、GNN_Link_Predict 等 此外,为了支持 nGQL 中的调用,还有两个模块: - ng_ai-udf:负责将 UDF 注册到 NebulaGraph,接受 ng_ai 的 Query 调用,访问 ng_ai API - ng_ai-api:ng_ai 的 API 服务,接受 UDF 的调用,访问 ng_ai 核心模块 ```asciiarmor ┌───────────────────────────────────────────────────┐ │ Spark Cluster │ │ .─────. .─────. .─────. .─────. │ │ ; : ; : ; : ; : │ ┌─▶│ : ; : ; : ; : ; │ │ │ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ │ │ │ `───' `───' `───' `───' │ Algo Spark │ Engine└───────────────────────────────────────────────────┘ │ ┌────────────────────────────────────────────────────┬──────────┐ └──┤ │ │ │ NebulaGraph AI Suite(ngai) │ ngai-api │◀─┐ │ │ │ │ │ └──────────┤ │ │ ┌────────┐ ┌──────┐ ┌────────┐ ┌─────┐ │ │ │ │ Reader │ │ Algo │ │ Writer │ │ GNN │ │ │ ┌───────▶│ └────────┘ └──────┘ └────────┘ └─────┘ │ │ │ │ │ │ │ │ │ │ │ │ ├────────────┴───┬────────┴─────┐ └──────┐ │ │ │ │ ▼ ▼ ▼ ▼ │ │ │ │ ┌─────────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐ │ │ │ ┌──┤ │ SparkEngine │ │ NebulaEngine │ │ NetworkX │ │ DGLEngine│ │ │ │ │ │ └─────────────┘ └──────────────┘ └──────────┘ └──────────┘ │ │ │ │ └──────────┬────────────────────────────────────────────────────┘ │ │ │ │ Spark │ │ │ └────────Reader ────────────┐ │ │ Spark Query Mode │ │ │ Reader │ │ │Scan Mode ▼ ┌─────────┐ │ │ ┌───────────────────────────────────────────────────┬─────────┤ ngai-udf│◀─────────────┐ │ │ │ │ └─────────┤ │ │ │ │ NebulaGraph Graph Engine Nebula-GraphD │ ngai-GraphD │ │ │ │ ├──────────────────────────────┬────────────────────┼───────────────────┘ │ │ │ │ │ │ │ │ │ │ NebulaGraph Storage Engine │ │ │ │ │ │ │ │ │ │ └─▶│ Nebula-StorageD │ Nebula-Metad │ │ │ │ │ │ │ │ └──────────────────────────────┴────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ RETURN ng_ai("pagerank", ["follow"], ["degree"], "spark", {space:"basketballplayer"}) │──┘ │ └───────────────────────────────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────┐ │ │ from ng_ai import NebulaReader │ │ │ │ │ │ # read data with spark engine, scan mode │ │ │ reader = NebulaReader(engine="spark") │ │ │ reader.scan(edge="follow", props="degree") │ └──│ df = reader.read() │ │ │ │ # run pagerank algorithm │ │ pr_result = df.algo.pagerank(reset_prob=0.15, max_iter=10) │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- **谢谢你读完本文** (///▽///) 欢迎前往 GitHub 来阅读 NebulaGraph 源码,或是尝试用它解决你的业务问题 yo~ GitHub 地址:[https://github.com/vesoft-inc/nebula](https://github.com/vesoft-inc/nebula)
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭