您能解释一下异常值过滤吗?

pac*_*dev 0 outliers pandas scikit-learn

我有一个包含先验异常值的数据帧。我想至少从“降雨”变量中删除异常值。我按如下方式进行。它看起来有效,但我在第二个图中仍然有异常值。正常吗?

  1. 去除异常值之前

在此输入图像描述

  1. 去除异常值
rainfall = df["Rainfall"]
q3 = np.quantile(rainfall, 0.75)
q1 = np.quantile(rainfall, 0.25)

iqr = q3 - q1

upper_bound = q1 + 1.5 * iqr
lower_bound = q3 - 1.5 * iqr

rainfall_wo_outliers = df[(rainfall <= lower_bound) | (rainfall >= upper_bound)]["Rainfall"]
Run Code Online (Sandbox Code Playgroud)
  1. 去除异常值后

在此输入图像描述

Ps:我之前已经缩放过数据MinMaxScaler

moz*_*way 5

首先,您删除异常值的条件是相反的,您应该使用(rainfall >= lower_bound) & (rainfall <= upper_bound)

现在回到根本问题。是的,这是正常的。异常值去除(至少使用您的方法)依赖于当前分布四分位数来计算 IQR 并决定删除哪些点。

但是,一旦删除数据,新总体就会具有新的统计参数,这意味着您最终将获得相对于新 Q1 和 Q3 的新异常值。

这对于正常或均匀数据尤其明显:

import numpy as np
import matplotlib.pyplot as plt

def iqr_outliers_removal(s):
    q1, q3 = np.quantile(s, [0.25, 0.75])
    iqr = q3 - q1
    upper_bound = q1 + 1.5 * iqr
    lower_bound = q3 - 1.5 * iqr
    
    return s[(s>=lower_bound) & (s<=upper_bound)]

# generate random data
s = np.random.normal(size=10_000)

# iteratively remove outliers
s2 = s.copy()
n = len(s2)
out = [s2]
for _ in range(100):
    print('.', end='')
    s2 = iqr_outliers_removal(s2)
    out.append(s2)
    
ax = plt.subplot()
ax.plot(list(map(len, out)), marker='.', ls='')
ax.set_ylabel('data size')
ax.set_xlabel('iteration')
ax.set_yscale('log')
Run Code Online (Sandbox Code Playgroud)

100 次异常值去除迭代的样本大小:

迭代异常值去除

现在,您可能会删除异常值,并且新种群会变得稳定。如果您使用s = np.random.uniform(size=10_000)并运行模拟几次,有时您可能会得到如下结果:

人口稳定

但这只是偶然的;)