提取线性回归中的离群值指数

Extracting the indices of outliers in Linear Regression

以下脚本计算两个 numpy 数组(x 和 y)之间的 R 平方值。

由于数据中存在离群值,R 平方值非常低。如何提取这些异常值的索引?

import numpy as np, matplotlib.pyplot as plt, scipy.stats as stats

x = np.random.random_integers(1,50,50)
y = np.random.random_integers(1,50,50)

r2 = stats.linregress(x, y) [3]**2
print r2

plt.scatter(x, y)

plt.show()

异常值定义为:平均值> 2*标准差。 您可以使用

行来执行此操作
[i for i in range(len(x)) if (abs(x[i] - np.mean(x)) > 2*np.std(x))]

是做什么的: 列表由 x 的索引构成,其中该索引处的元素满足上述条件。

快速测试:

x = np.random.random_integers(1,50,50)

这给了我数组:

array([16,  6, 13, 18, 21, 37, 31,  8,  1, 48,  4, 40,  9, 14,  6, 45, 20,
       15, 14, 32, 30,  8, 19,  8, 34, 22, 49,  5, 22, 23, 39, 29, 37, 24,
       45, 47, 21,  5,  4, 27, 48,  2, 22,  8, 12,  8, 49, 12, 15, 18])

现在我手动添加一些异常值,因为最初有 none:

x[4] = 200
x[15] = 178

让我们测试一下:

[i for i in range(len(x)) if (abs(x[i] - np.mean(x)) > 2*np.std(x))]

结果:

[4, 15]

这是您要找的吗?

编辑: 我在上面的行中添加了 abs() 函数,因为当你处理负数时,这可能会以失败告终。 abs()函数取绝对值。

我认为 Sander 的方法是正确的,但是如果您在做出决定之前必须看到 R2 没有那些异常值,这里是一种方法。

设置数据并引入异常值:

In [1]:
import numpy as np, scipy.stats as stats
np.random.seed(123)

x = np.random.random_integers(1,50,50)
y = np.random.random_integers(1,50,50)   
y[5] = 100

计算 R2 一次取出一个 y 值(以及匹配的 x 值):

m = np.eye(y.shape[0])
r2 = np.apply_along_axis(lambda a: stats.linregress(np.delete(x, a.argmax()), np.delete(y, a.argmax()))[3]**2, 0, m)

获取最大异常值的索引:

r2.argmax()

Out[1]:
5

去掉这个异常值得到R2:

In [2]:
r2[r2.argmax()]

Out[2]:
0.85892084723588935

获取离群值:

In [3]:
y[r2.argmax()]

Out[3]:
100

要获得最高 n 异常值:

In [4]:
n = 5
sorted_index = r2.argsort()[::-1]
sorted_index[:n]

Out [4]:
array([ 5, 27, 34,  0, 17], dtype=int64)