我有一个不包含异常值的训练数据集:
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个异常。有人可以告诉我如何提高性能。我完全不确定为什么算法要求用户指定污染参数。我很清楚它被用作阈值,但我如何事先知道污染程度。谢谢!
答案 0 :(得分: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%|
------------------------------------------------
尝试按照描述更改数据集比例,然后使用您发布的代码再试一次!
希望这有帮助,祝你好运!
P.S。您也可以尝试使用正常实例训练的OneClassSVM - 测试集也应该与上面非常相似,不仅仅是异常值。
答案 1 :(得分:0)
尽管这个问题已经存在了两年之久,但由于我目前处于类似情况,因此我将其发布以供将来参考和提出类似问题的人们。
在Scikit学习文档中它指出:
异常检测: 训练数据包含离群值,离群值定义为与其他观测值相距甚远的观测值。因此,离群检测估计器会尝试拟合训练数据最集中的区域,而忽略了异常观察。
新颖性检测: 训练数据不受异常值的污染,我们有兴趣检测新观察值是否是异常值。在这种情况下,离群值也称为新颖性。
从问题的这一部分判断“(..),其中异常值百分比约为10%,这是用于sklearn中的隔离林的默认污染参数。请注意,异常值中没有任何异常值训练集。”,这表明您实际上想使用的是新颖检测。
正如@mkaran所建议的,OneClassSVM可以用于新颖性检测,但是,由于它有点慢,因此我建议在这种情况下的任何人都应尝试使用本地异常值。 另外,从sklearn 0.22版开始,IsolationForest算法不需要污染,这可能非常有用。