第二章:数据采集与清洗

大家好,我是老张。今天咱们聊聊数据采集与清洗。说实话,这是整个模型训练里最枯燥、但也是最关键的环节。我见过太多团队,模型算法调得天花乱坠,最后栽在数据质量上。嗯,咱们一步步来。

核心观点:数据质量决定了模型效果的上限。算法只是逼近这个上限的手段。

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 数据清洗与标准化

数据采集回来,你会发现什么妖魔鬼怪都有:空值、重复数据、格式不统一、时间戳乱跳……清洗就是把这些「脏数据」处理掉。

我总结了一套清洗流程,你参考下:

  1. 去重:基于时间戳+唯一ID,删除完全重复的记录
  2. 空值处理:数值型用均值/中位数填充,文本型用「unknown」标记
  3. 异常值过滤:比如 CPU 使用率超过 100% 的,直接丢弃
  4. 格式统一:时间戳转成 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"}

个人经验:标注时别只标「正常」和「异常」两类。我习惯加一个「不确定」标签。这样模型训练时,不确定的数据可以单独处理,避免污染正常样本。

知识体系总览

下面这张图,是我自己梳理的数据采集与清洗全流程。你保存下来,做项目时对照着看:

数据采集与清洗知识体系 数据源 数据源 数据源 Filebeat + Logstash Prometheus + node_exporter 自定义 exporter 数据清洗:去重 → 空值处理 → 异常过滤 → 格式统一 数据标注:自动标注 → 人工校验 → 迭代修正

嗯,以上就是数据采集与清洗的核心内容。说白了,就是「采得对、洗得净、标得准」。这三点做好了,模型训练就成功了一半。我在实际项目中,光清洗这块就占了整个数据 pipeline 60% 的工作量。别嫌麻烦,后面你会感谢自己的。


专注资料整理