Hampel滤波器

Hampel滤波器是一种基于中值和中值绝对偏差(MAD)的滤波器,旨在识别和去除时间序列数据中的异常值。相对于传统均值和标准差方法,Hampel滤波器对异常值更具鲁棒性

Hampel滤波器的核心在于中值的计算和MAD的求解。中值代表数据的中间值,而MAD度量了数据点与中值之间的离散程度

中值:

对于包含N个数据点的数据集X,中值计算公式如下:

  • 如果N为奇数:中值=XN+12

  • 如果N为偶数:中值=12(XN2+XN2+1)

中值绝对偏差(MAD):

MAD是每个数据点Xi与数据集X的中值之间绝对差的中值:

MAD=中值(|Xi-中值(X)|)

其中,Xi表示每一个数据点

Hampel滤波器异常值判定标准:

如果数据点Xi被认定为异常值(即其绝对偏差除以MAD超过阈值),那么将其替换为数据集X的中值;否则,保持数据点的原始值

Xi={(X)if|Xi(X)|MAD>Xiotherwise

# 生成包含异常值的正弦波数据
def generate_data_with_outliers():
    time = np.linspace(0, 10, 100)
    signal = np.sin(time) + np.random.normal(0, 0.1, 100)
    # 添加异常值
    outliers_indices = [20, 40, 60, 80]
    outliers_values = [2.0, -1.9, 2.1, -0.5]
    
    for index, value in zip(outliers_indices, outliers_values):
        signal[index] = value
    return time, signal
def hampel(vals_orig, k=5, v=3):
    """
    使用Hampel滤波器去除时间序列中的异常值。
    参数:
        - vals_orig: numpy数组,原始时间序列数据
        - k: 整数,滤波器窗口的大小(半窗口大小为k/2)
        - v: 浮点数,用于异常值检测的阈值
    返回:
        - vals_filt: numpy数组,经过滤波的时间序列数据
        - outliers_indices: list,异常值的索引列表
    """
    # 创建输入数据的副本
    vals_filt = np.copy(vals_orig)
    outliers_indices = []
    # 定义Hampel滤波器函数
    n = len(vals_orig)
    for i in range(k, n - k):
        # 提取窗口
        window = vals_orig[i - k:i + k + 1]
        # 计算中值和中值绝对偏差(MAD)
        median = np.median(window)
        mad = np.median(np.abs(window - median))
        # 检查当前值是否为异常值
        if np.abs(vals_orig[i] - median) > v * mad:
            # 用中值替换异常值
            vals_filt[i] = median
            # 记录异常值的索引
            outliers_indices.append(i)
    return vals_filt, outliers_indices
    # 生成包含异常值的数据
    time, data = generate_data_with_outliers()    
    # 对数据应用Hampel滤波器
    filtered_data, outliers_indices = hampel(data)
    # 绘制原始数据和滤波后的数据
    plt.figure(figsize=(10, 6))
    plt.plot(time, data, label='origenal data')
    plt.scatter(time[outliers_indices], data[outliers_indices], c='red', 
    	marker='o', label='outliers', s=50)
    plt.plot(time, filtered_data, label='data filtered', linestyle='--', color='red')
    plt.fill_between(time, filtered_data, data, color='red', alpha=0.2, label='outliers region')
    plt.title('outliers removal using hampel identifier')
    plt.grid(True)
    plt.legend()
    plt.show()

posted @   华小电  阅读(564)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示