ARTICLE DETAIL

资讯详情

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

如何去除杂音,进行数据清洗

如何去除杂音,进行数据清洗 数据清洗是 RAG 系统中最关键但最容易被忽视的环节。垃圾进垃圾出——如果索引的是脏数据检索结果和生成答案都会出问题。一、什么是“杂音”杂音类型示例影响格式噪声页眉页脚、页码、目录、水印污染向量导致误匹配内容噪声广告、推荐链接、版权声明、免责声明浪费 Token误导模型结构噪声重复的标题、多余的空格/换行、特殊字符增加存储降低检索精度语言噪声OCR 识别错误、乱码、拼写错误语义扭曲检索失败无关内容导航栏、侧边栏、评论区、相关推荐完全不相关干扰检索二、数据清洗的完整流程原始文档 ↓ 1. 格式转换PDF/Word → 纯文本 ↓ 2. 预处理去页眉页脚、去水印、去页码 ↓ 3. 正则清洗去特殊字符、多余空格、乱码 ↓ 4. 内容过滤去广告、去免责声明、去导航 ↓ 5. 文本规范化统一大小写、标点、数字格式 ↓ 6. 去重重复段落、近似内容 ↓ 7. 质量过滤过短、无意义内容 ↓ 清洗后的文本 → 切割 → 向量化三、各步骤具体实现1. 格式转换后的预处理针对 PDF 的特殊处理importredefclean_pdf_text(text:str)-str:清洗 PDF 提取后的常见噪声# 1. 去除页眉页脚通常行数很少且包含页码或日期linestext.split(\n)# 去掉首尾各3行如果它们包含页码或日期模式iflen(lines)10:# 检测页码模式第1页、Page 1、1/10等page_patternr第?\s*\d\s*页|Page\s*\d|^\d$|^\d/\d$# 去掉顶部可能的页眉whilelinesandre.search(page_pattern,lines[0]):lines.pop(0)# 去掉底部可能的页脚whilelinesandre.search(page_pattern,lines[-1]):lines.pop()text\n.join(lines)# 2. 去除水印常见模式watermark_patterns[r机密|Confidential|草稿|Draft|内部使用|Do Not Distribute]forpatterninwatermark_patterns:textre.sub(pattern,,text,flagsre.IGNORECASE)# 3. 去除孤立页码textre.sub(r\n\s*\d\s*\n,\n\n,text)returntext针对 HTML 的特殊处理frombs4importBeautifulSoupimportredefclean_html_text(html:str)-str:提取 HTML 正文去除导航、广告等soupBeautifulSoup(html,html.parser)# 1. 移除明显的噪声标签noise_selectors[nav,header,footer,aside,.sidebar,.ad,.advertisement,.recommendation,.comments,.related-posts,.newsletter]forselectorinnoise_selectors:fortaginsoup.select(selector):tag.decompose()# 2. 移除 script 和 stylefortaginsoup([script,style,noscript,meta,link]):tag.decompose()# 3. 提取正文优先 main/article/bodymainsoup.find(main)orsoup.find(article)orsoup.find(body)ifnotmain:mainsoup# 4. 获取文本textmain.get_text(separator\n,stripTrue)# 5. 清理多余空行textre.sub(r\n{3,},\n\n,text)returntext2. 正则表达式清洗通用importrefromtypingimportListdefbasic_text_cleaning(text:str)-str:基础正则清洗# 1. 去除多余空白多个空格 → 个空格textre.sub(r[ \t], ,text)# 2. 去除多余换行多个换行 → 两个换行textre.sub(r\n{3,},\n\n,text)# 3. 去除控制字符保留换行和制表符textre.sub(r[\x00-\x08\x0b\x0c\x0e-\x1f\x7f],,text)# 4. 去除零宽字符textre.sub(r[\u200b\u200c\u200d\u200e\u200f\ufeff],,text)# 5. 规范化标点英文标点后加空格textre.sub(r([.?!,;:])([^\s]),r\1 \2,text)# 6. 规范化引号弯引号转直引号texttext.replace(“,).replace(”,).replace(‘,).replace(’,)# 7. 规范化连字符不同 Unicode 连字符统一为 -textre.sub(r[−—–],-,text)returntext.strip()3. 特殊字符与乱码清理deffix_garbled_text(text:str)-str:修复常见乱码和特殊字符# 1. 去除不可打印字符importstring printableset(string.printable)text.join(cifcinprintableorcin\n\r\telse forcintext)# 2. 常见 OCR 错误纠正ocr_fixes{0:O,# 数字0和字母O混淆1:l,# 数字1和字母l混淆rn:m,# rn 被识别成 mvv:w,# vv 被识别成 w}forwrong,correctinocr_fixes.items():texttext.replace(wrong,correct)# 3. 去除 Unicode 表情符号通常是无用噪声emoji_patternre.compile([\U0001F600-\U0001F64F# 表情符号\U0001F300-\U0001F5FF# 符号\U0001F680-\U0001F6FF# 交通标志\U0001F1E0-\U0001F1FF# 国旗],flagsre.UNICODE)textemoji_pattern.sub(,text)returntext4. 内容过滤黑名单# 常见噪声关键词NOISE_KEYWORDS[# 网站导航首页,上一篇,下一篇,相关文章,热门推荐,点击这里,了解更多,立即注册,免费订阅,# 版权与法律版权所有,Copyright,All rights reserved,隐私政策,使用条款,免责声明,本网站,# 广告广告,赞助,推广,AD,Sponsored,# 表单姓名,邮箱,电话,提交,取消,]# 噪声模式正则NOISE_PATTERNS[r©\s*\d{4},# 版权年份r第[一二三四五六七八九十\d]章,# 章节号保留标题即可r图\d[.、],# 图片标注r表\d[.、],# 表格标注r参考文献.*$,# 参考文献开始后面内容可能有用但需谨慎]deffilter_noise_lines(text:str)-str:按行过滤噪声linestext.split(\n)filtered[]forlineinlines:lineline.strip()# 跳过空行ifnotline:continue# 跳过过短的行可能无意义iflen(line)10andnotany(c.isalpha()forcinline):continue# 跳过包含噪声关键词的行is_noiseFalselower_lineline.lower()forkeywordinNOISE_KEYWORDS:ifkeyword.lower()inlower_line:is_noiseTruebreakifis_noise:continue# 跳过匹配噪声模式的行forpatterninNOISE_PATTERNS:ifre.search(pattern,line):is_noiseTruebreakifnotis_noise:filtered.append(line)return\n.join(filtered)5. 文本规范化defnormalize_text(text:str)-str:文本格式规范化# 1. 统一英文大小写保留专有名词的原始大小写这里简化处理# 可以只对句子首字母大写其余小写# 2. 统一数字格式中文数字转阿拉伯数字可选# 3. 统一日期格式可选# 4. 修复中英文之间的空格# 中文和英文之间加空格textre.sub(r([a-zA-Z])([\u4e00-\u9fff]),r\1 \2,text)textre.sub(r([\u4e00-\u9fff])([a-zA-Z]),r\1 \2,text)# 5. 去除中文和标点之间的空格textre.sub(r([\u4e00-\u9fff])\s([。】》]),r\1\2,text)textre.sub(r([【《“‘])\s([\u4e00-\u9fff]),r\1\2,text)returntext6. 去重fromdifflibimportSequenceMatcherdefdeduplicate_chunks(chunks:List[str],similarity_threshold:float0.85)-List[str]:去除重复或高度相似的文本块defis_similar(a:str,b:str,threshold:float)-bool:判断两个文本是否相似# 快速判断完全相等ifab:returnTrue# 长度相差超过50%的不太可能相似ifmin(len(a),len(b))/max(len(a),len(b))0.5:returnFalse# 计算相似度ratioSequenceMatcher(None,a,b).ratio()returnratiothreshold unique[]forchunkinchunks:is_dupFalseforexistinginunique:ifis_similar(chunk,existing,similarity_threshold):is_dupTruebreakifnotis_dup:unique.append(chunk)returnunique7. 质量过滤defquality_filter(chunks:List[str],min_length:int50,max_length:int2000,min_alpha_ratio:float0.3)-List[str]:根据质量指标过滤filtered[]forchunkinchunks:# 长度过滤iflen(chunk)min_lengthorlen(chunk)max_length:continue# 字母/汉字占比过滤避免全是符号/数字alpha_countsum(1forcinchunkifc.isalpha())ifalpha_count/len(chunk)min_alpha_ratio:continue# 大写字母比例过滤避免全大写噪声upper_countsum(1forcinchunkifc.isupper())ifupper_countlen(chunk)*0.5:continuefiltered.append(chunk)returnfiltered四、完整清洗 PipelineclassDocumentCleaner:文档清洗流水线def__init__(self):self.steps[self.preprocess_pdf,# PDF 特殊处理self.basic_cleaning,# 基础正则清洗self.fix_garbled,# 乱码修复self.filter_noise,# 内容过滤self.normalize,# 规范化self.deduplicate,# 去重可选]defclean(self,text:str,source_type:strpdf)-str:forstepinself.steps:textstep(text,source_type)ifcallable(step)elsestepreturntextdefpreprocess_pdf(self,text:str,source_type:str)-str:ifsource_typepdf:# 调用 PDF 专用清洗textclean_pdf_text(text)returntextdefbasic_cleaning(self,text:str,source_type:str)-str:returnbasic_text_cleaning(text)deffix_garbled(self,text:str,source_type:str)-str:returnfix_garbled_text(text)deffilter_noise(self,text:str,source_type:str)-str:returnfilter_noise_lines(text)defnormalize(self,text:str,source_type:str)-str:returnnormalize_text(text)defdeduplicate(self,text:str,source_type:str)-str:# 先按段落去重paragraphstext.split(\n\n)unique_parasdeduplicate_chunks(paragraphs)return\n\n.join(unique_paras)五、针对中文的特殊清洗defchinese_specific_cleaning(text:str)-str:中文文档特殊处理# 1. 全角转半角数字、英文、标点fullwidthhalfwidth!#$%\()*,-./:;?[\\]^_{|}~full_to_halfstr.maketrans(fullwidth,halfwidth)texttext.translate(full_to_half)# 2. 中文数字转阿拉伯数字可选但建议保持原样# 如果是为了检索保留中文数字可能更好# 3. 去除中文文本中插入的英文空格但保留必要的分隔# 中文和英文之间加空格已在 normalize_text 中处理# 4. 处理中文省略号…… → ... 或保留textre.sub(r…{2,},...,text)returntext六、不同文档类型的清洗策略文档类型主要噪声推荐清洗重点PDF页眉页脚、页码、水印、换行混乱去页眉页脚、修复断行Word修订标记、注释、格式代码去除修订标记、提取正文HTML导航、广告、侧边栏、版权提取主内容、去噪声标签Markdown格式标记、链接保留结构、去除无关链接OCR文本识别错误、乱码、错位纠错、修复乱码聊天记录时间戳、系统消息、表情保留有效对话总结数据清洗的核心原则先粗后细先处理大块噪声页眉页脚再处理细节特殊字符保留语义不要过度清洗破坏原意可重现清洗规则应该可验证、可调整针对性强不同文档类型用不同策略适度原则清洗到“够用”即可追求100%完美不现实
返回列表