在线性回归中提取异常值的索引

Bor*_*rys 1 statistics numpy matplotlib scipy

以下脚本计算两个 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()
Run Code Online (Sandbox Code Playgroud)

San*_*der 5

异常值定义为:值均值 > 2*标准差。你可以用这条线做到这一点

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

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

快速测试:

x = np.random.random_integers(1,50,50)
Run Code Online (Sandbox Code Playgroud)

这给了我数组:

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])
Run Code Online (Sandbox Code Playgroud)

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

x[4] = 200
x[15] = 178
Run Code Online (Sandbox Code Playgroud)

让我们测试:

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

结果:

[4, 15]
Run Code Online (Sandbox Code Playgroud)

这就是你要找的吗?

编辑: 我在上面的行中添加了 abs() 函数,因为当您使用负数时,这可能会结束。abs() 函数取绝对值。