【问题标题】:sklearn: Anomaly detection using Isolation Forestssklearn:使用隔离森林进行异常检测
【发布时间】:2017-12-16 16:02:04
【问题描述】:

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

train_vectors.shape
(588649, 896)

而且,我还有另一组测试向量 (test_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 个。有人可以告诉我如何提高性能。我完全不确定为什么该算法需要用户指定污染参数。我很清楚它被用作阈值,但我如何事先知道污染水平。谢谢!

【问题讨论】:

    标签: scikit-learn outliers anomaly-detection


    【解决方案1】:

    IsolationForest 的工作方式与您描述的有点不同:)。 contamination 是:

    The amount of contamination of the data set, i.e. the proportion of outliers in the data set. Used when fitting to define the threshold on the decision function.link

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

    train set and test set proportions
    ------------------------------------------------
    |  normal ~ 90%                  | outliers 10%|
    ------------------------------------------------
    

    尝试按照描述更改您的数据集比例,然后使用您发布的代码重试!

    希望这会有所帮助,祝你好运!

    附:你也可以试试OneClassSVM,它只用普通实例训练——测试集也应该和上面差不多,但不仅仅是异常值。

    【讨论】:

    • 我明白了。但是,我如何事先知道异常值百分比?
    • @user1274878 我知道我知道......你不能真的知道,但是,或者你有一个估计,例如由于某些假设,您的异常值很少见,或者您拥有各种数据集并且或多或少地知道会发生什么。在任何一种情况下,运行实验来评估和调整你的参数more info顺便说一句,隔离森林的工作假设你的异常值很少并且可以很容易地分离(“很少和不同”)。
    • 根据您的建议尝试了 oneClassSVM,但此数据集需要数小时。仅使用单个内核和大约 90% 的内存。你能指出一个有效的实现吗?
    • @user1274878 OCSVM 确实很慢,在做了一些研究之后,我尝试了不同的nu 值和shrinking 设置为False - 虽然不是一个令人印象深刻的改进。您也可以更改max_iter
    • @mkaran 感谢您的回答。可以请您看一下相关帖子here吗?
    【解决方案2】:

    虽然这个问题已有几年的历史,但我将其发布以供将来参考和人们提出类似问题,因为我目前处于类似情况。

    在 Scikit Learn 文档中指出:

    异常值检测: 训练数据包含异常值,这些异常值被定义为与其他数据相距甚远的观察值。因此,异常值检测估计器会尝试拟合训练数据最集中的区域,而忽略异常观察。

    新奇检测: 训练数据没有被异常值污染,我们有兴趣检测一个新的观察值是否是异常值。在这种情况下,异常值也称为新奇。

    从问题的这一部分判断“(..)这里的异常值百分比约为 10%,这是 sklearn 中用于隔离森林的默认污染参数。请注意,在训练集。”,这表明您可能想要使用的实际上是 Novelty Detection

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-20
      • 2020-11-16
      • 2020-01-14
      • 2020-10-01
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 2018-05-25
      相关资源
      最近更新 更多