你能解释一下异常值过滤吗?
Could you explain outliers filtering?
我有一个包含先验离群值的 DataFrame。我想至少从“降雨量”变量中删除异常值。我这样做如下。它看起来有效,但我在第二个数字中仍然有异常值。 正常吗?
- 移除异常值之前
- 移除异常值
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"]
- 去除异常值后
Ps:我之前用MinMaxScaler
缩放过数据
首先,你去除异常值的条件是倒置的,你应该使用(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')
100 次异常值移除迭代的样本大小:
现在,您可能会删除异常值并且新的人口变得稳定。如果您多次使用 s = np.random.uniform(size=10_000)
和 运行 模拟,有时您可能会得到类似这样的结果:
但这只是偶然;)
我有一个包含先验离群值的 DataFrame。我想至少从“降雨量”变量中删除异常值。我这样做如下。它看起来有效,但我在第二个数字中仍然有异常值。 正常吗?
- 移除异常值之前
- 移除异常值
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"]
- 去除异常值后
Ps:我之前用MinMaxScaler
首先,你去除异常值的条件是倒置的,你应该使用(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')
100 次异常值移除迭代的样本大小:
现在,您可能会删除异常值并且新的人口变得稳定。如果您多次使用 s = np.random.uniform(size=10_000)
和 运行 模拟,有时您可能会得到类似这样的结果:
但这只是偶然;)