跳到主要内容

文本预处理

学习目标

完成本节后,你将能够:

  • 理解文本预处理到底在解决什么问题
  • 掌握清洗、标准化、分词、停用词等常见步骤
  • 写出一个可直接运行的预处理函数
  • 明白为什么预处理不是越重越好,而是任务驱动

一、为什么文本要预处理?

原始文本通常很“脏”:

  • 大小写不统一
  • 标点很多
  • 链接、数字、表情混在一起
  • 同一个意思可能有很多写法

你可以把文本预处理想成“洗菜”:

  • 不洗,模型很难直接下锅
  • 洗过头,又可能把营养一起洗掉

所以预处理的核心不是“洗得越干净越好”,而是:

让文本更适合当前任务。


二、预处理最常见的几步

步骤常见作用
小写化统一英文大小写
去链接 / 特殊符号降低无意义噪声
去多余空格统一格式
分词拆成更小处理单位
停用词处理去掉高频低信息词
数字 / 特殊模式标准化统一某些规则模式

但记住:

  • 这些步骤不是每次都全做
  • 也不是做得越多越好

三、先跑一个最小预处理函数

下面我们先用英文示例,因为英文更容易用标准库直接演示。
思路对中文同样适用,只是中文通常要借助更专业的切分工具。

import re

stopwords = {"the", "is", "a", "an", "and", "to", "of", "in"}


def preprocess(text):
text = text.lower() # 1. 小写化
text = re.sub(r"http\\S+", " ", text) # 2. 去链接
text = re.sub(r"[^a-z0-9\\s]", " ", text) # 3. 去特殊符号
text = re.sub(r"\\s+", " ", text).strip() # 4. 合并多余空格

tokens = text.split() # 5. 简单分词
tokens = [t for t in tokens if t not in stopwords] # 6. 去停用词
return tokens


sample = "The movie is AMAZING, and the ending is full of surprises!"
print(preprocess(sample))

这个例子最想让你看到什么?

文本预处理通常不是一个神秘大黑箱,
而是一连串很朴素的小步骤。

真正关键的是:

  • 每一步为什么存在
  • 它是否真的适合当前任务

四、小写化为什么常见?

1. 统一词形

在英文里:

  • Apple
  • apple
  • APPLE

很多任务里可能都想当成同一个词。

2. 但不是永远都该做

例如:

  • 命名实体识别
  • 品牌名识别

大小写本身可能就是重要信息。

所以要记住:

  • 预处理一定要和任务绑定看

五、分词为什么这么重要?

1. 因为模型不直接处理“整句原文”

它通常需要更小单位:

  • 子词

2. 英文和中文情况不同

英文天然有空格,
简单场景里可以直接 split()

中文没有天然空格,
分词问题会更复杂。

例如:

  • “自然语言处理”

到底切成:

  • 自然语言处理

还是:

  • 自然 / 语言 / 处理

会直接影响后续表示和模型效果。

3. 一个简单中文切分意识

即便现在不引入专业分词工具,你也要先建立一个判断:

中文文本不是天然就有词边界。


六、停用词为什么有用,又为什么危险?

1. 有用的地方

高频但区分度弱的词,例如:

  • the
  • is
  • and

在很多传统模型里确实容易带来噪声。

2. 危险的地方

某些看似不起眼的词,可能非常关键。

例如:

  • not good

如果把 not 去掉,语义就翻转了。

3. 所以停用词不是“必删项”

更合理的想法是:

  • 它是一个可选操作
  • 是否使用取决于任务

七、再看一个稍完整点的小练习

import re

stopwords = {"the", "is", "a", "an", "and", "to", "of", "in", "this"}


def preprocess(text):
text = text.lower()
text = re.sub(r"http\\S+", " ", text)
text = re.sub(r"[^a-z0-9\\s]", " ", text)
text = re.sub(r"\\s+", " ", text).strip()
tokens = text.split()
tokens = [t for t in tokens if t not in stopwords]
return tokens


texts = [
"This course is easy to follow!",
"The examples are clear and practical.",
"I love the hands-on exercises in this class.",
]

for text in texts:
print("原文 :", text)
print("处理后 :", preprocess(text))
print("-" * 30)

这个例子真正值得关注什么?

你要看:

  • 哪些信息被保留了
  • 哪些信息被删除了
  • 删除是否符合任务需要

这比死记“预处理步骤表”更重要。


八、传统模型和预训练模型的预处理思路为什么不同?

1. 传统机器学习

通常更依赖人工预处理,因为模型本身比较浅,
对噪声比较敏感。

2. 预训练模型 / 大模型

很多时候更依赖模型自带 tokenizer,
如果你在外面过度清洗,反而可能:

  • 破坏原始结构
  • 丢掉模型能利用的信息

3. 一个很重要的判断

不是所有 NLP 时代都用同一套预处理策略。


九、初学者常见误区

1. 觉得预处理越多越高级

不对。
删太多信息,效果反而可能更差。

2. 不区分任务就套同一套规则

文本分类、检索、NER、RAG 的预处理策略常常不同。

3. 中文也直接 split()

在很多任务里通常不够。


小结

文本预处理最重要的不是“洗干净”,而是:

围绕任务,把文本整理成更适合当前模型处理的形式。

下一节我们会继续往前走,解决另一个关键问题:

文本怎么表示成数字?


练习

  1. preprocess() 再加一个数字替换逻辑,把所有数字替换成 <num>
  2. not 加进停用词,再观察情感句子会发生什么问题。
  3. 自己找 5 条短评论,跑一遍预处理,看看哪些信息被保留、哪些被删掉。
  4. 想一想:在 NER 场景里,小写化为什么可能反而有害?