从 Python 中的一维和二维数据中识别异常值块
Identifying chunks of outliers from a 1D and 2D data in Python
Data: 我在一列中有一个数据 d 作为函数变化另外两个变量 a 和 b 的定义在其他两列中。我的 objective 是识别 d 中的块或异常值。这些离群值块可能看起来不是离群值,但就我而言,我想识别那些不落在可以用直线拟合的数据云上的数据。
问题:虽然我以前从来没有做过聚类分析,但是这个名字听起来好像可以实现我想做的事情。如果我选择进行聚类分析,我想针对以下两种情况进行分析:
- 与 a 和 d
- 与 a、b 和d
我做了一些搜索,发现#1,使用 KernelDensity
模块会更合适,而对于 #2,使用 MeahShift
模块是一个不错的选择,两者都在 Python .
问题: 我以前从未做过聚类分析,所以我无法理解他们文档中给出的 KernelDensity
和 MeahShift
的示例(here and here,分别)。有人可以解释一下我如何使用 KernelDensity
和 MeahShift
来识别 d 中的异常值 "chunks"对于案例 1 和案例 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')
# 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')
您的示例数据
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)
Data: 我在一列中有一个数据 d 作为函数变化另外两个变量 a 和 b 的定义在其他两列中。我的 objective 是识别 d 中的块或异常值。这些离群值块可能看起来不是离群值,但就我而言,我想识别那些不落在可以用直线拟合的数据云上的数据。
问题:虽然我以前从来没有做过聚类分析,但是这个名字听起来好像可以实现我想做的事情。如果我选择进行聚类分析,我想针对以下两种情况进行分析:
- 与 a 和 d
- 与 a、b 和d
我做了一些搜索,发现#1,使用 KernelDensity
模块会更合适,而对于 #2,使用 MeahShift
模块是一个不错的选择,两者都在 Python .
问题: 我以前从未做过聚类分析,所以我无法理解他们文档中给出的 KernelDensity
和 MeahShift
的示例(here and here,分别)。有人可以解释一下我如何使用 KernelDensity
和 MeahShift
来识别 d 中的异常值 "chunks"对于案例 1 和案例 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')
# 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')
您的示例数据
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)