sklearn:使用隔离林进行异常检测



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

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 个。有人可以告诉我如何提高性能吗?我完全不确定为什么算法要求用户指定污染参数。我很清楚它被用作阈值,但我如何事先知道污染水平。谢谢!

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.链接

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

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

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

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

附言您也可以尝试仅使用普通实例训练的OneClassSVM - 测试集也应该与上面非常相似,而不仅仅是异常值。

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

在Scikit Learn文档中,它指出:

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

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

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

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

最新更新