You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MATLAB的散点图正偏差异常值检测及曲线拟合需求

基于LOESS/LOWESS的自适应密度异常值检测方案(MATLAB实现)

核心思路

用LOESS拟合数据主趋势曲线,结合局部密度加权的置信区间作为异常判定边界,重点识别高于趋势线的正偏差点,负偏差点仅做标记不重点关注。这种方法既保证主数据簇的拟合准确率,又能根据数据密度动态调整检测灵敏度,适配不同分布的散点图。

MATLAB实现步骤

1. 数据预处理与LOESS趋势拟合

先对x轴数据排序(LOESS对有序数据拟合效果更稳定),用MATLAB内置工具生成趋势线及基础置信区间:

% 假设输入为x、y向量,先按x排序
[sortedX, idx] = sort(x);
sortedY = y(idx);

% 带置信区间的LOESS拟合,Span控制平滑度(0.1-1之间调整)
mdl = fitlm(sortedX, sortedY, 'LinearModel', 'loess', 'Span', 0.3);
pred = predict(mdl, sortedX); % 趋势预测值
  • Span参数:数据密集区可设较小值(贴近局部趋势),稀疏区设较大值(避免过度拟合噪声),也可通过交叉验证自动选最优值。

2. 生成随密度变化的自适应边界

默认置信区间是全局统一的,结合局部核密度估计调整边界宽度,实现密度越高、边界越严格的效果:

% 计算每个x点的局部密度
kde = fitdist(sortedX, 'Kernel', 'epanechnikov');
density = pdf(kde, sortedX);

% 归一化密度值,避免极端值干扰边界调整
normDensity = (density - min(density))/(max(density)-min(density))*0.9 + 0.1;

% 提取原始观测置信区间,用密度加权调整
[~,~,lower,upper] = predict(mdl, sortedX, 'Prediction', 'observation');
% 正偏差重点:密度越高,上边界越窄(严格检测)
adjustedUpper = pred + (upper - pred)./normDensity;
% 负偏差非重点:适度放宽下边界
adjustedLower = pred - (pred - lower)*normDensity;

3. 异常点标记与可视化验证

对比原始数据与自适应边界,标记异常点并还原到原始数据索引:

% 标记正/负偏差异常点
positiveOutliers = sortedY > adjustedUpper;
negativeOutliers = sortedY < adjustedLower;

% 还原原始数据的异常点索引
originalPosOutliers = false(size(x));
originalPosOutliers(idx(positiveOutliers)) = true;
originalNegOutliers = false(size(x));
originalNegOutliers(idx(negativeOutliers)) = true;

% 可视化确认
figure;
scatter(x, y, 'b'); hold on;
plot(sortedX, pred, 'r', 'LineWidth', 2);
plot(sortedX, adjustedUpper, 'g--', 'LineWidth', 1.5);
plot(sortedX, adjustedLower, 'm--', 'LineWidth', 1.5);
scatter(x(originalPosOutliers), y(originalPosOutliers), 100, 'k', 'filled', 'MarkerEdgeColor', 'r');
scatter(x(originalNegOutliers), y(originalNegOutliers), 80, 'k', 'filled', 'MarkerEdgeColor', 'y');
legend('原始数据','LOESS趋势线','自适应上边界','自适应下边界','正偏差异常','负偏差异常');

关键调优策略

  • Span参数优化:遍历0.2-0.8的取值,计算拟合残差的均方根,选择残差最小的Span值。
  • 核密度带宽调整:若默认带宽不合适,手动设置fitdist的Bandwidth参数,带宽越小密度检测越敏感。
  • 置信区间类型切换:如需更保守的检测,用'Prediction', 'confidence'(置信区间)替代观测区间,边界更窄。

批量处理适配

将逻辑封装为函数,循环处理数千个数据集:

function [posOutliers, negOutliers] = detectLOESSOutliers(x, y, span)
    % 实现上述预处理、拟合、边界调整、标记逻辑
    [sortedX, idx] = sort(x);
    sortedY = y(idx);
    mdl = fitlm(sortedX, sortedY, 'LinearModel', 'loess', 'Span', span);
    pred = predict(mdl, sortedX);
    kde = fitdist(sortedX, 'Kernel', 'epanechnikov');
    density = pdf(kde, sortedX);
    normDensity = (density - min(density))/(max(density)-min(density))*0.9 + 0.1;
    [~,~,lower,upper] = predict(mdl, sortedX, 'Prediction', 'observation');
    adjustedUpper = pred + (upper - pred)./normDensity;
    adjustedLower = pred - (pred - lower)*normDensity;
    positiveOutliers = sortedY > adjustedUpper;
    negativeOutliers = sortedY < adjustedLower;
    posOutliers = false(size(x));
    posOutliers(idx(positiveOutliers)) = true;
    negOutliers = false(size(x));
    negOutliers(idx(negativeOutliers)) = true;
end

% 批量处理示例
for i = 1:numDatasets
    x = datasetList{i}.x;
    y = datasetList{i}.y;
    [pos, neg] = detectLOESSOutliers(x, y, 0.3);
    % 保存结果或自动生成报告
end

注意事项

  • 若数据存在多簇分布,先通过kmeans聚类,对每个簇单独做LOESS拟合,避免跨簇拟合导致的边界偏差。
  • 对于x轴无明确顺序的散点,可按局部密度或y值排序后再拟合,保证LOESS的局部性效果。

内容的提问来源于stack exchange,提问作者S_Av

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 12:23:33