在Python中识别1D和2D数据中的异常值块

时间:2015-07-09 21:11:10

标签: python scikit-learn cluster-analysis outliers chunks

数据:我在一列中有一个数据 d ,它随着另外两个变量的变化而变化, b ,在其他两列中定义。我的目标是在 d 中识别块或异常值。那些异常值块似乎不是异常值,但对于我的情况,我想识别那些不属于可以拟合线性数据的数据云的数据。

问题:尽管之前我从未进行过群集分析,但这个名称听起来似乎可以实现我想做的事情。如果我选择进行聚类分析,我想对两种情况进行如下操作:

  1. a d
  2. a b d
  3. 我做了一些搜索,找到了#1,使用KernelDensity模块会更合适,而使用MeahShift模块的#2将是一个不错的选择,都在Python中。

    问题:之前我从未进行过群集分析,所以我无法理解他们的文档中提供的KernelDensityMeahShift的示例(here和分别为here。有人可以解释我如何使用KernelDensityMeahShift来识别" chunk"情况1和2的 d 中的异常值?

1 个答案:

答案 0 :(得分:2)

首先,KernelDensity用于非参数方法。由于您坚信关系是线性的(即参数模型),KernelDensity不是此任务中最合适的选择。

以下是识别异常值的示例代码。

import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import RANSACRegressor


# data: 1000 obs, 100 of them are outliers
# =====================================================
np.random.seed(0)
a = np.random.randn(1000)
b = np.random.randn(1000)
d = 2 * a - b + np.random.randn(1000)
# the last 100 are outliers
d[-100:] = d[-100:] + 10 * np.abs(np.random.randn(100))

fig, axes = plt.subplots(ncols=2, sharey=True)
axes[0].scatter(a, d, c='g')
axes[0].set_xlabel('a')
axes[0].set_ylabel('d')
axes[1].scatter(b, d, c='g')
axes[1].set_xlabel('b')

enter image description here

# processing
# =====================================================
# robust regression
robust_estimator = RANSACRegressor(random_state=0)
robust_estimator.fit(np.vstack([a,b]).T, d)
d_pred = robust_estimator.predict(np.vstack([a,b]).T)

# calculate mse
mse = (d - d_pred.ravel()) ** 2

# get 50 largest mse, 50 is just an arbitrary choice and it doesn't assume that we already know there are 100 outliers
index = argsort(mse)
fig, axes = plt.subplots(ncols=2, sharey=True)
axes[0].scatter(a[index[:-50]], d[index[:-50]], c='b', label='inliers')
axes[0].scatter(a[index[-50:]], d[index[-50:]], c='r', label='outliers')
axes[0].set_xlabel('a')
axes[0].set_ylabel('d')
axes[0].legend(loc='best')
axes[1].scatter(b[index[:-50]], d[index[:-50]], c='b', label='inliers')
axes[1].scatter(b[index[-50:]], d[index[-50:]], c='r', label='outliers')
axes[1].legend(loc='best')
axes[1].set_xlabel('b')

enter image description here

您的样本数据

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import RANSACRegressor

df = pd.read_excel('/home/Jian/Downloads/Data.xlsx').dropna()

a = df.a.values.reshape(len(df), 1)
d = df.d.values.reshape(len(df), 1)

fig, axes = plt.subplots(ncols=2, sharey=True)
axes[0].scatter(a, d, c='g')
axes[0].set_xlabel('a')
axes[0].set_ylabel('d')

robust_estimator = RANSACRegressor(random_state=0)
robust_estimator.fit(a, d)
d_pred = robust_estimator.predict(a)

# calculate mse
mse = (d - d_pred) ** 2

index = np.argsort(mse.ravel())

axes[1].scatter(a[index[:-50]], d[index[:-50]], c='b', label='inliers', alpha=0.2)
axes[1].scatter(a[index[-50:]], d[index[-50:]], c='r', label='outliers')
axes[1].set_xlabel('a')
axes[1].legend(loc=2)