3. MRM 数据预处理:原始数据导入、缺失值处理、数据归一化与标准化、批次效应校正
在 MRM(多反应监测)框架下,原始质谱数据在进入特征筛选流程前,必须经过严格的预处理。数据预处理的质量直接决定后续特征筛选的可靠性与可重复性。本章节将系统讲解从原始数据导入到批次效应校正的完整流程,确保数据符合统计建模与机器学习的基本假设。
3.1 原始数据导入与格式规范
MRM 实验通常输出峰面积、保留时间、信噪比等定量信息。常见的数据来源包括 Sciex OS、Agilent MassHunter、Waters MassLynx 等。导入阶段需统一数据格式,建立样本-特征矩阵。
| 数据来源 | 常见导出格式 | 导入注意事项 |
|---|---|---|
| Sciex OS | .csv, .txt | 检查峰面积列名是否包含特殊字符 |
| Agilent MassHunter | .csv, .xlsx | 确认是否包含内标校正后的比值 |
| Waters MassLynx | .csv, .txt | 注意多批次导出时列顺序是否一致 |
| Skyline | .csv | 推荐使用"Transition Results"导出模板 |
最佳实践:建议在导入阶段建立统一的列名映射表,将原始列名(如
Area、Peak Area、Intensity)统一为 FeatureID_Area 格式,便于后续批量处理。
# Python 示例:统一导入 MRM 数据
import pandas as pd
def import_mrm_data(filepath, sample_id_col='SampleID', feature_col='FeatureName', value_col='Area'):
"""
导入 MRM 原始数据并转换为宽表格式
"""
df_raw = pd.read_csv(filepath)
df_wide = df_raw.pivot_table(
index=sample_id_col,
columns=feature_col,
values=value_col,
aggfunc='mean'
)
return df_wide
3.2 缺失值处理策略
MRM 数据中的缺失值通常来源于:低于检测限(LOD)、峰积分失败、离子抑制或仪器漂移。不同缺失机制需要采用不同的处理策略。
关键区分:必须区分"真正缺失"与"零值"。在 MRM 中,零值通常表示未检测到信号,不应直接视为缺失值。建议将零值单独标记后,根据生物学背景决定是否纳入分析。
缺失值处理流程
- 缺失率评估:计算每个特征在所有样本中的缺失比例。缺失率 > 50% 的特征建议直接剔除。
- 缺失机制判断:通过比较缺失组与完整组的其他特征分布,初步判断是否为随机缺失(MAR)或非随机缺失(MNAR)。
- 插补方法选择:
- 最小值/1/2 最小值法:适用于低于检测限的缺失,用特征最小检测值的 1/2 填充。
- KNN 插补:利用相似样本的特征信息进行填充,适用于随机缺失。
- 随机森林插补:对非线性关系鲁棒,适合复杂代谢组学数据。
- 多重插补(MICE):保留不确定性,适用于后续需要统计推断的场景。
3.3 数据归一化与标准化
归一化与标准化是消除样本间系统性差异、使特征具有可比性的关键步骤。在 MRM 框架下,两者具有不同的应用场景。
| 方法 | 计算公式 | 适用场景 | 对 MRM 数据的意义 |
|---|---|---|---|
| Z-score 标准化 | \( z = \frac{x - \mu}{\sigma} \) | 特征服从近似正态分布 | 消除不同代谢物浓度量纲差异 |
| Min-Max 归一化 | \( x' = \frac{x - x_{min}}{x_{max} - x_{min}} \) | 需要将数据映射到 [0,1] 区间 | 适用于神经网络等对输入范围敏感的模型 |
| 总离子流归一化 | \( x' = \frac{x}{TIC} \) | 质谱数据批次内校正 | 消除样本间总信号强度差异 |
| 内标归一化 | \( x' = \frac{x}{IS_{area}} \) | 已知稳定同位素内标 | 校正仪器响应波动和样本制备差异 |
| 分位数归一化 | 排序后取均值对齐 | 多批次数据分布不一致 | 使所有样本的统计分布一致 |
MRM 推荐策略:优先使用内标归一化(如果实验设计中包含内标),其次考虑总离子流归一化。Z-score 标准化通常放在特征筛选之前,作为最终输入模型的预处理步骤。
# Python 示例:多种归一化方法实现
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np
def normalize_mrm_data(df, method='zscore', tic_col=None, is_col=None):
"""
MRM 数据归一化统一接口
"""
df_norm = df.copy()
if method == 'zscore':
scaler = StandardScaler()
df_norm[:] = scaler.fit_transform(df_norm)
elif method == 'minmax':
scaler = MinMaxScaler()
df_norm[:] = scaler.fit_transform(df_norm)
elif method == 'tic':
# 总离子流归一化
tic = df_norm.sum(axis=1)
df_norm = df_norm.div(tic, axis=0)
elif method == 'is':
# 内标归一化:假设 is_col 为内标列名
is_values = df_norm[is_col]
df_norm = df_norm.div(is_values, axis=0)
return df_norm
3.4 批次效应校正
批次效应是 MRM 数据分析中最常见的系统性误差来源,可能由试剂批次、仪器状态、操作人员、环境温度等因素引起。若不校正,批次效应会与生物学差异混淆,导致假阳性特征筛选结果。
批次效应检测方法
- 主成分分析(PCA):绘制前两个主成分的散点图,按批次着色。若样本按批次聚类,则存在显著批次效应。
- 层次聚类热图:观察样本聚类是否与批次标签一致。
- 批次间特征分布比较:对每个特征进行批次间的 t 检验或 Wilcoxon 检验,统计显著差异的比例。
批次效应校正实施步骤
- 构建批次标签向量:为每个样本分配批次编号(如 Batch_1, Batch_2, ...)。
- 选择校正方法:
- 2-3 个批次,样本量较小:推荐 ComBat(Python:
combat.py,R:sva包)。 - 多个批次,实验设计平衡:推荐 Limma(R:
limma包)。 - 无批次标签但有负对照特征:推荐 RUV(R:
ruv包)。
- 2-3 个批次,样本量较小:推荐 ComBat(Python:
- 校正效果验证:
- 重新绘制 PCA 图,检查批次聚类是否消失。
- 计算批次间特征分布的 KS 统计量,校正后应显著降低。
- 保留生物学对照样本(如 QC 样本),验证校正后 QC 样本的变异系数(CV)是否降低。
常见陷阱:批次效应校正不应与生物学分组变量混淆。校正模型必须包含生物学分组作为协变量,否则可能消除真实的生物学差异。建议在校正前将数据按生物学分组分层,或在校正模型中显式包含分组变量。
# Python 示例:使用 ComBat 进行批次效应校正
# 需要安装 combat 库: pip install combat
from combat.pycombat import pycombat
def batch_correction_combat(df, batch_labels):
"""
使用 ComBat 方法校正批次效应
df: 样本×特征 数据框
batch_labels: 批次标签列表(与 df 行顺序一致)
"""
# pycombat 要求数据为 特征×样本 格式
df_t = df.T
df_corrected_t = pycombat(df_t, batch_labels)
df_corrected = df_corrected_t.T
return df_corrected
3.5 预处理流程总结
完整的 MRM 数据预处理流程应按照以下顺序执行,每一步的输出作为下一步的输入:
| 步骤 | 操作 | 输出 | 质量检查指标 |
|---|---|---|---|
| 1 | 原始数据导入与格式统一 | 样本×特征宽表 | 行数=样本数,列数=特征数 |
| 2 | 缺失值评估与处理 | 完整数据矩阵 | 缺失率 < 5% |
| 3 | 数据归一化/标准化 | 归一化后矩阵 | 特征量纲一致 |
| 4 | 批次效应检测 | 批次效应评估报告 | PCA 无批次聚类 |
| 5 | 批次效应校正 | 校正后数据矩阵 | QC 样本 CV < 20% |
最终建议:将预处理后的数据保存为两个版本——原始预处理版本(仅缺失值处理+归一化)和批次校正版本。在后续特征筛选中,可以对比两个版本的结果,评估批次效应对特征选择稳定性的影响。这是 MRM 框架下质量控制的重要环节。