4、数据标注与预处理:云端标注工具、数据清洗、特征工程、数据划分
数据准备这件事,说实话,比调模型要花时间得多。我见过太多团队把精力全砸在模型结构上,结果数据一塌糊涂,跑出来的指标根本没法看。今天咱们就聊聊云端ML工作流里,数据标注和预处理到底该怎么搞。
4.1 云端标注工具:SageMaker Ground Truth
标注数据,听起来就是个苦力活。但如果你还在用Excel手动打标签,那效率确实太低了。我个人习惯用SageMaker Ground Truth,它最大的好处是——你不用自己管标注团队。
你只需要上传原始数据,定义好标注任务(比如图像分类、目标检测、文本分类),Ground Truth会自动把任务分发给标注工人。它内置了质量检查机制,说白了就是同一份数据会分给多个人标,然后做一致性校验。
- 创建标注项目 → 选择任务类型
- 上传数据(S3路径) → 配置工人团队(公有/私有)
- 启动标注 → 自动质检 → 导出标注结果
我在项目中遇到过一个问题:标注结果里有些标签明显是错的。后来发现是标注任务说明写得太模糊。嗯,这里要注意——标注指南一定要写清楚,最好附上正反例。否则工人凭感觉标,你后面清洗数据会哭的。
4.2 数据清洗:别让脏数据毁了你的模型
数据清洗,说白了就是「去杂质」。你想想看,原始数据里什么妖魔鬼怪都有:空值、重复值、异常值、格式不统一……这些不处理,模型学到的全是噪音。
我一般按这个顺序来清洗:
- 去重:同一份数据出现多次,模型会过拟合到这些样本上。
- 处理缺失值:数值型用均值/中位数填充,类别型用众数填充。如果缺失太多(超过50%),我建议直接删掉这个特征。
- 异常值检测:用3σ原则或者IQR(四分位距)方法。比如用户年龄出现200岁,这明显是录入错误。
- 格式统一:日期格式、文本编码、数值单位,全部标准化。
在云端做数据清洗,我推荐用AWS Glue或者SageMaker Processing。它们可以自动处理大规模数据,而且支持Python脚本。你只需要写个清洗函数,然后提交一个Processing Job就行。
# 一个简单的清洗示例(SageMaker Processing)
import pandas as pd
def clean_data(df):
# 去重
df = df.drop_duplicates()
# 填充缺失值
df['age'].fillna(df['age'].median(), inplace=True)
# 异常值处理(年龄超过120视为异常)
df = df[df['age'] <= 120]
return df
# 在SageMaker Processing中调用
from sagemaker.processing import ProcessingInput, ProcessingOutput
4.3 特征工程:把原始数据变成模型能理解的语言
特征工程,说白了就是「翻译」。原始数据是人类的语言,模型只懂数字。你得想办法把文本、图片、时间、类别这些东西,变成数值向量。
我个人习惯把特征工程分成三类:
| 特征类型 | 常见方法 | 注意事项 |
|---|---|---|
| 数值型 | 标准化(Z-score)、归一化(Min-Max) | 树模型不需要归一化,但神经网络需要 |
| 类别型 | 独热编码、标签编码、目标编码 | 类别太多时独热编码会爆炸,考虑用嵌入 |
| 文本型 | TF-IDF、词嵌入(Word2Vec/BERT) | 短文本用TF-IDF,长文本用预训练模型 |
| 时间型 | 提取年/月/日/星期、周期性编码 | 时间戳本身没意义,要提取周期特征 |
为什么会这样?因为模型本质上是在做数学运算。你给它一个「红色」的字符串,它算不了。但如果你把「红色」编码成 [1,0,0],把「蓝色」编码成 [0,1,0],模型就能理解它们之间的「距离」了。
4.4 数据划分:训练/验证/测试
数据划分这件事,看起来简单,但坑特别多。最常见的错误就是——先划分,再做特征工程。顺序搞反了,会导致数据泄露。
正确的顺序是:
- 先把原始数据分成三份:训练集(60-70%)、验证集(15-20%)、测试集(15-20%)
- 只在训练集上做特征工程(比如计算均值、标准差)
- 用训练集上算好的参数,去转换验证集和测试集
为什么要这样?你想想看,如果你先对整个数据集做标准化,那验证集的数据「偷看」了训练集的分布信息。模型在测试时表现好,其实是因为它已经提前知道了全局信息。这属于典型的「数据泄露」。
在云端,你可以用SageMaker的train_test_split功能,或者自己写脚本。我个人习惯用scikit-learn的train_test_split和StratifiedKFold来做分层抽样,确保每个类别在训练集和测试集中的比例一致。
from sklearn.model_selection import train_test_split
# 先划分,再特征工程
X_train, X_temp, y_train, y_temp = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
X_val, X_test, y_val, y_test = train_test_split(
X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp
)
- 先划分,后做特征工程
- 时间序列数据必须按时间顺序划分
- 分类问题用分层抽样,保持类别分布一致
- 测试集只用一次,不要用它调参
好了,数据标注和预处理这部分就聊到这儿。记住一句话:数据质量决定了模型效果的上限,模型算法只是在逼近这个上限。把数据搞扎实了,后面的事情会顺利很多。
公众号:蓝海资料掘金营,微信deep3321