RFE配合rbf核SVM做特征选择返回NaN值如何解决
报错核心原因
你遇到的报错本质是RFE要求基学习器必须提供特征权重输出(coef_或feature_importances_属性),而你使用的rbf核SVC不满足这个要求:
- scikit-learn中只有使用线性核的SVC(
kernel='linear')会在拟合后生成存储各特征权重的coef_属性,rbf、poly等非线性核的SVC没有对应属性,RFE无法拿到特征重要性做排序淘汰,因此报错。 - 你替换的RF、DT、XGBoost等树模型默认会计算特征重要性,生成
feature_importances_属性,因此可以直接适配RFE。
同时你的代码还存在两个逻辑问题:
- Pipeline中RFE的基学习器和最终分类器复用了同一个未训练的SVC实例,会存在训练状态冲突的问题,两个阶段应该使用独立的模型实例。
- 交叉验证阶段你传入了
X_test, y_test,这属于测试集数据泄露,交叉验证应该在训练集X_train, y_train上执行,最终再用测试集评估最优模型的效果。
解决方案
方案1:使用线性核SVM适配RFE
如果你可以接受用线性SVM作为RFE的基学习器,修改get_models函数即可:
def get_models(min_selected_features, max_selected_features): models = dict() for i in range(min_selected_features, max_selected_features): # RFE的基学习器用线性核SVM,支持输出coef_ rfe_estimator = svm.SVC(kernel='linear', probability=True) clf = RFE(estimator=rfe_estimator, n_features_to_select=i) # 最终分类器可以按需求指定核,和RFE基学习器独立 final_model = svm.SVC(kernel='rbf', probability=True) models[str(i)] = Pipeline(steps=[('s',clf),('m',final_model)]) return models # 交叉验证修改为使用训练集 scores = evaluate_model(model, X_train, y_train)
方案2:保留非线性核SVM,更换特征选择方法
如果必须使用非线性核SVM作为基学习器,RFE不支持该场景,可更换为以下方案:
- 使用序列特征选择(SequentialFeatureSelector):该方法不需要模型输出特征重要性,通过迭代添加/删除特征、验证模型效果的方式选最优特征子集,适配所有类型的模型。
- 先通过**排列重要性(PermutationImportance)**计算非线性SVM的特征重要性,再基于重要性阈值做特征筛选。
- 更换为无监督/统计类特征选择方法,比如方差过滤、互信息特征选择、ANOVA F值检验等。
内容的提问来源于stack exchange,提问作者Tùng Võ
相关产品推荐
相关产品推荐

