SMD/SMAP/MSL/SWaT/WADI 5大异常检测数据集:从原始文件到统一CSV格式的3步标准化流程 五大工业级时间序列异常检测数据集标准化处理实战指南1. 工业场景下的时间序列异常检测数据集概述在智能制造和物联网时代设备传感器产生的多变量时间序列数据呈指数级增长。SMD、SMAP、MSL、SWaT和WADI这五大数据集已成为学术界和工业界评估异常检测算法的黄金标准。这些数据集具有三个显著特征多维度监控单个实体包含38-127个不等的监测指标如SMD数据集每台服务器监控CPU负载、内存使用等38个维度精确标注测试集包含专家标记的异常片段SWaT数据集甚至标注了41次攻击的具体时间点真实场景全部来自服务器集群、航天器、水处理厂等真实工业环境WADI数据集采集自真实供水管网16天的运行数据# 典型数据集维度对比 datasets { SMD: {entities:28, dims:38, time_points:1411200}, SMAP: {entities:55, dims:25, time_points:None}, MSL: {entities:27, dims:55, time_points:None}, SWaT: {entities:1, dims:51, time_points:946944}, WADI: {entities:1, dims:127, time_points:1209600} }2. 数据集标准化处理的核心挑战原始数据存在三大典型问题需要解决2.1 格式异构性SMD采用TXT文件存储每行代表一个时间点的所有维度数据SMAP/MSL使用NPY二进制格式配合CSV标注文件SWaT和WADI提供原始CSV但时间格式不统一2.2 时间表示差异匿名时间戳SMAP/MSL用连续整数代替真实时间多时区问题WADI数据集包含新加坡时区的UTC8时间格式错误WADI新版存在时间列解析异常2.3 标签不一致SWaT用Normal/Attack字符串标记WADI采用1/-1表示正常/攻击SMD提供额外的异常维度解释标签重要提示处理WADI数据时要特别注意其第二版本删除了训练集中的不稳定时段但测试集保持完整需要特殊处理时间对齐问题3. 三步标准化处理流程详解3.1 数据下载与结构重组SMD数据集处理方案# 下载并解压SMD数据集 git clone https://github.com/NetManAIOps/OmniAnomaly.git cd OmniAnomaly/ServerMachineDataset tree -L 2 # 输出结构应包含 # ├── train # ├── test # └── test_labelSMAP/MSL特殊处理# 使用wget下载NASA数据集 import subprocess subprocess.run([wget https://s3-us-west-2.amazonaws.com/telemanom/data.zip], shellTrue) subprocess.run([unzip data.zip rm data.zip], shellTrue)SWaT/WADI申请流程访问iTrust实验室官网填写数据使用申请表获取批准后下载压缩包文件特别注意WADI有两个版本需要区分3.2 时间对齐与特征提取关键操作步骤统一时间列为datetime格式处理缺失值向前填充/线性插值特征重命名规范化为col_0到col_N标签列统一转换为0/1二进制格式# WADI时间修正示例 def recover_wadi_time(df): 修复WADI数据集的时间格式问题 # 合并Date和Time列 df[datetime] pd.to_datetime(df[Date] df[Time]) # 处理新版数据的时间跳变 if Row in df.columns: ref_time pd.read_csv(WADI.A1_9 Oct 2017/WADI_14days.csv) ref_time[datetime] pd.to_datetime(ref_time[Date] ref_time[Time]) df df.merge(ref_time[[Row,datetime]], onRow) return df.drop([Date,Time], axis1)3.3 标准化输出结构最终统一的目录结构规范processed_datasets/ ├── SMD │ ├── machine-1-1 │ │ ├── train.csv │ │ └── test.csv │ └── machine-1-2 │ ├── train.csv │ └── test.csv ├── SMAP │ ├── train.csv │ └── test.csv └── WADI ├── train.csv └── test.csvCSV文件标准字段timestamp: 统一的时间戳或连续IDcol_[0-N]: 所有特征列label: 仅测试集包含0表示正常1表示异常4. 各数据集处理代码精要4.1 SMD处理核心逻辑def process_smd(input_dir, output_dir): for machine_file in os.listdir(f{input_dir}/train): if not machine_file.endswith(.txt): continue # 处理训练集 train_data pd.read_csv(f{input_dir}/train/{machine_file}, delimiter,, headerNone) train_data.columns [fcol_{i} for i in range(train_data.shape[1])] train_data[timestamp] train_data.index # 处理测试集及标签 test_data pd.read_csv(f{input_dir}/test/{machine_file}, delimiter,, headerNone) test_labels pd.read_csv(f{input_dir}/test_label/{machine_file}, delimiter,, headerNone) # 合并测试数据和标签 test_data[label] test_labels.values test_data[timestamp] test_data.index # 保存结果 machine_name machine_file.replace(.txt,) os.makedirs(f{output_dir}/{machine_name}, exist_okTrue) train_data.to_csv(f{output_dir}/{machine_name}/train.csv, indexFalse) test_data.to_csv(f{output_dir}/{machine_name}/test.csv, indexFalse)4.2 SMAP/MSL特殊处理def process_nasa_data(dataset_name): # 加载异常标注CSV anomalies pd.read_csv(data/labeled_anomalies.csv) anomalies anomalies[anomalies[spacecraft] dataset_name] # 构建测试集标签 test_labels [] for _, row in anomalies.iterrows(): chan_data np.load(fdata/test/{row[chan_id]}.npy) labels np.zeros(len(chan_data)) for start, end in ast.literal_eval(row[anomaly_sequence]): labels[start:end1] 1 test_labels.extend(labels) # 合并所有通道数据 train_data np.concatenate([ np.load(fdata/train/{row[chan_id]}.npy) for _, row in anomalies.iterrows() ]) # 保存标准化CSV pd.DataFrame(train_data).to_csv(f{dataset_name}_train.csv, index_labeltimestamp) pd.DataFrame(test_labels).to_csv(f{dataset_name}_test.csv, index_labeltimestamp)5. 实战问题排查指南常见问题1WADI时间对齐失败症状测试集出现NaN时间戳解决方案使用Row列与旧版数据做精确匹配# WADI时间修复代码 train_new pd.read_csv(WADI.A2_19 Nov 2019/WADI_14days_new.csv) train_old pd.read_csv(WADI.A1_9 Oct 2017/WADI_14days.csv, skiprows4) train_old[datetime] pd.to_datetime(train_old[Date] train_old[Time]) train_new train_new.merge(train_old[[Row,datetime]], onRow)常见问题2SMAP数据维度不匹配症状label长度与测试数据不一致检查点确认labeled_anomalies.csv中num_values与npy文件行数一致性能优化技巧对于大型数据集如SMD使用dask替代pandas处理WADI时限制内存使用pd.read_csv(..., chunksize100000)使用并行处理加速SMD的28台机器处理6. 标准化数据集的应用验证完成处理后可通过以下代码快速验证数据质量def validate_dataset(dataset_path): 验证标准化数据集的基本属性 train pd.read_csv(f{dataset_path}/train.csv) test pd.read_csv(f{dataset_path}/test.csv) print(f训练集形状: {train.shape}) print(f测试集形状: {test.shape}) print(特征维度示例:, [c for c in train.columns if c.startswith(col_)][:5]) if label in test.columns: anomaly_ratio test[label].mean() print(f异常比例: {anomaly_ratio:.2%}) # 检查时间连续性 if timestamp in train.columns: time_diff pd.to_datetime(train[timestamp]).diff().value_counts() print(时间间隔分布:\n, time_diff.head())典型输出示例训练集形状: (708405, 39) 测试集形状: (708405, 40) 特征维度示例: [col_0, col_1, col_2, col_3, col_4] 异常比例: 3.17% 时间间隔分布: 00:01:00 708404 Name: timestamp, dtype: int64