为何RFECV网格分数绘图会拆分为5条曲线?
解决RFECV绘制CV分数图出现多条曲线的问题
问题原因
- RFECV交叉验证默认设置:RFECV默认使用5折交叉验证,因此
grid_scores_(或新版本的cv_results_)存储的是每个特征数量下所有交叉验证折的分数,形成嵌套结构,直接绘图会生成对应折数的多条曲线。 - 任务类型不匹配:你使用回归模型(RandomForestRegressor),但RFECV的评估器用了分类器(DecisionTreeClassifier),特征选择逻辑不符合回归任务需求,会干扰分数计算。
- 代码逻辑冗余:将RFECV与模型放入Pipeline后又额外调用
cross_val_score,但RFECV内部已完成交叉验证选择最优特征数量,重复操作无意义。
修正方案与代码
核心调整点
- 替换RFECV的评估器为回归模型,匹配任务类型;
- 对每个特征数量的CV分数取均值,绘制单条曲线;
- 修正数据集读取的分隔符问题(原数据用分号分隔);
- 适配sklearn新版本的API(弃用
grid_scores_,改用cv_results_)。
修正后的完整代码
import pandas as pd import matplotlib.pyplot as plt from sklearn.feature_selection import RFECV from sklearn.tree import DecisionTreeRegressor from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import RepeatedKFold # 加载红酒质量数据集(注意原数据用分号分隔) dataset_url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv' df = pd.read_csv(dataset_url, sep=';') # 划分特征矩阵与目标变量 x = df.iloc[:, 0:-1] y = df.quality # 初始化RFECV:使用回归评估器,指定交叉验证策略 cv = RepeatedKFold(n_splits=10, n_repeats=1, random_state=42) rfe = RFECV( estimator=DecisionTreeRegressor(random_state=42), cv=cv, scoring='neg_mean_squared_error', n_jobs=-1 ) rfe.fit(x, y) # 绘制单条CV分数曲线:每个特征数量对应平均CV分数 plt.figure(figsize=(12, 6)) plt.xlabel("选择的特征数量") plt.ylabel("交叉验证分数(负均方误差)") plt.plot( range(1, len(rfe.cv_results_['mean_test_score']) + 1), rfe.cv_results_['mean_test_score'] ) plt.show() # 可选:用筛选后的最优特征训练回归模型 selected_features = x.columns[rfe.support_] selected_x = x[selected_features] model = RandomForestRegressor(random_state=42) model.fit(selected_x, y)
关键说明
- 任务匹配:回归任务必须使用回归类评估器(如
DecisionTreeRegressor),否则特征选择的评估逻辑会偏离任务需求。 - 分数均值计算:通过
cv_results_['mean_test_score']直接获取每个特征数量下的平均CV分数,无需手动遍历嵌套列表取均值(旧版本可使用[mean(score) for score in rfe.grid_scores_])。 - 数据读取修正:原数据集采用分号作为分隔符,未指定
sep=';'会导致数据读取错误,这是容易忽略的细节问题。
内容的提问来源于stack exchange,提问作者McGez
相关产品推荐
相关产品推荐

