You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pyviz实现多关联规则子图合并与交互式筛选的技术问询

基于Pyviz实现多关联规则子图合并与交互式筛选的技术问询

嘿,我完全get到你的需求了——把多组关联规则的子图合并成一个完整的网络图,然后通过下拉菜单切换查看特定子图对吧?这其实可以通过给每个子图的节点和边打上分组标签,再借助Pyviz自带的筛选功能轻松实现,下面是具体的思路和修改后的代码:

核心实现思路

  • 为每个子图的所有节点和边添加一个分组标识属性(比如group),分别标记为graph_1、graph_2、graph_3,作为后续筛选的依据
  • 将三个子图合并到同一个NetworkX有向图中,完整保留所有节点和边的属性信息
  • 利用Pyviz的filter_menu功能,自动识别分组属性生成下拉筛选菜单,实现子图的切换显示

修改后的代码实现

import networkx as nx
import numpy as np
from pyvis.network import Network

def build_grouped_graph(rules, group_name):
    rules_to_show = len(rules)
    G = nx.DiGraph()
    strs = []
    median = rules['confidence'].median()

    # 遍历规则构建带分组属性的节点和边
    for i in range(rules_to_show):
        conf = rules.iloc[i]['confidence']
        # 给规则节点加分组后缀,避免不同子图的规则节点重名
        rule_node = f"R{i}_{group_name}"
        strs.append(rule_node)
        # 给节点添加group属性
        G.add_node(rule_node, group=group_name)

        # 处理前件节点与边
        for a in rules.iloc[i]['antecedents']:
            if a not in G:
                G.add_node(a, group=group_name)
            edge_color = 'lightgrey' if conf > median else 'orange'
            # 给边也添加group属性
            G.add_edge(a, rule_node, color=edge_color, value=conf*0.01, group=group_name)

        # 处理后件节点与边
        for c in rules.iloc[i]['consequents']:
            if c not in G:
                G.add_node(c, group=group_name)
            edge_color = 'lightgrey' if conf > median else 'orange'
            G.add_edge(rule_node, c, color=edge_color, value=conf*0.01, group=group_name)

    # 生成节点颜色映射(保留你原来的逻辑)
    color_map = []
    for node in G:
        if node in strs:
            color_map.append("lightblue")
        else:
            color_map.append("lightgreen")
    
    return G, color_map

# ---------------------- 假设你有三个规则数据集 ----------------------
# rules_df1, rules_df2, rules_df3 分别对应三组关联规则数据
# dataset1, dataset2, dataset3 分别对应三组数据的支持度信息
# -----------------------------------------------------------------

# 构建三个带分组属性的子图
graph1, color_map1 = build_grouped_graph(rules_df1, "graph_1")
graph2, color_map2 = build_grouped_graph(rules_df2, "graph_2")
graph3, color_map3 = build_grouped_graph(rules_df3, "graph_3")

# 合并三个子图到总网络图中
total_graph = nx.DiGraph()
# 合并节点(保留属性)
total_graph.add_nodes_from(graph1.nodes(data=True))
total_graph.add_nodes_from(graph2.nodes(data=True))
total_graph.add_nodes_from(graph3.nodes(data=True))
# 合并边(保留属性)
total_graph.add_edges_from(graph1.edges(data=True))
total_graph.add_edges_from(graph2.edges(data=True))
total_graph.add_edges_from(graph3.edges(data=True))

# 合并颜色映射,确保每个节点对应正确颜色
all_color_map = {}
for node, color in zip(graph1.nodes, color_map1):
    all_color_map[node] = color
for node, color in zip(graph2.nodes, color_map2):
    all_color_map[node] = color
for node, color in zip(graph3.nodes, color_map3):
    all_color_map[node] = color
sorted_color_map = [all_color_map[node] for node in total_graph.nodes]

# 处理节点大小(基于支持度,保留你原来的逻辑)
mydic = {}
for dataset in [dataset1, dataset2, dataset3]:
    for index, row in dataset.iterrows():
        mydic[row["items"]] = row['support']

node_values = []
for node in total_graph.nodes:
    node_values.append(int(mydic.get(node, 0.0001)*10000))

# 生成Pyviz交互式可视化
nt = Network(notebook=True,
             cdn_resources="remote",
             bgcolor="#222222",
             font_color="white",
             height="750px",
             width="100%",
             select_menu=True,
             filter_menu=True)  # 开启筛选菜单,自动识别group属性

# 添加节点,包含大小、颜色和分组属性
for idx, node in enumerate(total_graph.nodes):
    nt.add_node(node, 
                value=node_values[idx], 
                color=sorted_color_map[idx],
                group=total_graph.nodes[node]['group'])

# 添加边,保留原有的颜色和权重属性
for edge in total_graph.edges(data=True):
    nt.add_edge(edge[0], edge[1], 
                color=edge[2]['color'], 
                value=edge[2]['value'],
                group=edge[2]['group'])

# 设置物理布局和显示控制按钮
nt.repulsion(node_distance=100, spring_length=500)
nt.show_buttons(filter_=['physics'])

# 保存并打开可视化页面
nt.show('combined_association_rules.html')

代码关键点说明

  1. 分组子图构建:build_grouped_graph函数专门生成带分组属性的子图,给规则节点加分组后缀避免重名,同时给每个节点和边都打上group标签
  2. 子图合并:完整合并三个子图的节点和边,保留所有属性信息,确保总网络图包含全部数据
  3. 筛选功能启用:开启Pyviz的filter_menu后,页面会自动生成基于group属性的下拉菜单,你可以选择只显示graph_1、graph_2或graph_3的内容
  4. 原有逻辑保留:完全保留了你原来的节点颜色规则(规则节点浅蓝色、项节点浅绿色)和支持度转节点大小的逻辑

注意事项

如果不同子图中有相同的项节点(比如多个子图都包含牛奶这个节点),上面的代码会让这个节点只属于最后添加的子图分组。如果希望共享节点在选中任意分组时都显示,可以修改节点的group属性为列表(比如["graph_1", "graph_2"]),不过Pyviz默认的筛选菜单是精确匹配,这时候可能需要自定义筛选逻辑,或者给共享节点添加多个分组标签(比如"graph_1|graph_2")后用模糊匹配。

备注:内容来源于stack exchange,提问作者rooya sh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:32:38