聚类时10折交叉验证报错:模型无fit属性与最优模型留存问题
报错根因
- 变量覆盖错误:Section2中执行
rf = cross_val_score(rf, train_feature, train_label, cv = 10)时,cross_val_score的返回值是长度为10的numpy数组,存储每一折的验证得分,并非模型对象。把这个数组重新赋值给原本存随机森林实例的rf变量后,后续调用rf.fit()本质是在给numpy数组调用fit方法,自然会提示不存在该属性。 - 逻辑认知偏差:
cross_val_score的设计逻辑是仅返回验证评分,训练过程中每一折生成的临时模型在计算完得分后就会被内存回收,不会留存任何折的拟合结果,根本无法直接从中提取“最优模型”。 - 规则不匹配:直接传
cv=10调用的是普通K折拆分,不是需要的分层10折交叉验证,在样本类别分布不均衡时验证结果会有明显偏差。
可复用修正方案
以下代码同时满足分层10折验证、自动留存最优折拟合模型、可无缝替换为KNN/决策树/逻辑回归等其他sklearn兼容模型的需求:
from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import StratifiedKFold from sklearn.base import clone import numpy as np # 1. 初始化配置 # 定义分层10折拆分规则,固定随机种子保证结果可复现 skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=42) # 初始化基础模型,换其他模型只需要修改这一行即可 base_model = RandomForestClassifier(random_state=42) # 2. 逐折训练、留存最优模型 best_val_score = -np.inf best_trained_model = None for fold_id, (train_fold_idx, val_fold_idx) in enumerate(skf.split(train_feature, train_label)): # 拆分当前折的训练、验证子集 X_train_fold, X_val_fold = train_feature[train_fold_idx], train_feature[val_fold_idx] y_train_fold, y_val_fold = train_label[train_fold_idx], train_label[val_fold_idx] # 克隆基础模型的初始参数,避免前序折训练的参数残留 fold_model = clone(base_model) fold_model.fit(X_train_fold, y_train_fold) # 计算当前折验证集准确率 fold_score = fold_model.score(X_val_fold, y_val_fold) print(f"第{fold_id+1}折验证得分:{fold_score:.4f}") # 得分更高则更新最优记录 if fold_score > best_val_score: best_val_score = fold_score best_trained_model = fold_model # 3. 用最优模型在测试集上预测 predictionrf = best_trained_model.predict(test_feature) scores.append(['Random Forest'] + apply_metrics(test_label, predictionrf)) print(f"模型最优交叉验证得分:{best_val_score:.4f}")
关键注意事项
- 逐折训练时必须用
clone复制基础模型,不能直接拿基础模型连续fit,否则下一折训练会在上一折的参数基础上更新,不符合交叉验证的独立拆分原则。 - 如果需要换其他对比模型(KNN、DTC、LR等),只需要替换
base_model初始化的那一行代码,交叉验证、最优模型留存的逻辑完全不需要改动。 - 最优模型的判定标准可以根据需求替换,比如把
fold_model.score()换成F1值、AUC等其他指标的计算逻辑即可,不影响整体流程。
内容的提问来源于stack exchange,提问作者ZENoilers
相关产品推荐
相关产品推荐

