含约1/3缺失值的DataFrame异常值标记及Isolation Forest实现求助
使用Isolation Forest检测异常值并标记NA/异常值
先看你的数据生成代码:
np.random.seed(42) data = np.random.randn(10000, 4) df = pd.DataFrame(data, columns=[f'Feature_{i+1}' for i in range(4)]) missing_rows = np.random.choice(10000, 3000, replace=False) for row in missing_rows: df.iloc[row, np.random.choice(4)] = np.nan
你之前用IQR逐特征检测异常,但Isolation Forest是基于整体特征分布的无监督异常检测算法,更适配特征不独立的场景。以下是具体实现步骤:
1. 预处理缺失值
Isolation Forest无法直接处理NaN,先对缺失值做填充(这里用中位数填充,也可根据数据分布选均值/众数):
from sklearn.impute import SimpleImputer from sklearn.ensemble import IsolationForest import pandas as pd # 填充缺失值 imputer = SimpleImputer(strategy='median') df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
2. 训练Isolation Forest并预测异常值
设置contamination参数指定异常值比例(根据数据情况调整,比如设为0.05代表5%的异常值):
# 初始化模型 iso_forest = IsolationForest(n_estimators=100, contamination=0.05, random_state=42) # 训练并预测,-1表示异常,1表示正常 df['is_abnormal'] = iso_forest.fit_predict(df_imputed) # 转为布尔值标记(True为异常) df['is_abnormal'] = df['is_abnormal'] == -1
3. 合并NA值标记
将缺失值也纳入需要标记的范围,生成每个特征的异常/NA标记:
for col in df.columns[:-1]: # 排除is_abnormal列 # 该特征的标记:模型检测的全局异常 或 本身为NaN df[f'mark_{col}'] = df['is_abnormal'] | df[col].isnull()
4. 用Pandas Styler标记异常值和NA值
通过样式函数给异常值和NA值设置不同背景色:
def highlight_abnormal_and_na(val, col): if pd.isna(val): return 'background-color: lightpink' if df.loc[df.index.get_loc(val.name), f'mark_{col}']: return 'background-color: yellow' return '' # 应用样式 styled_df = df.style.apply(lambda row: [highlight_abnormal_and_na(row[col], col) for col in df.columns[:-5]], axis=1) # 显示样式化后的DataFrame styled_df
关键说明:
- Isolation Forest基于特征空间隔离异常点,比单特征IQR更适合特征不独立的场景;
contamination参数可根据业务场景调整,不确定时可用默认的'auto',手动设置更可控;- 填充缺失值时,优先选择对数据分布影响小的策略,比如中位数适配有偏分布,均值适配正态分布;
- Styler样式可自定义,修改
return中的CSS即可调整字体颜色、加粗等效果。
内容的提问来源于stack exchange,提问作者Cooper
相关产品推荐
相关产品推荐

