趋近智
Assistant
在线
趋近智
清洗和标准化文本是为有效检索准备数据的一个非常重要的环节。检索系统的表现与它所搜索的数据质量直接相关。原始文本,特别是来自网页或扫描文档等来源的文本,通常充满可能降低嵌入 (embedding)模型表现的噪音。这些噪音包括格式瑕疵、不一致的空白字符、不相关的元数据以及敏感内容。
预处理旨在创建文本的干净、一致表示,以准确捕捉其语义。通过移除干扰元素,您可以帮助嵌入模型关注有用的内容,从而获得更准确、更相关的检索结果。本节将向您介绍标准化和清洗文本数据的常用方法。
文本标准化是将文本转换为单一、规范形式的过程。这很有必要,因为嵌入 (embedding)模型对输入中的变体很敏感,而这些变体对于人类读者来说可能不会改变其含义。例如,如果大小写不是您程序中的主要考虑因素,那么“Hello World”和“hello world”应该理想地以相似方式表示。
一个典型的起点是处理空白字符。来自不同来源的文本可能包含不规则的间距、多个换行符或制表符,这会为您的嵌入带来干扰。您可以通过将多个空白字符合并为一个空格并标准化换行符来统一它们。
from kerb.preprocessing import normalize_whitespace
raw_text = "This text has extra spaces\n\n\nand multiple newlines."
normalized = normalize_whitespace(raw_text)
print(f"原始: {repr(raw_text)}")
print(f"标准化后: {repr(normalized)}")
# 原始: 'This text has extra spaces\n\n\nand multiple newlines.'
# 标准化后: 'This text has extra spaces and multiple newlines.'
另一个微小但很有用的工作是Unicode标准化。像“é”这样的字符在Unicode中可以用多种方式表示。对其进行标准化可确保相同的字符始终由相同的字节序列表示,这对保持分词 (tokenization)一致性很有意义。
不同的文档格式会带来特有的噪音类型。网页中充满了HTML标签、脚本和CSS,而从PDF中提取的文本可能包含因换行符和不规则间距造成的连字符瑕疵。移除这些结构性噪音是首要步骤。
对于HTML内容,您可以提取干净、人类可读的文本,同时丢弃所有标记 (token)。
from kerb.preprocessing import extract_text_from_html
html_content = """
<html>
<body>
<h1>Main Title</h1>
<p>This is <strong>important</strong> content.</p>
<script>alert('noise');</script>
</body>
</html>
"""
clean_content = extract_text_from_html(html_content)
print(clean_content)
# Main Title
# This is important content.
类似地,如果您正在使用Markdown,您可能希望去除格式以获取底层文本。strip_markdown函数可用于此目的,将**bold**文本转换为bold。
对于许多RAG程序,URL、电子邮件地址和电话号码等元素是可能扭曲文本块语义的噪音。移除它们有助于嵌入 (embedding)模型关注主要内容。更值得一提的是,移除或编辑个人身份信息(PII)是保护隐私和数据安全的常规做法。
您可以单独移除这些元素,也可以将其作为大型清洗流程的一部分。对于处理敏感数据的程序,您可能选择编辑而非仅仅移除PII,用一个通用占位符替换敏感数据。
from kerb.safety import redact_pii
sensitive_text = "Please contact support at [email protected] or call 555-123-4567 for help."
redacted_text = redact_pii(sensitive_text)
print(f"原始: {sensitive_text}")
print(f"编辑后: {redacted_text}")
# 原始: Please contact support at [email protected] or call 555-123-4567 for help.
# 编辑后: Please contact support at [REDACTED_EMAIL] or call [REDACTED_PHONE] for help.
这种方法在保护敏感内容的同时,保留了有关某段内容存在的上下文 (context)。
虽然您可以逐个应用这些函数,但定义一个可重用的预处理流程会更高效。normalize_text函数与NormalizationConfig结合使用,允许您以声明式方式协调多个清洗和标准化步骤。您可以为不同类型的内容或RAG流程的不同阶段定义不同的配置。
让我们构建一个处理网络抓取文章的常规流程。目的是将文本转为小写,移除URL和电子邮件,并标准化所有空白字符和引号。
from kerb.preprocessing import normalize_text, NormalizationConfig, NormalizationLevel
# 为我们的流程定义一个配置
web_article_config = NormalizationConfig(
level=NormalizationLevel.STANDARD, # 应用标准Unicode、引号和空白字符标准化
lowercase=True,
remove_urls=True,
remove_emails=True,
remove_extra_spaces=True
)
messy_article_snippet = """
Check out our new "Report" at https://example.com/report!
Contact [email protected] for info.
It's an in-depth analysis of AI’s impact.
"""
# 一次调用应用整个流程
processed_text = normalize_text(messy_article_snippet, config=web_article_config)
print("### 预处理前 ###")
print(messy_article_snippet)
print("\n### 预处理后 ###")
print(processed_text)
此“前后”对比呈现了我们流程的结果:
预处理前
Check out our new "Report" at https://example.com/report!
Contact [email protected] for info.
It's an in-depth analysis of AI’s impact.
预处理后
check out our new "report" at !
contact for info.
it's an in-depth analysis of ai's impact.
现在的输出是一段干净、标准化的文本块。这个清理过的版本更适合嵌入 (embedding)模型,因为噪音已被清除,只留下核心文本内容。预处理的程度需要权衡。过于激进的清洗可能会移除有用的上下文 (context),因此测试您的流程对检索效果的影响总是一个明智的做法。
在文档加载、分块并彻底清洗之后,我们拥有了一个高质量的文本片段数据集。每个片段都是一个语义连贯且标准化的信息单元,为下一步做好了准备:通过嵌入将文本转换为数值表示。