GraphRAG 数据清洗:3 步把脏数据洗干净,变成可检索的知识图谱

发布时间:2026/9/1 8:35:46
GraphRAG 数据清洗:3 步把脏数据洗干净,变成可检索的知识图谱 GraphRAG 数据清洗3 步把脏数据洗干净变成可检索的知识图谱【免费下载链接】graphragA modular graph-based Retrieval-Augmented Generation (RAG) system项目地址: https://gitcode.com/GitHub_Trending/gr/graphragGraphRAG 是微软开源的模块化图结构检索增强生成系统它先用 LLM 从文档中构建实体关系图谱再基于图谱做检索。做知识图谱数据清洗时翻车几乎都发生在数据进场环节HTML 转义字符混进实体名、字段缺失、图里散落孤立节点。本文按一次真实索引任务走完整流程配置怎么定、三步清洗按什么顺序做、效果怎么验证。什么脏数据会让 GraphRAG 翻车最常见的翻车点是实体名污染。LLM 的抽取结果靠分隔符逐条解析源文档里若有 HTML 转义内容实体名可能解析出Operation amp; Dulce这样的值。不还原的话同一实体会以amp;和两种形态各存一条图上凭空多出重复节点——实体提取失败排查通常先从这一步查起。第二类脏数据在图结构层面。主题不相干的文档抽取后会产生孤立节点和小型连通簇社区检测Leiden在由多个不连通分量拼成的图上跑得到的社区层级没有意义。再往细里说字段缺失、权重解析成 NaN 的记录如果放过去会直接污染度数统计和嵌入结果。分块参数和校验字段怎么配分块参数是清洗的预处理部分都在项目配置里。max_tokens按模型上下文窗口定overlap保证关键概念不被切在块边界上。顺手打开 graphml 快照方便后面验证图结构。核心配置input: type: files chunking: strategy: token max_tokens: 1200 overlap: 100 snapshots: graphml: true必填字段校验不能直接写在配置里要在进管道前做每份文档记录若缺少 id、text、source 等核心字段或类型不对直接跳过该文档。项目里现成的函数在packages/graphrag/graphrag/index/utils/dicts.py下面细说。三步清洗流程GraphRAG 文本标准化clean_str 的三层处理实现在 packages/graphrag/graphrag/index/utils/string.pyclean_str的逻辑很克制非字符串直接原样返回html.unescape还原amp;之类转义并去掉首尾空白正则剔除\x00-\x1f与\x7f-\x9f区间的控制字符。调用时机在解析抽取结果时packages/graphrag/graphrag/index/operations/extract_graph/graph_extractor.py里每条实体名、类型、描述、关系两端点和边描述写入 DataFrame 前都会先过一遍clean_str。这一步等于在抽取出口把脏数据拦下不让它进图。字段校验与空值过滤存在、类型、空值三段链校验是一条链顺序固定。先查存在性dict_has_keys_with_types(data, [(title, str), (type, str)])发现字段缺失立刻返回 False。再做类型验证对每个字段尝试field_type(value)转换TypeError 或 ValueError 即判无效inplaceTrue时转换结果会被写回顺手完成类型统一。最后做空值判断packages/graphrag/graphrag/index/utils/is_null.py的is_null同时检查 None 和 float NaN后者是value is None抓不住的而 NaN 恰好藏在权重、度数这类数值字段里。管道里记录级校验在抽取写入前跑空值检查则用在文本嵌入等环节。stable_lcc 连通分量去噪它到底做了什么代码在packages/graphrag/graphrag/graphs/stable_lcc.py注意在 graphs/ 下而非 index/utils/由graphrag/index/operations/cluster_graph.py在社区检测前调用。原理用三句话讲清先把节点名归一化HTML 反转义、转大写、去空白让同名节点的大小写和转义变体合并再求最大连通分量把它之外的节点全部丢掉孤立节点和小型簇都在这一步出局最后按节点名排序边并去重反向对保证同一输入永远得到同一输出这就是 stable 的含义。清洗效果怎么验证别信看起来变好了看数字。三个指标就够。实体规模清洗前后对比输出目录里entities.parquet、relationships.parquet的行数以及去重后的节点数变化能说明清洗实际动过多少数据。连通分量覆盖把 relationships 过一遍stable_lcc对比保留边数占比。占比很低说明图碎裂严重要回源头数据找原因。孤立节点占比不属于最大连通分量的节点数除以总节点数。拿节点集的小片段import pandas as pd rels pd.read_parquet(output/relationships.parquet) nodes set(rels.source) | set(rels.target)图级别的直觉验证把 graphml 快照导进 Gephi在 Network Overview 面板看度数分布和分量布局巨分量是否一家独大一眼便知。踩坑记录清洗过度误删专有名词现象ATT 这类名字里的被某层预处理写成amp;或被自写过滤器当特殊字符剥掉。原因clean_str只处理转义和控制字符不会删合法标点问题多半出在你额外加的一层归一化。处理定稿前抽几百个实体名抽查专有名词进白名单额外的归一化步骤用替换后再校验而不是先删掉。大规模数据清洗耗时现象逐行清洗加全量索引改一次配置重跑一遍不现实。原因逐行clean_str、DataFrame 写入、graphml 导出都是串行 IO规模一上来就放大。处理用增量索引更新能力分批处理必填字段校验和空值过滤前置到索引之前别让脏数据消耗 LLM 调用。特殊字符被错误过滤现象权重字段出现 NaN度数统计跟着错。原因非数值权重解析失败时会回退 1.0但 NaN 还可能来自 float 解析等其他来源is None根本抓不到。处理数值字段统一用is_null检查写表前过滤并记下被过滤行的来源文档方便回溯。想继续深入方向有两个参照packages/graphrag/graphrag/index/operations/的写法写自己的行级清洗处理器挂进管道或者把dicts.py的校验扩展成配置驱动的字段白名单。第一轮练习建议拿仓库自带的官方 Operation Dulce 数据集docs/data/operation_dulce/跑一遍完整清洗流程它恰好同时具备上面几类问题清洗前后的实体数和连通分量差异可以直接对比。【免费下载链接】graphragA modular graph-based Retrieval-Augmented Generation (RAG) system项目地址: https://gitcode.com/GitHub_Trending/gr/graphrag创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考