GridSearchCV自定义评分评估IsolationForest估计器有效性咨询
无标签场景下Isolation Forest超参数调优问题
问题背景
现有一批无y target值的样本数据,所有X features(预测变量)均用于拟合Isolation Forest(孤立森林)估计器,目标是识别现有X特征、以及未来待输入数据中的真实异常值。例如拟合形状为(340,3)即(n_samples, n_features)的数组后,对特征做预测以识别340个观测值中的outliers(异常点)。
当前实现流程
- 创建Pipeline对象
from sklearn.pipeline import Pipeline from sklearn.ensemble import IsolationForest from sklearn.model_selection import GridSearchCV steps=[('IsolationForest', IsolationForest(n_jobs=-1, random_state=123))] pipeline=Pipeline(steps)
- 构建超参数调优参数网格
parameteres_grid={'IsolationForest__n_estimators':[25,50,75], 'IsolationForest__max_samples':[0.25,0.5,0.75,1.0], 'IsolationForest__contamination':[0.01,0.05], 'IsolationForest__bootstrap':[True, False] }
- 调用GridSearchCV执行调优
isolation_forest_grid=GridSearchCV(pipeline, parameteres_grid, scoring=scorer_f, cv=3, verbose=2) isolation_forest_grid.fit(scaled_x_features.values)
核心目标是设计合理的评分函数(即代码中定义的scorer_f),筛选出最适配异常检测场景的孤立森林估计器。
当前实现的评分函数如下:
def scorer_f(estimator, X): thresh=np.quantile(estimator.score_samples(X), 0.05) scores=estimator.score_samples(X) return len(np.where(scores<thresh)[0])
该评分函数逻辑为:固定将批次中5%(0.05分位数)的观测识别为异常值,所有得分低于阈值的样本判定为异常,期望通过该规则让GridSearch选择识别出最多异常值的模型以适配最坏场景。
当前交叉验证平均测试得分结果如下:
isolation_forest_grid.cv_results_['mean_test_score'] array([4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 3.8, 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 3.8, 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. , 4. ])
GridSearch最终随机选择了索引为31的模型作为最优模型,但绝大多数估计器识别出的异常值数量均为4.0,剩余选择逻辑本质为随机判定。
待确认问题:该实现方法在数学层面是否有效,是否能产出可用于异常检测的有效模型估计器。已知当前异常检测的现存痛点是sklearn.metrics库中缺少对应的官方评分指标,难以找到适配GridSearchCV方法的优质评分指标。
解答
- 你当前实现的评分函数没有数学有效性,完全无法筛选出效果更优的异常检测模型。
核心逻辑缺陷:你固定取预测得分的5%分位数作为异常阈值,只要模型输出的异常得分是连续值,低于该阈值的样本量永远会稳定在总样本量的5%左右。你使用3折交叉验证,每折样本量约为113,5%分位对应的异常数约为4-5个,结果中绝大多数得分都是4.0、极少数为3.8,本质是分位数计算的浮点误差、以及少量样本得分刚好等于阈值导致的,不是不同参数组合的模型效果一致,是你的评分规则从根本上无法区分模型好坏。 - 你设定的“选择识别异常最多的模型适配最坏场景”的逻辑同样不成立。无监督异常检测的目标是识别真正偏离正常数据分布的样本,而非尽可能多判定异常——如果按你的评分逻辑,把所有样本都判为异常的模型会拿到最高分,显然完全不符合业务需求。
无监督场景下Isolation Forest调优的可行方案
无标签异常检测不需要硬套带标签场景的GridSearchCV评分逻辑,可按以下优先级选择方案:
- 优先基于业务先验固定
contamination参数
如果你能通过业务经验估算出数据中的大致异常比例(例如交易场景欺诈率约1%、工业设备故障场景异常率约0.5%),直接将该值传入IsolationForest的contamination参数,模型会自动按该比例输出异常判定,不需要将该参数纳入网格搜索范围。 - 无业务先验时,用类间分离度作为评分指标
好的孤立森林模型,应当让识别出的正常点平均异常得分尽可能高、异常点平均异常得分尽可能低,两类点的得分差值越大,说明模型对正常/异常的区分度越好。可参考如下评分函数实现:import numpy as np def scorer_f(estimator, X): scores = estimator.score_samples(X) thresh = estimator.offset_ # 模型基于contamination计算的内置阈值 normal_scores = scores[scores >= thresh] anomaly_scores = scores[scores < thresh] # 过滤全判正常/全判异常的无效模型 if len(normal_scores) == 0 or len(anomaly_scores) == 0: return -np.inf # 返回两类样本的平均得分差,值越大区分度越高 return normal_scores.mean() - anomaly_scores.mean() - 缩小不必要的超参数搜索范围
针对你当前340样本、3特征的小数据集,n_estimators取100即可达到稳定效果,max_samples取256或全量样本即可,bootstrap参数对小数据集结果影响极小,不需要遍历过多参数组合——绝大多数参数组合在小数据集上的效果本来就没有显著差异,强行搜索只会增加无效计算。
内容的提问来源于stack exchange,提问作者NikSp
相关产品推荐
相关产品推荐

