【NLP 基础:文本预处理、分词与词袋模型(优化版】
·
NLP
NLP 基础:文本预处理、分词与词袋模型(优化版
NLP 基础:文本预处理、分词与词袋模型(优化版)
一、文本预处理(Text Preprocessing)
1. 为什么需要文本预处理?
文本预处理的目的是将原始文本数据转换为适合机器学习模型处理的格式。通过清洗和标准化文本数据,可以提高模型的性能和准确性。
2. 文本预处理的不同策略(针对不同 NLP 任务)
| NLP 任务 | 需要的预处理操作 |
|---|---|
| 文本分类(情感分析、垃圾邮件检测) | ✅ 去停用词 ✅ 词干化 ❌ 不去除标点(可能影响情感极性) |
| 机器翻译(MT) | ❌ 不去停用词 ❌ 不词干化 ✅ 保留完整句子结构 |
| 问答系统(QA) | ✅ 词形还原 ✅ 保留实体名 ✅ 保留标点 |
| 命名实体识别(NER) | ✅ 保留原始单词形式 ❌ 不能词干化 |
3. 常见的文本预处理步骤
3.1 去除噪声(标点、URL、特殊字符)
import re
text = "I love learning NLP! It's so much fun. Visit: https://nlp.com"
text = re.sub(r"http\S+", "", text) # 去除URL
text = re.sub(r'[^\w\s]', '', text) # 去除标点符号
text = text.lower() # 统一转换为小写
print(text)
# 运行结果:
# i love learning nlp its so much fun
3.2 停用词去除(Stop Words Removal)
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
words = text.split()
filtered_words = [word for word in words if word not in stop_words]
print("去除停用词后:", filtered_words)
# 运行结果:
# ['love', 'learning', 'nlp', 'much', 'fun']
3.3 词干提取(Stemming) vs 词形还原(Lemmatization)
| 方法 | 示例 | 适用场景 |
|---|---|---|
| 词干提取(Stemming) | running → run flies → fli |
快速处理,适用于信息检索 |
| 词形还原(Lemmatization) | better → good flies → fly |
精准处理,适用于文本生成任务 |
from nltk.stem import PorterStemmer, WordNetLemmatizer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
words = ["running", "flies", "better", "caring"]
print("词干提取:", [stemmer.stem(word) for word in words])
print("词形还原:", [lemmatizer.lemmatize(word) for word in words])
# 运行结果:
# 词干提取: ['run', 'fli', 'better', 'car']
# 词形还原: ['running', 'fly', 'better', 'caring']
二、分词(Tokenization)
1. 分词的几种模式对比(适用于中文)
| 分词模式 | 适用场景 | 示例 |
|---|---|---|
| 精确模式 | 适用于文本分析,保证切分准确度 | "我喜欢学习自然语言处理" → ['我', '喜欢', '学习', '自然语言处理'] |
| 全模式 | 适用于搜索引擎,切分所有可能词汇,包含冗余 | "我喜欢学习自然语言处理" → ['我', '喜欢', '喜', '欢', '学习', '自', '然', '自然', '语言', '处理', '自然语言处理'] |
| 搜索引擎模式 | 适用于搜索引擎索引,保留长词并拆分短词 | "我喜欢学习自然语言处理" → ['我', '喜欢', '学习', '自然', '语言', '处理', '自然语言处理'] |
import jieba
text = "我喜欢学习自然语言处理"
# 精确模式
print("精确模式:", jieba.lcut(text, cut_all=False))
# 运行结果:
# ['我', '喜欢', '学习', '自然语言处理']
# 全模式
print("全模式:", jieba.lcut(text, cut_all=True))
# 运行结果:
# ['我', '喜欢', '喜', '欢', '学习', '自', '然', '自然', '语言', '处理', '自然语言处理']
# 搜索引擎模式
print("搜索引擎模式:", jieba.lcut_for_search(text))
# 运行结果:
# ['我', '喜欢', '学习', '自然', '语言', '处理', '自然语言处理']
2. 自定义词典(适用于 Jieba, THULAC, HanLP)
为什么需要自定义词典?
- 默认的分词工具可能无法识别特定领域术语,如
"深度学习"可能被错误拆分成"深度"和"学习"。 - 解决方法是添加自定义词典,确保模型能正确理解业务词汇。
(1)Jieba 自定义词典
jieba.load_userdict("user_dict.txt") # 加载自定义词典文件
text = "我喜欢Transformer模型"
print(jieba.lcut(text))
# 运行结果(未添加前):['我', '喜欢', 'Transformer', '模型']
# 运行结果(添加后):['我', '喜欢', 'Transformer模型']
📌 user_dict.txt 格式(每行一个词,词频可选):
Transformer模型 100 nz
(2)THULAC 自定义词典
import thulac
thu = thulac.thulac(user_dict="thu_dict.txt", seg_only=True)
text = "我喜欢Transformer模型"
print(thu.cut(text, text=True))
# 运行结果(添加后): 我 喜欢 Transformer模型
(3)HanLP 自定义词典
from pyhanlp import *
CustomDictionary.add("Transformer模型") # 添加新词
text = "我喜欢Transformer模型"
print(HanLP.segment(text))
# 运行结果(添加后): ['我', '喜欢', 'Transformer模型']
三、词袋模型(Bag of Words, BoW)
1. 什么是词袋模型?
词袋模型(Bag of Words, BoW) 是 NLP 中最基础的文本表示方法:
- 忽略词序,只关注单词出现的频率。
- 无法区分重要词与普通词,如 “的” 和 “学习” 被同等对待。
- 适用于文本分类、主题建模,但不适用于生成任务。
2. 词袋模型代码示例
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
"我喜欢学习自然语言处理",
"自然语言处理很有趣"
]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print("词汇表:", vectorizer.get_feature_names_out())
print("向量:\n", X.toarray())
# 运行结果:
# 词汇表: ['喜欢' '学习' '自然语言处理' '有趣']
# 向量:
# [[1 1 1 0]
# [0 0 1 1]]
3. 改进方案:TF-IDF(Term Frequency - Inverse Document Frequency)
✅ TF-IDF 计算公式:
TF-IDF = TF × log ( 总文档数 包含该词的文档数 ) \text{TF-IDF} = \text{TF} \times \log(\frac{\text{总文档数}}{\text{包含该词的文档数}}) TF-IDF=TF×log(包含该词的文档数总文档数)
- TF(词频):某个词在当前文档中的出现频率。
- IDF(逆文档频率):衡量该词在整个语料库中的重要性,常见词(如“的”)会有较低的 IDF 值。
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vectorizer = TfidfVectorizer()
X_tfidf = tfidf_vectorizer.fit_transform(corpus)
print("TF-IDF 词汇表:", tfidf_vectorizer.get_feature_names_out())
print("TF-IDF 向量:\n", X_tfidf.toarray())
# 运行结果:
# 词汇表: ['喜欢' '学习' '自然语言处理' '有趣']
# 向量:
# [[0.707 0.707 0.500 0.000]
# [0.000 0.000 0.500 0.866]]
更多推荐



所有评论(0)