除箱线图法外,MATLAB中还有多种实用的异常值检测方法,不同方法适配不同数据分布和业务场景。本文整理6种主流方法,涵盖原理、代码实现、适用场景,所有代码可直接套用。
一、标准差法(3σ原则)—— 适配正态分布数据
核心原理
正态分布中,约99.7%的数据落在「均值±3×标准差」范围内,超出该范围的数值判定为异常值;若需更宽松标准,可改用2σ(覆盖95.4%数据)。
适用场景
数据符合正态分布(如传感器稳态数据、实验重复测量数据),单变量检测优先用。
实操代码
%% 标准差法异常值检测
% 1. 数据导入与预处理(以CSV为例)
data = readtable('待检测数据.csv');
detect_col = data.('温度值'); % 选择检测列
detect_col_filled = fillmissing(detect_col, 'constant', mean(detect_col, 'omitNaN')); % 均值填充缺失值
detect_arr = table2array(detect_col_filled);
% 2. 验证数据正态性(关键前提)
[h,p] = swtest(detect_arr); % Shapiro-Wilk检验,P>0.05则符合正态分布
if p > 0.05
disp('数据符合正态分布,可使用标准差法');
% 3. 计算均值和标准差
mu = mean(detect_arr); % 均值
sigma = std(detect_arr); % 标准差
% 4. 设定3σ边界
lower_3sigma = mu - 3*sigma;
upper_3sigma = mu + 3*sigma;
% 5. 定位异常值
outlier_logic = (detect_arr < lower_3sigma) | (detect_arr > upper_3sigma);
outlier_idx = find(outlier_logic);
outlier_values = detect_arr(outlier_idx);
% 6. 可视化(直方图+3σ边界)
figure('Color','white');
histogram(detect_arr, 'Normalization','pdf');
hold on;
xline(mu, 'g--', 'LineWidth',1.5, 'DisplayName','均值');
xline(lower_3sigma, 'r-', 'LineWidth',1.5, 'DisplayName','3σ下边界');
xline(upper_3sigma, 'r-', 'LineWidth',1.5, 'DisplayName','3σ上边界');
legend;
title('标准差法异常值检测');
% 7. 输出结果
disp(['3σ法检测到异常值数量:', num2str(length(outlier_idx))]);
else
disp('数据不符合正态分布,建议改用箱线图法');
end
二、百分位数法(缩尾法)—— 适配偏态分布数据
核心原理
通过设定分位数边界(如1%和99%分位数),超出边界的数值判定为异常值;无需假设数据分布,是箱线图法的简化版。
适用场景
偏态分布数据(如收入、销量、用户消费金额),避免极端值干扰统计结果。
实操代码
%% 百分位数法异常值检测
% 1. 数据预处理
data = readtable('用户消费数据.csv');
detect_col = data.('消费金额');
detect_arr = table2array(fillmissing(detect_col, 'constant', median(detect_col, 'omitNaN')));
% 2. 设定分位数边界(常用1%/99%,可调整为5%/95%)
p01 = quantile(detect_arr, 0.01); % 1%分位数(下边界)
p99 = quantile(detect_arr, 0.99); % 99%分位数(上边界)
% 3. 定位异常值
outlier_logic = (detect_arr < p01) | (detect_arr > p99);
outlier_idx = find(outlier_logic);
% 4. 输出结果
disp(['1%/99%分位数边界:', num2str(p01), ' ~ ', num2str(p99)]);
disp(['检测到异常值数量:', num2str(length(outlier_idx))]);
% 5. 异常值处理(缩尾替换)
detect_arr_clean = detect_arr;
detect_arr_clean(detect_arr_clean < p01) = p01;
detect_arr_clean(detect_arr_clean > p99) = p99;
三、DBSCAN聚类法—— 适配多变量/空间数据
核心原理
基于密度聚类,将数据划分为“核心点”“边界点”“噪声点”,噪声点即为异常值;无需预设异常值比例,能识别任意形状的异常簇。
适用场景
多变量异常检测(如温度+压力+转速组合异常)、空间数据(如GPS轨迹异常点)。
实操代码
%% DBSCAN聚类法异常值检测(多变量)
% 1. 数据预处理(选择2列及以上数值列)
data = readtable('工业传感器数据.csv');
num_data = data(:, {'温度', '压力', '转速'}); % 多变量选择
num_data_filled = fillmissing(num_data, 'constant', median(num_data, 'omitNaN'));
data_mat = table2array(num_data_filled);
% 2. DBSCAN聚类(关键参数:Eps=邻域半径,MinPts=邻域最小点数)
% 自动计算最优Eps(可选,也可手动设定)
k = 5; % 近邻数
[idx, dist] = knnsearch(data_mat, data_mat, 'K', k);
k_dist = sort(dist(:,k));
Eps = k_dist(end*0.9); % 取90%分位数作为Eps
MinPts = 5; % 邻域最小点数,建议≥维度数+1
% 3. 执行DBSCAN
labels = dbscan(data_mat, Eps, MinPts); % labels=-1表示异常值(噪声点)
% 4. 定位异常值
outlier_idx = find(labels == -1);
disp(['DBSCAN检测到异常值数量:', num2str(length(outlier_idx))]);
% 5. 可视化(前两列数据)
figure('Color','white');
scatter(data_mat(:,1), data_mat(:,2), 10, labels, 'filled');
hold on;
scatter(data_mat(outlier_idx,1), data_mat(outlier_idx,2), 50, 'r', 'filled', 'Marker','x');
xlabel('温度');
ylabel('压力');
title('DBSCAN聚类异常值检测(红色X为异常值)');
colorbar;
四、Z-score法(标准化法)—— 适配多维度数据对比
核心原理
将数据标准化为Z值(Z=(x-均值)/标准差),通常|Z|>3判定为异常值;消除量纲影响,适合多维度数据统一检测。
适用场景
多指标异常对比(如不同单位的传感器数据、多维度评分数据)。
实操代码
%% Z-score法异常值检测
% 1. 数据预处理
data = readtable('多维度评分数据.csv');
detect_cols = data(:, {'指标1', '指标2', '指标3'});
detect_cols_filled = fillmissing(detect_cols, 'constant', mean(detect_cols, 'omitNaN'));
data_mat = table2array(detect_cols_filled);
% 2. 计算Z-score(逐列标准化)
z_score = zscore(data_mat); % MATLAB内置函数,直接计算Z值
% 3. 判定异常值(|Z|>3)
outlier_logic = abs(z_score) > 3;
% 按行判定:只要有一列是异常值,该行即为异常
outlier_row_logic = any(outlier_logic, 2);
outlier_idx = find(outlier_row_logic);
% 4. 输出结果
disp(['Z-score法检测到异常行数量:', num2str(length(outlier_idx))]);
disp('异常行索引:');
disp(outlier_idx);
五、Grubbs检验法(格拉布斯检验)—— 适配小样本数据
核心原理
专门针对小样本(n=3~250)的异常值检测,假设数据正态分布,逐步检验并剔除异常值(单次检测一个异常值)。
适用场景
实验室小样本实验数据(如5~20个重复测量值),需精准识别单个异常值。
实操代码
%% Grubbs检验法异常值检测(小样本)
% 1. 数据预处理(小样本示例)
data = [25.1, 24.9, 25.0, 28.5, 25.2]; % 小样本数据(5个值)
alpha = 0.05; % 显著性水平
% 2. Grubbs检验核心函数(自定义)
function [outlier_idx, clean_data] = grubbs_test(data, alpha)
n = length(data);
outlier_idx = [];
clean_data = data;
while true
mu = mean(clean_data);
sigma = std(clean_data);
% 计算Grubbs统计量
G = max(abs(clean_data - mu)) / sigma;
% 临界值(n:样本量,alpha:显著性水平)
t_val = tinv(1 - alpha/(2*n), n-2);
G_critical = (n-1) * sqrt(t_val^2 / (n-2 + t_val^2)) / sqrt(n);
if G > G_critical
% 定位异常值
idx = find(abs(clean_data - mu) == max(abs(clean_data - mu)));
outlier_idx = [outlier_idx, find(data == clean_data(idx))];
% 剔除异常值
clean_data(idx) = [];
n = n - 1;
else
break;
end
end
end
% 3. 执行检验
[outlier_idx, clean_data] = grubbs_test(data, alpha);
% 4. 输出结果
disp(['Grubbs检验检测到异常值索引:', num2str(outlier_idx)]);
disp(['异常值:', num2str(data(outlier_idx))]);
disp(['清洗后数据:', num2str(clean_data)]);
六、IQR改进法(极端异常值检测)—— 适配需严格筛选的场景
核心原理
箱线图法的升级版,用3×IQR替代1.5×IQR作为边界,仅识别极端异常值(避免误判轻微偏离值)。
适用场景
需严格控制异常值数量(如金融风控、医疗数据),仅关注极端偏离的异常值。
实操代码
%% IQR改进法(极端异常值检测)
% 1. 数据预处理
data = readtable('金融交易数据.csv');
detect_col = data.('交易金额');
detect_arr = table2array(fillmissing(detect_col, 'constant', median(detect_col, 'omitNaN')));
% 2. 计算统计量(3×IQR边界)
q = quantile(detect_arr, [0.25, 0.75]);
Q1 = q(1); Q3 = q(2);
IQR_val = Q3 - Q1;
% 极端异常值边界(3×IQR)
lower_bound = Q1 - 3*IQR_val;
upper_bound = Q3 + 3*IQR_val;
% 3. 定位极端异常值
outlier_logic = (detect_arr < lower_bound) | (detect_arr > upper_bound);
outlier_idx = find(outlier_logic);
% 4. 输出结果
disp(['极端异常值边界:', num2str(lower_bound), ' ~ ', num2str(upper_bound)]);
disp(['检测到极端异常值数量:', num2str(length(outlier_idx))]);
七、各方法对比与选型建议
| 方法 | 核心优势 | 适用场景 | 注意事项 |
|---|---|---|---|
| 标准差法 | 计算简单、适配正态分布 | 正态分布单变量数据(如传感器稳态数据) | 需先验证正态性,非正态数据易误判 |
| 百分位数法 | 无需假设分布、适配偏态数据 | 偏态分布数据(如消费、收入) | 分位数需根据业务调整(1%/99%/5%) |
| DBSCAN聚类法 | 多变量检测、识别任意形状异常 | 多维度数据(如温度+压力+转速) | 需调优Eps和MinPts参数 |
| Z-score法 | 消除量纲、适配多维度对比 | 多指标统一检测(不同单位数据) | 依赖正态分布,偏态数据效果差 |
| Grubbs检验法 | 精准识别小样本单个异常值 | 实验室小样本数据(n=3~250) | 仅适用于正态分布小样本 |
| IQR改进法 | 严格筛选极端异常值 | 金融、医疗等高精度场景 | 易遗漏轻微异常值 |
选型核心原则:
- 单变量+正态分布 → 标准差法;
- 单变量+偏态分布 → 百分位数法/IQR改进法;
- 多变量+任意分布 → DBSCAN聚类法;
- 小样本+正态分布 → Grubbs检验法;
- 多维度对比 → Z-score法。