不连续有噪音的时间序列:4个过滤器子函数(2)
思路:
噪音过滤器:slope,Z-score,IQR等3个子函数,其中slope包含1个均值±3倍标准差筛选的子函数;这几种方法其实原理差不多,效果也是大差不差,按需求选用即可
子函数代码
- slope方法
function y_cleaned = removeOutliersSLOPE(y, itr_thresh,thresh_idx)
% removeOutliersSLOPE 使用 SLOPE 方法去除离群点
% y: 输入的时间序列
% itr_thresh: 筛选次数
% thresh_idx:标准差倍数阈值
% y_cleaned: 去除离群点后的时间序列
% 利用斜率筛选部分异常值
itr=1;
y_cleaned=y;
while itr<itr_thresh
y_filled = fillmissing(y_cleaned, 'linear'); % 先填充NaN
% 计算包络线的局部斜率
slope = [0;diff(y_filled)];
[slope_Stats,slope_nan_mask,slope_mask,valid_slope] =...
filter_mean_within_std_range('slope',slope,thresh_idx);
y_cleaned(slope_mask)=nan;
itr=itr+1;
end
end
这里包含filter_mean_within_std_range.m子函数,具体如下:
function [Output_Stats,nan_mask,out_of_range_mask,valid_vector] =...
filter_mean_within_std_range(object,input_vector,idx)
% 移除输入向量中的 NaN 值
nan_mask = isnan(input_vector);
input_nan_vector = input_vector(~nan_mask);
% 计算输入向量的均值和标准差
mu = mean(input_nan_vector);
sigma = std(input_nan_vector);
% 选择位于范围内的值
out_of_range_mask = input_vector > (mu + idx*sigma) | input_vector < (mu - idx*sigma);
valid_vector = input_vector;
valid_vector(out_of_range_mask)=nan;
% 计算保留值的均值
mean_within_std = nanmean(valid_vector);
% 计算保留值的均值
Output_Stats=table;
Output_Stats.type = object;
Output_Stats.mean_within_std = mean_within_std;%原数据均值
Output_Stats.num_all=length(input_vector);%原数据总个数
Output_Stats.num_nan=sum(nan_mask);%原数据nan值个数
Output_Stats.num_fiter=sum(out_of_range_mask);%原数据离群噪点个数
Output_Stats.dele_frac=(sum(nan_mask)+sum(out_of_range_mask))/length(input_vector);
end
- Z-score方法
function y_cleaned = removeOutliersZScore(y, threshold)
% removeOutliersZScore 使用 Z-score 方法去除离群点
% y: 输入的时间序列
% threshold: Z-score 的阈值 (通常为 3)
% y_cleaned: 去除离群点后的时间序列
% 计算 Z-score
z_scores = (y - mean(y, 'omitnan')) ./ std(y, 'omitnan');
% 标记离群点
outliers = abs(z_scores) > threshold;
% 去除离群点
y_cleaned = y;
y_cleaned(outliers) = NaN;
end
- IQR方法
function y_cleaned = removeOutliersIQR(y, multiplier)
% removeOutliersIQR 使用 IQR 方法去除离群点
% y: 输入的时间序列
% multiplier: IQR 的倍数阈值 (通常为 1.5)
% y_cleaned: 去除离群点后的时间序列
% 计算四分位数
Q1 = quantile(y, 0.25);
Q3 = quantile(y, 0.75);
IQR = Q3 - Q1;
% 计算上下界
lower_bound = Q1 - multiplier * IQR;
upper_bound = Q3 + multiplier * IQR;
% 标记离群点
outliers = (y < lower_bound) | (y > upper_bound);
% 去除离群点
y_cleaned = y;
y_cleaned(outliers) = NaN;
end