提取线性回归中的离群值指数
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)
以下脚本计算两个 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)