以下脚本计算两个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()
答案 0 :(得分:3)
异常值定义为:value-mean> 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])
现在我手动添加一些异常值,因为最初没有:
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()函数取绝对值。
答案 1 :(得分:1)
我认为桑德的方法是正确的,但如果你在做出决定之前必须看到没有这些异常值的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)