You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于不同特征层级的SVM-RFE:全淘汰阶段性能与特征追踪问询

实现SVM-RFE分阶段特征淘汰并追踪性能与保留特征

嘿,这个需求其实很常见,用scikit-learn就能轻松搞定,关键是要控制RFE的淘汰节奏,同时把每个阶段的结果都记录下来。我给你捋清楚步骤,附上可运行的代码:

核心思路

  • 必须用线性核SVM作为基础模型:因为RFE需要通过模型的coef_属性评估特征重要性,只有线性核SVM才有这个属性
  • 用RFE的step=0.1参数:让每次迭代自动淘汰当前特征集的10%
  • 手动迭代追踪结果:默认RFE只会返回最终的特征子集,所以我们需要循环执行RFE,每次记录当前阶段的特征数、准确率和保留特征

完整代码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import RFE
from sklearn.datasets import make_classification

# ---------------------- 1. 准备数据(替换成你自己的数据集即可) ----------------------
# 模拟生成1000特征的二分类数据集,你可以替换成X = 你的特征矩阵,y = 标签向量
X, y = make_classification(n_samples=2000, n_features=1000, n_informative=100, random_state=42)

# ---------------------- 2. 初始化模型与追踪变量 ----------------------
# 初始化线性SVM分类器(必须用linear kernel,否则没有coef_无法进行RFE)
svc = SVC(kernel='linear', random_state=42)

# 初始化三个列表,分别记录每个阶段的特征数、准确率、保留特征索引
feature_counts = []
accuracy_scores = []
retained_features = []

# 初始特征索引:所有1000个特征都保留
current_features = np.arange(X.shape[1])

# ---------------------- 3. 循环执行SVM-RFE并追踪结果 ----------------------
while len(current_features) > 0:
    # 记录当前阶段的特征数量
    feature_counts.append(len(current_features))
    
    # 用当前特征集训练模型,用5折交叉验证计算平均准确率(避免过拟合,结果更可靠)
    X_current = X[:, current_features]
    avg_acc = cross_val_score(svc, X_current, y, cv=5, scoring='accuracy').mean()
    accuracy_scores.append(avg_acc)
    
    # 记录当前阶段保留的特征索引(注意用copy()避免后续修改影响已保存的数据)
    retained_features.append(current_features.copy())
    
    # 如果只剩1个特征,停止循环(再淘汰就没特征了)
    if len(current_features) == 1:
        break
    
    # 初始化RFE,每次淘汰当前特征的10%
    rfe = RFE(estimator=svc, step=0.1, verbose=0)
    # 用当前特征集拟合RFE
    rfe.fit(X_current, y)
    
    # 更新当前特征集:保留RFE选中的特征
    current_features = current_features[rfe.support_]

# ---------------------- 4. 结果查看与可视化 ----------------------
# 把结果转成DataFrame,方便查看和分析
results_df = pd.DataFrame({
    '特征数量': feature_counts,
    '5折平均准确率': accuracy_scores,
    '保留特征索引': retained_features
})

# 打印前5个阶段的结果
print("前5个阶段的特征淘汰结果:")
print(results_df.head())

# 绘制准确率随特征数量变化的折线图
plt.figure(figsize=(10,6))
plt.plot(feature_counts, accuracy_scores, marker='o', color='#1f77b4', linestyle='-')
plt.xlabel('特征数量', fontsize=12)
plt.ylabel('5折交叉验证平均准确率', fontsize=12)
plt.title('SVM-RFE特征淘汰阶段准确率变化趋势', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()

关键细节说明

  • 交叉验证的必要性:用cross_val_score而不是单一训练测试集,是为了避免数据划分带来的偶然性,让准确率更具参考性
  • 特征索引的追踪:每次保存current_features.copy()是因为列表是可变对象,直接赋值会导致后续修改覆盖之前的记录
  • 停止条件:当特征数只剩1时停止循环,确保我们能获取到最后一个特征的性能数据

如何获取指定阶段的结果

比如你想查看900个特征阶段的信息:

# 找到特征数量为900的行索引
idx = results_df[results_df['特征数量'] == 900].index[0]
# 获取该阶段的准确率和保留特征
acc_900 = results_df.loc[idx, '5折平均准确率']
feats_900 = results_df.loc[idx, '保留特征索引']
print(f"900特征阶段的平均准确率:{acc_900:.4f}")
print(f"900特征阶段保留的前10个特征索引:{feats_900[:10]}")

内容的提问来源于stack exchange,提问作者Malik Yousef

火山引擎 最新活动