Scikit-Learn IsolationForest多DataFrame异参拟合实现(非GridSearchCV)
问题根因
代码逻辑存在两处错误:
- Pipeline模型实例在循环外提前定义,定义时IsolationForest的超参数就已经绑定为当时变量
i的取值,循环执行时不会动态匹配参数列表的对应索引值 - 循环内反复调用
fit()是在同一个模型对象上重复训练,存入结果字典的全是同一模型的引用,最终所有键对应的模型参数完全一致
修正方案
将Pipeline实例化逻辑移到循环内部,每次迭代用对应索引的超参数创建全新的独立模型,训练完成后直接计算所需的决策函数值和预测标签,统一存入结果字典:
from sklearn.pipeline import Pipeline from sklearn.impute import IterativeImputer from sklearn.preprocessing import StandardScaler from sklearn.compose import ColumnTransformer from sklearn.ensemble import IsolationForest # 5个模型对应的超参数,索引和数据集顺序一一对应(dataset0到dataset4) n_estimators = [150, 200, 125, 125, 125] max_samples = [0.70, 0.70, 0.80, 0.70, 0.70] max_features = [1, 4, 2, 2, 3] contamination = [0.05, 0.06, 0.05, 0.07, 0.05] # 数值列定义 num_columns = list(subset_features[1:]) # 结果存储字典,每个索引对应一个数据集的完整结果 clf_res = {} for i, (df_name, df) in enumerate(dfs.items()): print(f'开始训练第{i}个数据集:{df_name}') # 每次循环新建独立的预处理流与模型实例,绑定当前索引对应的超参数 num_transformer = Pipeline([ ('impute', IterativeImputer()), ('scale', StandardScaler()) ]) ct = ColumnTransformer([ ('num_pipeline', num_transformer, num_columns) ]) clf = Pipeline([ ('ct', ct), ('iforest', IsolationForest( n_estimators=n_estimators[i], max_samples=max_samples[i], max_features=max_features[i], contamination=contamination[i], n_jobs=4, random_state=42 # 如需完全随机可改回None,固定种子可保证结果可复现 )) ]) # 模型训练 clf.fit(df) # 计算所需输出 decision_scores = clf.decision_function(df) pred_labels = clf.predict(df) # 结果入库 clf_res[i] = { "dataset_name": df_name, "model": clf, "decision_scores": decision_scores, "pred_labels": pred_labels }
结果调用
训练完成后可直接按索引取对应数据集的结果:
- 训练好的独立模型:
clf_res[索引]["model"] - 异常决策分数:
clf_res[索引]["decision_scores"] - 异常预测标签(1为正常样本,-1为异常样本):
clf_res[索引]["pred_labels"]
所有模型均为独立实例,超参数与预设列表一一对应,不会出现参数复用问题。
内容的提问来源于stack exchange,提问作者GSA
相关产品推荐
相关产品推荐

