我正在创建一个包含数千个数据点的交互式散点图,我想动态地找到异常值,以便只注释那些不太聚集在一起的点。
我目前正在通过使用以下查询以一种稍微复杂的方式执行此操作,用户可以在其中提供 q_x、q_y 和 q_xy(比如 0.998、0.994 和 0.95)的值:
outliers = df[(df['x'] > df['x'].quantile(q_x)) | (df['y'] > df['y'].quantile(q_y))
| ((df['x'] > df['x'].quantile(q_xy)) & (df['y'] > df['y'].quantile(q_xy)))]
这种实现了我想要的,但是用户必须修改三个变量以获得他们想要的选择,即使这样它也有点不平衡,因为查询的三个部分集中在数据的不同部分。
是否有更好、更合理的数学方法来查找一组 x、y 点的异常值?
非常感谢。
您可以定义一个接受规则字典的自定义函数:
def is_outlier(df, rules):
m_or = pd.Series(False, index=df.index)
for cols, q in rules.items():
cols = [cols] if isinstance(cols, str) else cols
m_and = pd.Series(True, index=df.index)
for col in cols:
m_and &= df[col] > df[col].quantile(q)
m_or |= m_and
return m_or.rename('outliers')
用法:
np.random.seed(142)
df = pd.DataFrame(np.random.randint(0, 50, (20, 2)), columns=['x', 'y'])
m = is_outlier(df, {'x': 0.998, 'y': 0.994, ('x', 'y'): 0.95})
输出:
>>> pd.concat([df, m], axis=1)
x y outliers
0 21 5 False
1 27 12 False
2 26 45 False
3 16 49 True
4 13 34 False
5 12 11 False
6 23 31 False
7 30 21 False
8 11 2 False
9 20 19 False
10 18 36 False
11 9 23 False
12 8 23 False
13 22 15 False
14 1 33 False
15 2 24 False
16 24 36 False
17 40 17 True
18 36 29 False
19 37 32 False
我找到了一篇非常有用的文章,它为我回答了这个问题。
我用过的代码:
from sklearn.ensemble import IsolationForest
outliers = 50 # or however many you want
l = len(df.index)
isf = IsolationForest(
n_estimators=100,
random_state=42,
contamination=0.5 if outliers / l > 0.5 else outliers / l
)
preds = isf.fit_predict(df[['x', 'y']].to_numpy())
df["iso_forest_outliers"] = preds
在哪里
outliers
是我想限制结果的异常值的数量。 'iso_forest_outliers'
列中的离群值列为 -1。 contamination
的值必须在 0 到 0.5 之间,这就是为什么会有 if else 语句的原因。