十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GraphRag 知识图谱数据清洗 3 步实战:实体去重、图剪枝与 PMI 权重降噪

GraphRag 知识图谱数据清洗 3 步实战:实体去重、图剪枝与 PMI 权重降噪 GraphRag 知识图谱数据清洗 3 步实战实体去重、图剪枝与 PMI 权重降噪【免费下载链接】graphragA modular graph-based Retrieval-Augmented Generation (RAG) system项目地址: https://gitcode.com/GitHub_Trending/gr/graphragLLM 抽取出的实体名带 HTML 转义符和首尾空格、同一实体大小写不一致、低权重噪声边把图谱连成一张毛线团——这些问题不处理下游检索与社区摘要的质量会从源头劣化。GraphRag 是一个模块化图结构检索增强生成RAG系统内置了一条「文本标准化 → 行级去重 → 图剪枝」的三级清洗链。本文逐层拆解这 3 步的实现机制再走查一条端到端数据链路最后给出剪枝参数调优与常见坑的排查思路。机制拆解GraphRag 数据清洗的 3 级流水线1. 文本级净化clean_str 与空值守门图谱构建的第一步是把 LLM 的原始输出洗成可聚合的文本。核心工具是 packages/graphrag/graphrag/index/utils/string.py 中的clean_strresult html.unescape(input.strip()) return re.sub(r[\x00-\x1f\x7f-\x9f], , result)它做三件事还原 HTML 转义amp;→、去首尾空白、剔除不可见控制字符。之所以必要是因为 LLM 抽取的实体记录经常夹带这些杂质。看调用点就明白了——在 packages/graphrag/graphrag/index/operations/extract_graph/graph_extractor.py 中每条 LLM 输出的实体/关系记录都先过一遍它且实体名、类型、源/目标节点统一转大写entity_name clean_str(record_attributes[1].upper()) entity_description clean_str(record_attributes[3]) source clean_str(record_attributes[1].upper())效果 apple 、Apple、amp;Apple最终收敛到同一个节点名为后两级去重打下基础。配套还有两道守门工具packages/graphrag/graphrag/index/utils/is_null.py 的is_null判定None/NaN在 embedding 环节run_embed_text.py拦截空文本避免无效向量化请求dict_has_keys_with_typesindex/utils/dicts.py按(字段名, 类型)清单校验 LLM 结构化输出字段缺失或类型不匹配直接判为不合格记录丢弃。2. 行级去重finalize 与 stable_lcc文本干净了同一批次里重复的实体行怎么合并答案在两个 finalize 操作中。finalize_entities按title去重并回填度数finalize_relationships的关键逻辑只有几行key (row.get(source, ), row.get(target, )) if key in seen: continue row[combined_degree] degree_map.get(key[0], 0) degree_map.get(key[1], 0)以(source, target)二元组为键去重同时计算combined_degree两端节点度数之和——这个字段后续会被社区检测用来判断一条边连了两个多重要的节点。每行还会被分配uuid4主键与human_readable_id保证 parquet 落盘后每行可寻址。更隐蔽的问题是方向不一致A→B和B→A会被当成两条边。packages/graphrag/graphrag/graphs/stable_lcc.py 的stable_lcc用四步消解它edges[source_column] edges[source_column].apply(_normalize_name) # 1. 名称归一化 lcc_nodes largest_connected_component( edges, source_columnsource_column, target_columntarget_column ) # 2. 只保留最大连通分量其后还有两步小字典序节点恒作 source方向固定、drop_duplicates消灭反向重复对最后按字典序排序。stable 的含义即无论输入行序如何输出完全一致。这不只是洁癖——增量索引update 流程依赖确定性的边表做 diff否则每次全量重建结果都会抖动。3. 图级剪枝prune_graph 与 PMI 边权重前两级解决重复这一级解决噪声。packages/graphrag/graphrag/index/operations/prune_graph.py 是整条清洗链里参数最丰富的环节def prune_graph( entities: pd.DataFrame, relationships: pd.DataFrame, min_node_freq: int 1, max_node_freq_std: float | None None, min_node_degree: int 1, max_node_degree_std: float | None None, min_edge_weight_pct: float 40, remove_ego_nodes: bool False, lcc_only: bool False, ) - tuple[pd.DataFrame, pd.DataFrame]:它按四个维度筛节点和边频率frequency min_node_freq的实体几乎没出现的删除max_node_freq_std可按「均值 k 倍标准差」再砍掉高频异常值度数min_node_degree清孤立/低连节点max_node_degree_std限制超中心节点边权重min_edge_weight_pct40表示删除权重排在第 40 百分位以下的边默认就砍掉一半弱连接结构remove_ego_nodesTrue摘除度数最高的 ego 节点lcc_onlyTrue只保留最大连通分量。边从哪里来、怎么算packages/graphrag/graphrag/graphs/edge_weights.py 提供 PMI点互信息权重edges_df[edge_weight_col] edges_df[prop_weight] * np.log2( edges_df[prop_weight] / (edges_df[source_prop] * edges_df[target_prop]) )直觉上两个高频节点之间即使共现很多PMI 也不高真正信息量大的共现才会得到高权重。这就是为什么美国这种超级枢纽不会把所有边都刷成大权重。若嫌 PMI 仍偏科可用同文件里的calculate_rrf_edge_weights它对 PMI 排名与原始权重排名做倒数排名融合更平滑。端到端走查一条文本如何变成干净图谱把上面三级串起来就是 GraphRag 索引管道的图谱构建链路输入原始文档经 input 模块解析、切分为 text unitsindex/text_splitting/抽取extract_graph调 LLM 抽实体与关系每条记录过clean_str标准化定稿finalize_graph阶段按 title / (source, target) 去重回填degree与combined_degree分配主键剪枝prune_graph依次执行频率、度数、边权重百分位过滤可选 LCC 收敛落盘产物是entities.parquet、relationships.parquet、communities.parquet等标准表格式定义见 docs/index/outputs.md示例产物可参考docs/examples_notebooks/inputs/目录。也就是说LLM 的脏活在第 2 步被压平第 3、4 步分别用确定性的行级与图级规则收口社区检测Leiden拿到的是已经去过重、去过噪的图。调优与避坑剪枝参数怎么调、坑在哪参数入口以上prune_graph参数均可在config.yaml的prune_graph段配置模型定义见 packages/graphrag/graphrag/config/models/prune_graph_config.py。调参建议参数默认调优建议min_edge_weight_pct40起点调到 60 时警惕 LCC 碎裂min_node_freq/max_node_freq_std1 / None语料小几十篇时把 freq 提到 2 见效明显remove_ego_nodesFalse出现单节点吞掉半个社区时再开lcc_onlyFalse语料主题分散时为 True 会误删有效子图⚠️三个最常见的坑剪枝过度导致社区碎片化min_edge_weight_pct拉太高后原本连通的子图被切断communities里出现一堆两三个节点的小社区。排查方法对比剪枝前后relationships.parquet的行数与 LCC 规模从 40 逐步上调。拼写级重复不会自动合并clean_str 大写只统一大小写/空白/转义Microsoft与MSFT这类别名仍会是两个节点——这不是 bug需要靠frequency阈值 业务侧的同义词表处理别指望管道自动消歧。结果每次跑都不一样如果自定义了中间步骤检查是否破坏了stable_lcc的确定性排序约定方向固定 字典序。官方实现保证同输入同输出任何绕过它的自定义逻辑都可能让增量更新失效。可视化验证剪枝效果最快的验证方式是导出 GraphML 快照丢进 Gephi 看度分布变化具体操作布局、外观面板配置见 docs/visualization_guide.md。图 1Gephi 中加载清洗后的实体-关系图谱可直观对比剪枝前后节点度数与连通分量的差异收束这条清洗链的适用边界这套「文本标准化 → 行级去重 → 图剪枝」链路对LLM 抽取 结构化落表的图谱构建非常称职但它不做别名消歧、也不做关系冲突仲裁——多语言语料或强领域缩写场景仍需业务层补规则。想动手验证最快的下一步clone 仓库git clone https://gitcode.com/GitHub_Trending/gr/graphrag用docs/examples_notebooks/inputs/里自带的 Operation Dulce 示例产物跑一遍docs/examples_notebooks/global_search.ipynb再对照本文参数表做一次剪枝实验。延伸阅读数据输入与切分docs/index/inputs.md输出表结构docs/index/outputs.md可视化指南docs/visualization_guide.md【免费下载链接】graphragA modular graph-based Retrieval-Augmented Generation (RAG) system项目地址: https://gitcode.com/GitHub_Trending/gr/graphrag创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表