MATLAB常用异常值检测常用的几种方法

95 阅读8分钟

除箱线图法外,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改进法严格筛选极端异常值金融、医疗等高精度场景易遗漏轻微异常值

选型核心原则

  1. 单变量+正态分布 → 标准差法;
  2. 单变量+偏态分布 → 百分位数法/IQR改进法;
  3. 多变量+任意分布 → DBSCAN聚类法;
  4. 小样本+正态分布 → Grubbs检验法;
  5. 多维度对比 → Z-score法。