Scikit learn sklearn:使用隔离林的异常检测

Scikit learn sklearn:使用隔离林的异常检测,scikit-learn,outliers,anomaly-detection,Scikit Learn,Outliers,Anomaly Detection,我有一个不包含异常值的训练数据集: train_vectors.shape (588649, 896) 我还有另外一组测试向量(test\u vectors),它们都是异常值 以下是我尝试执行异常值检测的步骤: from sklearn.ensemble import IsolationForest clf = IsolationForest(max_samples=0.01) clf.fit(train_vectors) y_pred_train = clf.predict(train_ve

我有一个不包含异常值的训练数据集:

train_vectors.shape
(588649, 896)
我还有另外一组测试向量(
test\u vectors
),它们都是异常值

以下是我尝试执行异常值检测的步骤:

from sklearn.ensemble import IsolationForest
clf = IsolationForest(max_samples=0.01)
clf.fit(train_vectors)
y_pred_train = clf.predict(train_vectors)
print(len(y_pred_train))
print(np.count_nonzero(y_pred_train == 1))
print(np.count_nonzero(y_pred_train == -1))

Output:
 588649
 529771
 58878
因此,这里的异常值百分比约为10%,这是sklearn中用于隔离林的默认污染参数。请注意,训练集中没有任何异常值

测试代码和结果:

y_pred_test = clf.predict(test_vectors)
print(len(y_pred_test))
print(np.count_nonzero(y_pred_test == 1))
print(np.count_nonzero(y_pred_test == -1))

Output:
 100
 83
 17

因此,它只检测到100个异常中的17个。有人能告诉我如何提高性能吗。我完全不知道为什么算法要求用户指定污染参数。我很清楚,它被用作阈值,但我如何事先知道污染水平。谢谢大家!

IsolationForest的工作原理与您描述的略有不同:)。
污染
为:

数据集的污染量,即数据集中异常值的比例。拟合时用于定义决策函数的阈值。

这意味着您的训练集应该包含大约10%的异常值。理想情况下,您的测试集也应该包含大约相同数量的异常值——并且它不应该只包含异常值

train set and test set proportions
------------------------------------------------
|  normal ~ 90%                  | outliers 10%|
------------------------------------------------
请尝试按所述更改数据集比例,然后使用您发布的代码重试

希望这有帮助,祝你好运


另外,您还可以尝试只使用普通实例进行训练的测试集-测试集也应该与上面的测试集非常相似,而不仅仅是异常值。

虽然这个问题已经提出了几年,但我还是将其发布给未来的参考和问类似问题的人,因为我目前处于类似的情况

在Scikit学习文档中,它指出:

异常值检测: 训练数据包含异常值,这些异常值被定义为远离其他观测值的观测值。因此,离群点检测估计器试图拟合训练数据最集中的区域,而忽略异常观测

新颖性检测: 训练数据不受异常值的污染,我们感兴趣的是检测新观测值是否为异常值。在这种情况下,离群值也称为新奇值

从问题的这一部分判断“(..)这里的异常值百分比约为10%,这是sklearn中隔离林使用的默认污染参数。请注意,训练集中没有任何异常值。”这表明你可能想要使用的实际上是新奇性检测

正如@mkaran所建议的,OneClassSVM可以用于新颖性检测,但是,由于它有点慢,我建议任何处于这种情况的人尝试使用局部异常值因子。
另外,从sklearn版本0.22开始,IsolationForest算法不需要污染,这可能非常有用。

我明白了。但是,我如何事先知道异常值百分比?@user1274878我知道我知道。。。你不能真正知道,但是,要么你有一个估计值,例如,你的离群值是罕见的,因为一些假设,或者你有各种各样的数据集,或多或少知道会发生什么。在任何一种情况下,运行实验来评估和调整您的参数。顺便说一句,隔离林的工作原理是假设您的异常值很少且易于分离(“很少且不同”)。根据您的建议尝试了oneClassSVM,此数据集需要数小时。仅使用一个内核和大约90%的内存。你能告诉我一个有效的实现方法吗?@user1274878 OCSVM确实非常慢,在做了一些研究之后,我尝试了不同的
nu
值和
showing
设置为
False
——但这并不是一个令人印象深刻的改进。您也可以更改
max\u iter
@mkaran谢谢您的回答。我可以请你看看相关的帖子吗?