文本预处理与分词是自然语言处理(NLP)中的关键步骤,旨在将原始文本转换为机器可理解的数字形式。核心概念包括标准化、分词和去停用词。标准化涉及处理大小写、去除噪音字符和统一格式;分词则将句子切分为词语,中文常用`jieba`库完成;去停用词旨在移除无意义的常用词,但需谨慎以保留对情感分析等任务重要的词语。读者将学会如何构建一个完整的文本预处理流水线,从原始文本到干净的词袋表示。掌握这些技能后,读者能够根据具体任务需求,灵活调整预处理步骤,避免常见错误,如过度小写化、误删情感符号或无法识别新词,从而为后续的NLP模型提供高质量的输入数据。
文本预处理与分词
自然语言处理 (NLP) 是机器学习中专门处理人类语言的分支。但机器只懂数字,不懂"今天天气真好"这种字符串。所以第一步永远是把文字变成数字,而"怎么变"决定了后续模型能学到多少信息。
这一章我们把文本预处理的整个流水线走一遍:从一段原始评论,到干净的"词袋"。
为什么预处理这么重要
一个真实例子。原始评论:
" 看了这部《流浪地球 2》, 真的太震撼了!!! 真❤️❤️❤️, 推荐给 5 星好评!!!! "
如果直接交给模型,它会被这些"噪音"干扰:
- 多余空格和换行
- 大小写混用 (这部 vs 这)
- 标点符号重复 (!!!)
- emoji (❤️)
- 数字符号 (5 vs 五)
预处理的目标就是标准化,让"震撼"和"震撼!"被识别成同一个词。
4 个核心步骤
1. 标准化:大小写、去噪、规范化
英文一般会小写化 + 用正则把奇怪的字符去掉:
import re
text = " 看了这部《流浪地球 2》, 真的太震撼了!!! 真❤️❤️❤️, 推荐给 5 星好评!!!! "
# 1. 去首尾空白
text = text.strip()
# 2. 全部小写 (英文场景)
text_lower = text.lower()
# 3. 用正则保留中文/英文/数字, 去掉 emoji 等
text_clean = re.sub(r"[^\u4e00-\u9fa5a-zA-Z0-9\s]", " ", text)
# 4. 多空格压成一个
text_clean = re.sub(r"\s+", " ", text_clean).strip()
print(text_clean) # "看了这部 流浪地球 2 真的太震撼了 推荐给 5 星好评"
2. 分词:把句子切成词
英文天然用空格分词。中文没有空格,需要算法:
import jieba
text = "我爱自然语言处理"
tokens = list(jieba.cut(text))
print(tokens) # ['我', '爱', '自然', '语言', '处理']
jieba 是中文 NLP 最常用的分词库,基于前缀词典 + 动态规划。安装: pip install jieba。
3. 去停用词
停用词 (stop words) 是"了"、"的"、"是"这种几乎不携带语义的词。但对情感分析要谨慎,否定词"不"必须保留。
# 常见停用词
stopwords = {"的", "了", "是", "在", "和", "有", "我", "你", "他", "她", "它"}
tokens = ['我', '爱', '自然', '语言', '处理']
filtered = [t for t in tokens if t not in stopwords and len(t) > 1]
print(filtered) # ['爱', '自然', '语言', '处理']
4. 词形还原与词干提取 (英文)
英文的 running / ran / runs 其实是同一个词,需要还原到原型:
from nltk.stem import PorterStemmer, WordNetLemmatizer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
# 词干提取: 粗略, 可能不是真单词
print(stemmer.stem("running")) # "run"
print(stemmer.stem("studies")) # "studi" (不是单词)
# 词形还原: 精确, 输出真单词
print(lemmatizer.lemmatize("running", pos="v")) # "run"
print(lemmatizer.lemmatize("studies", pos="n")) # "study"
完整流水线:一段评论变干净词袋
我们把上面的步骤组合起来,给一个完整的处理函数:
import re
import jieba
STOPWORDS = {"的", "了", "是", "在", "和", "有", "我", "你", "他", "她", "它", "也", "都", "就", "都"}
def preprocess_chinese(text: str, remove_stopwords: bool = True) -> list[str]:
# 1. 去空白 + 标准化
text = text.strip().lower()
# 2. 只保留中英文和数字
text = re.sub(r"[^\u4e00-\u9fa5a-zA-Z0-9\s]", " ", text)
text = re.sub(r"\s+", " ", text).strip()
# 3. 分词
tokens = list(jieba.cut(text))
# 4. 过滤: 去停用词, 去掉单字 (常用停用词已覆盖)
if remove_stopwords:
tokens = [t for t in tokens if t not in STOPWORDS and len(t) >= 1]
# 5. 去掉纯空格
tokens = [t for t in tokens if t.strip()]
return tokens
raw = " 看了这部《流浪地球 2》, 真的太震撼了!!! 真❤️❤️❤️, 推荐给 5 星好评!!!! "
print(preprocess_chinese(raw))
# ['看', '这部', '流浪', '地球', '2', '真', '太', '震撼', '推荐', '5', '星', '好评']
三个常见坑
-
不要全部小写化: "iPhone 14" 小写后变成 "iphone 14",专有名词丢信息。可以用 NER (命名实体识别) 标记再决定是否小写。
-
emoji 不是垃圾: 情感分析里 😍😍😍 是强烈的正面信号。可以用
emoji.demojize()转成文字描述。 -
错别字/拼音: 真实用户评论里到处都是"蓝瘦香菇"代替"难受想哭"。简单的正则匹配词典,复杂的用 text2vec 找近义词。
小结
- 预处理 = 标准化 + 分词 + 去停用词 + (词形还原)
- 英文用空格分词 + 词形还原;中文用 jieba 等分词工具
- 没有"标准流程",根据任务决定保留什么 (情感分析不能乱去停用词)
- 永远是流水线:原始文本 → 标准化 → 分词 → 过滤 → 干净 token 列表
练习思考
- 用 jieba 分词 "我今天去星巴克喝了一杯拿铁",看看哪些词分错了?怎么用
add_word修正? - 给一个英文句子 "I LOVE running!!! " 写预处理函数,要求保留情感强度 (LOVE 不要变小写)。
- 思考:为什么"商品评论"和"法律合同"的预处理流程应该不一样?
章末小测验
检验你对《文本预处理与分词》的掌握程度。
中文分词最常用的开源工具是?
为什么情感分析中'不推荐'不能拆成'不'和'推荐'?