第二章:数据采集与清洗
大家好,我是老张。今天咱们聊聊数据采集与清洗。说实话,这是整个模型训练里最枯燥、但也是最关键的环节。我见过太多团队,模型算法调得天花乱坠,最后栽在数据质量上。嗯,咱们一步步来。
核心观点:数据质量决定了模型效果的上限。算法只是逼近这个上限的手段。
2.1 日志数据采集
日志,说白了就是系统运行时的「黑匣子」。我习惯把日志分成三类:
- 系统日志:内核、服务进程的 stdout/stderr
- 应用日志:业务代码里的 print、log4j 等输出
- 访问日志:Nginx、API Gateway 的请求记录
采集方式上,我个人推荐用 Filebeat + Logstash 这套组合。为什么?Filebeat 轻量,几乎不占资源;Logstash 做过滤和转换很灵活。我在一个日活千万的项目里用过,单机采集 5000 条/秒,CPU 占用不到 5%。
小技巧:采集时一定要带上时间戳和主机名。否则后面回溯问题,你会想骂人。我曾经因为没打时间戳,排查一个故障花了三天。
举个采集配置的例子:
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
fields:
log_type: nginx_access
env: production
output.logstash:
hosts: ["192.168.1.100:5044"]
2.2 指标数据采集
指标数据跟日志不一样。日志是「发生了什么事」,指标是「系统状态怎么样」。比如 CPU 使用率、内存占用、QPS、延迟分位数。这些数据是数值型的,适合做趋势分析和异常检测。
我常用的采集方案是 Prometheus + node_exporter。Prometheus 的 pull 模式比 push 模式更可靠——你想想看,如果采集端挂了,push 模式的数据就丢了;pull 模式至少还能重试。
| 指标类型 | 采集工具 | 采集频率 | 存储方式 |
|---|---|---|---|
| 系统指标 | node_exporter | 15s | Prometheus TSDB |
| 应用指标 | micrometer / statsd | 30s | InfluxDB / VictoriaMetrics |
| 业务指标 | 自定义 exporter | 60s | ClickHouse |
注意:采集频率不是越高越好。15s 一次足够捕捉大部分异常。我曾经把频率设到 1s,结果存储成本翻了 10 倍,收益微乎其微。
2.3 数据清洗与标准化
数据采集回来,你会发现什么妖魔鬼怪都有:空值、重复数据、格式不统一、时间戳乱跳……清洗就是把这些「脏数据」处理掉。
我总结了一套清洗流程,你参考下:
- 去重:基于时间戳+唯一ID,删除完全重复的记录
- 空值处理:数值型用均值/中位数填充,文本型用「unknown」标记
- 异常值过滤:比如 CPU 使用率超过 100% 的,直接丢弃
- 格式统一:时间戳转成 ISO 8601,IP 地址转成整数
举个例子,时间戳标准化:
# Python 示例
import pandas as pd
def clean_timestamp(df):
# 统一转为 UTC 时间戳
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)
# 过滤掉未来时间(时钟漂移)
df = df[df['timestamp'] <= pd.Timestamp.now(tz='UTC')]
return df
避坑指南:我曾经遇到过一个坑——日志里时间戳是本地时间,但没标注时区。清洗时直接当 UTC 处理,结果模型训练出来的预测偏差了 8 小时。后来我强制要求所有采集端统一用 UTC。
2.4 数据标注基础
标注,就是给数据打标签。比如日志是「正常」还是「异常」,指标是「故障」还是「平稳」。标注质量直接影响模型效果。
我建议标注流程分三步:
- 自动标注:用规则引擎先打一批标签。比如 CPU > 90% 持续 5 分钟,自动标为「高负载」
- 人工校验:随机抽 10% 的数据,让运维同学确认标签是否正确
- 迭代修正:根据模型预测结果,定期修正标注错误的数据
标注格式上,我推荐用 JSON Lines,每行一个样本:
{"timestamp": "2024-01-15T10:30:00Z", "cpu": 85.2, "mem": 72.1, "label": "normal"}
{"timestamp": "2024-01-15T10:31:00Z", "cpu": 97.8, "mem": 94.3, "label": "high_load"}
{"timestamp": "2024-01-15T10:32:00Z", "cpu": 99.9, "mem": 98.5, "label": "anomaly"}
个人经验:标注时别只标「正常」和「异常」两类。我习惯加一个「不确定」标签。这样模型训练时,不确定的数据可以单独处理,避免污染正常样本。
知识体系总览
下面这张图,是我自己梳理的数据采集与清洗全流程。你保存下来,做项目时对照着看:
嗯,以上就是数据采集与清洗的核心内容。说白了,就是「采得对、洗得净、标得准」。这三点做好了,模型训练就成功了一半。我在实际项目中,光清洗这块就占了整个数据 pipeline 60% 的工作量。别嫌麻烦,后面你会感谢自己的。