数据预处理
预计学习时间:30分钟
数据预处理是将原始数据转化为高质量训练数据的关键步骤,好的预处理能显著提升模型训练效果。
预处理的重要性
数据预处理直接影响模型学习效果和训练效率:
- 提升数据质量:去除噪声,修正错误,标准化格式
- 增强模型泛化:减少过拟合风险,提高模型鲁棒性
- 加速训练收敛:规范化的数据有助于模型更快收敛
文本数据预处理流程
1. 数据清洗
数据清洗是去除原始数据中无效或有害信息的过程:
import re
import pandas as pd
def clean_text(text):
# 移除HTML标签
text = re.sub(r'<.*?>', '', text)
# 移除URL
text = re.sub(r'http\S+', '', text)
# 移除多余空白
text = re.sub(r'\s+', ' ', text).strip()
# 移除特殊字符
text = re.sub(r'[^\w\s]', '', text)
return text
# 应用到数据集
df = pd.read_csv('raw_data.csv')
df['cleaned_text'] = df['text'].apply(clean_text)
常见清洗操作
- 去除HTML/XML标签:防止模型学习网页结构而非内容
- 规范化URL和邮箱:统一替换为特殊标记如
<URL>
和<EMAIL>
- 处理表情符号和特殊Unicode字符:转换或删除
- 去除无意义的重复:如多余空格、重复标点符号
2. 文本规范化
文本规范化使得不同表达形式的相同内容被统一处理:
def normalize_text(text):
# 转换为小写
text = text.lower()
# 标准化数字表示
text = re.sub(r'\d+', '<NUM>', text)
# 替换常见缩写
text = text.replace("can't", "cannot").replace("won't", "will not")
return text
常见规范化操作
- 大小写统一:通常转为小写,除非大小写信息重要
- 数字处理:根据需要保留、替换或归一化
- 缩写展开:展开常见缩写如"don't"到"do not"
- 拼写纠正:修正常见拼写错误
3. 文本过滤
文本过滤用于去除不适合训练的内容:
低质量和有害内容可能对模型产生负面影响,建立有效的过滤机制至关重要。
def filter_text(text, min_length=10, toxic_words=None):
if toxic_words is None:
toxic_words = ["offensive_word1", "offensive_word2"]
# 长度过滤
if len(text.split()) < min_length:
return False
# 有害内容过滤
if any(word in text.lower() for word in toxic_words):
return False
return True
# 应用过滤
df_filtered = df[df['cleaned_text'].apply(filter_text)]
常见过滤标准
- 内容长度:过滤过短或过长的文本
- 信息密度:去除信息量极低的样本
- 质量评分:基于启发式规则的质量评分
- 有害内容:过滤包含有害、冒犯性或敏感内容的样本
4. 去重与排序
去除重复数据并根据质量排序:
# 去重
df_unique = df_filtered.drop_duplicates(subset=['cleaned_text'])
# 基于质量指标排序
def quality_score(text):
# 简单的质量评分函数示例
return len(text.split()) / (text.count('!') + 1)
df_unique['quality'] = df_unique['cleaned_text'].apply(quality_score)
df_sorted = df_unique.sort_values('quality', ascending=False)
高级预处理技术
文本增强
文本增强通过生成变体扩充训练数据:
from nlpaug.augmenter.word import SynonymAug
# 同义词替换增强
aug = SynonymAug()
augmented_text = aug.augment(original_text)
常见文本增强方法:
- 同义词替换:用同义词替换部分词语
- 回译:将文本翻译为另一种语言再翻译回来
- 随机插入/删除/交换:对文本进行轻微修改
语义去重
基于语义相似度的去重比简单的字符匹配更有效:
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
# 加载模型
model = SentenceTransformer('all-MiniLM-L6-v2')
# 计算文本嵌入
embeddings = model.encode(df['cleaned_text'].tolist())
# 找出相似文本对
similarity_matrix = cosine_similarity(embeddings)
数据平衡
确保不同主题、风格和难度水平的数据分布均衡:
from sklearn.cluster import KMeans
# 将文本聚类
kmeans = KMeans(n_clusters=10)
clusters = kmeans.fit_predict(embeddings)
# 从每个簇中均匀采样
balanced_indices = []
for cluster_id in range(10):
cluster_indices = np.where(clusters == cluster_id)[0]
sampled_indices = np.random.choice(
cluster_indices,
size=min(1000, len(cluster_indices)),
replace=False
)
balanced_indices.extend(sampled_indices)
balanced_data = df.iloc[balanced_indices]
预处理工具与框架
工具名称 | 主要功能 | 适用场景 |
---|---|---|
NLTK | 基础文本处理、分词、词干提取 | 语言学研究、通用文本处理 |
SpaCy | 高效文本处理、命名实体识别 | 生产环境、需要高性能的场景 |
TextCleaner | 专注文本清洗、规范化 | 数据准备初期阶段 |
NLPAug | 文本增强、数据扩充 | 数据量不足的场景 |
Pandas | 数据操作、过滤、转换 | 所有数据处理流程 |
预处理最佳实践
- 建立预处理流水线:设计模块化、可复用的处理流程
- 记录预处理步骤:详细记录每一步的操作和参数
- 样本检查:定期随机抽查预处理后的样本,确保质量
- 预处理一致性:确保训练集和测试集使用相同的预处理流程
- 性能优化:对大规模数据集使用并行处理或分布式计算
下一节将探讨数据调度,学习如何有效地组织和分配训练数据。