使用Isolation Forest做异常检测输出大量NaN,如何定位问题诱因?
问题原因排查
- 最高概率:DataFrame与预测结果的索引不匹配
你代码中clf.predict(data)返回的是顺序对齐的numpy数组,转成pd.Series()时默认生成从0开始的连续整数索引,如果原始传入的df的索引不是连续0开头的整数(比如做过行过滤、使用自定义索引、索引存在断层),赋值给df1["iforest"]时会按索引对齐,匹配不上的位置就会被填充为NaN。
解决方式:直接赋值numpy数组,不需要转Series,改为df1["iforest"] = clf.predict(data)即可,numpy数组赋值按位置对齐,不受索引影响。 - 次高概率:输入特征存在非法值
检查df1中是否存在缺失值、无穷大/无穷小值:
执行print(df1.isna().sum())查看是否有缺失值,执行print(np.isinf(df1.values).sum())查看是否有无穷值。sklearn的Isolation Forest在处理包含非法值的输入时,部分版本不会直接抛出异常,会输出NaN作为预测结果。如果存在非法值,先做填充、截断处理后再输入模型。 - 模型配置本身不会直接产生NaN
你当前设置的contamination=0.01、n_estimators=10属于合法参数范围,不会直接导致输出NaN。只有当输入特征全部为恒定值,树模型无法完成分裂时,才有可能出现预测异常,这种情况可以先检查df1.nunique()的结果,确认每个特征都有至少2种不同取值。
快速验证方法
先打印原生预测结果print(clf.predict(data)),如果输出的numpy数组本身就包含NaN,说明是输入数据或训练环节的问题;如果输出全是1和-1,就可以100%确定是索引对齐导致的问题。
内容的提问来源于stack exchange,提问作者Jeffrey Ran Zhang
相关产品推荐
相关产品推荐

