SOS算法(Stochastic Outlier Selection Algorithm)是由Jeroen Janssens提出的一种无监督异常检测算法。该算法通过计算数据点之间的关联度(affinity)来识别异常点。核心思想是,如果一个点与其他所有点的关联度都很低,那么它被视为异常点。以下是该算法的详细公式和步骤:
其MATLAB代码如下:
用于导入 data.xlsx
文件,使用除最后一列外的特征矩阵来检测并删除异常值,并将清理后的数据保存为新的 Excel 文件 cleaned_data.xlsx
。
% 导入数据
data = readmatrix('data.xlsx');
% 提取特征矩阵(除去最后一列)
features = data(:, 1:end-1);
% 获取特征矩阵的大小
[n, d] = size(features);
% 初始化异常概率矩阵
P = zeros(n, 1);
% 计算相异度矩阵(欧氏距离矩阵)
D = pdist2(features, features);
% 设置参数(如邻域大小 k 的估计,或标准差)
sigma = zeros(n, 1);
% 确定每个点的自适应尺度参数 sigma_i
for i = 1:n
% 排除自身计算局部邻域的距离
D_sorted = sort(D(i, D(i, :) > 0));
% 使用局部邻域(例如第 k 小的距离)来估计 sigma_i
k = min(10, n-1); % 选择邻域大小为 10 或点数 - 1
sigma(i) = D_sorted(k);
end
% 计算关联度矩阵
A = zeros(n, n);
for i = 1:n
for j = 1:n
if i ~= j
A(i, j) = exp(-D(i, j)^2 / (2 * sigma(i)^2));
end
end
% 归一化
A(i, :) = A(i, :) / sum(A(i, :));
end
% 计算每个点的异常概率
for i = 1:n
P(i) = exp(-sum(A(i, :)));
end
% 设置异常概率的阈值,例如中位数或自定义值
threshold = median(P);
% 标记并删除异常值
outlierIdx = P < threshold;
% 打印检测到的异常值数量
fprintf('检测到的异常值数量: %d\n', sum(outlierIdx));
% 删除异常值
cleanedData = data(~outlierIdx, :);
% 保存清理后的数据到新的 Excel 文件
writematrix(cleanedData, 'cleaned_data.xlsx');
disp('清理后的数据已保存为 "cleaned_data.xlsx".');
代码说明
pdist2(features, features)
:计算特征矩阵中所有点之间的欧氏距离矩阵 DDD。- 自适应尺度参数 σi\sigma_iσi:使用第 kkk 小的距离(局部邻域)来估计 σi\sigma_iσi。
- 关联度矩阵 AAA:通过高斯函数计算,确保每行总和为 1。
- 异常概率 PPP:计算每个数据点的异常性,并以此来标记和删除异常值。
调整建议
- 邻域大小 kkk:可以根据数据集的大小进行调整。
- 阈值选择:可以使用自定义阈值来标记异常点。
此代码运行后,MATLAB 会生成一个新的 Excel 文件 cleaned_data.xlsx
,其中包含删除异常值后的数据。
在 SOS 算法中,异常概率 PPP 用于量化每个数据点的异常性。为了识别和删除异常值,我们需要设置一个阈值,将高于或低于该阈值的点标记为异常。这里的解释涉及如何选择和理解该阈值:
1. 中位数作为阈值
- 中位数是将数据点的异常概率排序后位于中间的值,即分布的 50% 分位点。
- 直觉:如果使用中位数作为阈值,则大约一半的数据点的异常概率会低于中位数,一半会高于中位数。这样可以用来分辨数据中较不常见的点,但不会过于严格。
示例解释:
- 如果 PPP 中包含大部分接近于正常值的数据点,但有一些点的概率显著低(或高),将中位数作为阈值能很好地识别这些异常点。
2. 自定义阈值
- 自定义值意味着用户根据特定需求选择一个固定的阈值,如 0.1 或 0.05。
- 直觉:当用户对数据有一定了解时,可以基于经验或具体问题设置阈值。例如,若想只标记 5% 的数据为异常值,可以选用概率分布中的 95% 分位点。
示例解释:
- 如果你想更严格地标记异常值,可以选择更低的阈值,如在下 5% 的异常概率时标记点为异常值。
阈值的作用和影响
- 高阈值:标记较少的数据点为异常,保留大部分数据。
- 低阈值:标记更多的数据点为异常,数据可能被过度清洗。
- 中位数阈值:平衡的选择,不会过于严格或宽松。
代码中的实现
在代码中,使用中位数作为阈值示例如下:
threshold = median(P);
outlierIdx = P < threshold; % 标记低于中位数的点为异常值
使用自定义值,可以手动设置:
threshold = 0.05; % 自定义阈值
outlierIdx = P < threshold; % 标记低于自定义值的点为异常值
标签:Selection,Algorithm,阈值,Outlier,data,矩阵,中位数,数据,异常
From: https://blog.csdn.net/subject625Ruben/article/details/143825581