我有一个不包含异常值的训练数据集:
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 开始,隔离森林算法不需要污染,这可能非常有用。