0

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

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

4

2 回答 2

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. 关联

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

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

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

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

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

于 2017-07-12T10:09:39.863 回答
0

尽管这个问题已经存在了几年,但我将其发布以供将来参考和人们提出类似问题,因为我目前处于类似情况。

在 Scikit Learn 文档中它指出:

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

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

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

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

于 2019-10-17T10:49:28.380 回答