RFE (Recursive Feature Elimination,遞迴特徵消除法) 是一種特徵工程技術。
它透過反覆訓練模型並剔除權重最低的特徵,找出對預測最有貢獻的變數。
其核心優勢在於能減少過擬合、提升模型泛化能力。

什麼是包裝法(Wrapper method)
包裝法(Wrapper)是特徵選擇技術當中的一種方式,其主要的特色是在使用此方式時,包裝法會與建立模型的訓練一同進行,這樣的優點是可以依照我們的目標變數,進行特徵的篩選,在保留重要特徵的同時,也會過排除掉較不重要的特徵。
以下我們會介紹兩種不同的包裝法,分別為:
- RFE(Recursive Feature Elimination):遞迴特徵消除法
- RFECV(Recursive Feature Elimination with Cross-Validation):有交叉驗證功能的遞迴特徵消除法
使用包裝法(Wrapper method)的優點
RFE方法適用於預測輸出能夠直接解釋特徵重要性的模型,例如決策樹、隨機森林和或是具有係數的線性模型等,RFE方法透過遞迴減少特徵數量,能夠增強模型的泛化能力(Generalization Capability),也就是讓模型在訓練資料以外的新資料上的預測能力也能夠有穩定的表現,另外能夠減少模型因為多餘的特徵或無相關性特徵而引起的過擬合(Overfitting)問題。
RFECV(Recursive Feature Elimination with Cross-Validation)就是基於RFE方法,加入帶有交叉驗證的模型,這兩種方法都是基於模型權重來選擇特徵,用於去除對模型預測貢獻不大的特徵。
遞迴特徵消除法(Recursive Feature Elimination, RFE)的特徵篩選流程
RFE(遞迴特徵消除)主要的原理是透過遞迴的方式來移除不重要的特徵,從中篩選出對模型預測最有貢獻的特徵子集(Feature Subset),下面說明篩選的步驟:
- 初始化模型與特徵子集:
我們可以先選擇一個初始的機器學習模型作為估計器(Estimator),此模型會提供關於篩選特徵所需重要性的訊息,而初始模型會將所有的特徵都加入初始模型當中進行訓練。 - 訓練模型並評估特徵重要性:
使用初始選擇的機器學習模型開始訓練資料,並依據模型提供的指標(metric),例如特徵的權重(Weight)或係數(Coefficient),以用來評估每個特徵的重要性。 - 移除最不重要的特徵:
根據訓練後的模型評估出的特徵重要性排序(Permutation Feature Importance),移除其中最不重要的特徵,我們可以設定每次要移除多少個特徵,或移除比例佔多少的特徵數量。 - 遞迴與重複執行:
當移除第一次不重要的特徵後,模型將會用剩下的特徵子集再次訓練模型,並再次移除最不重要的特徵,這樣的過程就會遞迴的執行,直到我們設定的特徵數量。 - 獲得最佳的特徵子集:
經過多次的特徵篩選和移除不重要特徵後,最後剩餘的特徵子集就會被視為對模型預測最有效果的特徵子集。
RFE 模型參數介紹
模型參數說明都是介紹scikit-learn當中的套件,首先是RFE的超參數說明:
estimator: 選定一個模型,模型需有特徵重要性的排名。n_features_to_select: 設定選擇的特徵數量;也可以設定為None,表示會保留一半的特徵在模型中。step: 設定每次遞迴要移除的特徵數量或是百分比。verbose: 設定有無需要顯示計算的內容。
接下來是RFECV的超參數說明:
estimator: 選定一個模型,模型需有特徵重要性的排名。step: 設定每次遞迴要移除的特徵數量或是百分比。cv: 設定交叉驗證策略的次數。scoring: 選定用來選擇特徵的評分指標(metric)。min_features_to_select: 設定選擇的最少特徵數量,默認值為1。verbose: 設定有無需要顯示計算的內容。n_jobs: 設定平行運算的CPU數量。
RFE 的實作三部曲教學
- 選擇武器(Estimator):
挑選一個能計算權重的模型(例如:SVC 或 RandomForest)。 - 設定目標(n_features):
決定你最終想留下幾個特徵。 - 開始篩選(Fit):
讓 RFE 透過「遞迴」自動幫你刪掉沒用的變數。
RFE 如何應用於模型
RFE不僅可以應用在分類問題上,也可以用於回歸問題,包裝法會依據選定的估計器來評估特徵的重要性,所以在選擇估計器的同時,就要對應到自身的預測類型進行模型的選擇,以下介紹RFE方法在分類問題上的效能表現。
分類問題範例(乳癌資料集)
這裡使用的資料集是Scikit-learn的乳癌資料集,目標是預測腫瘤是良性(benign)還是惡性(malignant),使用的估計器模型是支持向量機(SVM),所有的程式碼放在Colab提供給大家。
# 安裝需要的套件
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import time
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import RFE
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, learning_curve
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
# 載入乳癌資料
data = load_breast_cancer()
X = data.data
y = data.target
print('原始資料的特徵數量: ', len(load_breast_cancer()['feature_names']), '\n', load_breast_cancer()['feature_names'])
print()
print('預測標籤為0(惡性腫瘤):', load_breast_cancer()['target_names'][0])
print('預測標籤為1(良性腫瘤):', load_breast_cancer()['target_names'][1])
# 切分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=28)
# 建立SVM分類器
svc_full = SVC(kernel='linear')
# 使用全部特徵訓練和預測並計算預測時間
start_time_full = time.time()
svc_full.fit(X_train, y_train)
y_pred_full = svc_full.predict(X_test)
end_time_full = time.time()
time_full = end_time_full - start_time_full
# 使用RFE選擇的特徵和預測並計算預測時間
svc = SVC(kernel='linear')
selector = RFE(estimator=svc, n_features_to_select=10, step=1)
selector = selector.fit(X_train, y_train)
X_train_rfe = selector.transform(X_train)
X_test_rfe = selector.transform(X_test)
start_time_rfe = time.time()
svc.fit(X_train_rfe, y_train)
y_pred_rfe = svc.predict(X_test_rfe)
end_time_rfe = time.time()
time_rfe = end_time_rfe - start_time_rfe
# 計算混淆矩陣
cm_full = confusion_matrix(y_test, y_pred_full)
cm_rfe = confusion_matrix(y_test, y_pred_rfe)
# 繪製混淆矩陣
plt.figure(figsize=(16, 6))
plt.subplot(1, 2, 1)
sns.heatmap(cm_full, annot=True, fmt="d", cmap='Blues', xticklabels=data.target_names, yticklabels=data.target_names)
plt.title('Confusion Matrix with All Features')
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.subplot(1, 2, 2)
sns.heatmap(cm_rfe, annot=True, fmt="d", cmap='Blues', xticklabels=data.target_names, yticklabels=data.target_names)
plt.title('Confusion Matrix with RFE Features')
plt.ylabel('Actual')
plt.xlabel('Predicted')
# 計算準確度
accuracy_full = accuracy_score(y_test, y_pred_full)
accuracy_rfe = accuracy_score(y_test, y_pred_rfe)
# 輸出預測的時間和準確度
print()
print(f'Training and prediction time with all features: {time_full:.4f} seconds')
print(f'Training and prediction time with RFE features: {time_rfe:.4f} seconds')
print()
print(f'Accuracy with all selected features: {accuracy_full:.4f}')
print(f'Accuracy with RFE selected features: {accuracy_rfe:.4f}')
原始資料的特徵數量: 30
[‘mean radius’ ‘mean texture’ ‘mean perimeter’ ‘mean area’
‘mean smoothness’ ‘mean compactness’ ‘mean concavity’
‘mean concave points’ ‘mean symmetry’ ‘mean fractal dimension’
‘radius error’ ‘texture error’ ‘perimeter error’ ‘area error’
‘smoothness error’ ‘compactness error’ ‘concavity error’
‘concave points error’ ‘symmetry error’ ‘fractal dimension error’
‘worst radius’ ‘worst texture’ ‘worst perimeter’ ‘worst area’
‘worst smoothness’ ‘worst compactness’ ‘worst concavity’
‘worst concave points’ ‘worst symmetry’ ‘worst fractal dimension’]
預測標籤為0(惡性腫瘤): malignant
預測標籤為1(良性腫瘤): benign
Training and prediction time with all features: 2.0523 seconds
Training and prediction time with RFE features: 0.0065 seconds
Accuracy with all selected features: 0.9532
Accuracy with RFE selected features: 0.9532

在輸出結果可以看到,原始全部特徵使用30項,而我們經過RFE選擇是選擇10項特徵,可以發現最後的準確度兩個幾乎是相同的,但在預測時間方面,可以發現計算時間的差異很明顯。
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import learning_curve
# 設計一個學習曲線圖
def plot_learning_curve(estimator, title, X, y, axes=None, ylim=None, cv=None, n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5)):
if axes is None:
_, axes = plt.subplots(1, 1, figsize=(8, 6))
axes.set_title(title)
if ylim is not None:
axes.set_ylim(*ylim)
axes.set_xlabel("Training examples")
axes.set_ylabel("Score")
train_sizes, train_scores, test_scores = learning_curve(
estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
# 繪製學習曲線
axes.grid()
axes.fill_between(train_sizes, train_scores_mean - train_scores_std,
train_scores_mean + train_scores_std, color="r", alpha=0.1)
axes.fill_between(train_sizes, test_scores_mean - test_scores_std,
test_scores_mean + test_scores_std, color="g", alpha=0.1)
axes.plot(train_sizes, train_scores_mean, 'o-', color="r",
label="Training score")
axes.plot(train_sizes, test_scores_mean, 'o-', color="g",
label="Cross-validation score")
axes.legend(loc="best")
return plt
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))
# 繪製使用全部特徵的學習曲線
plot_learning_curve(svc_full, "Learning Curve with All Features", X_train, y_train, axes=ax1, cv=5, n_jobs=4)
# 繪製使用RFE選擇的特徵的學習曲線
plot_learning_curve(svc, "Learning Curve with RFE Features", X_train_rfe, y_train, axes=ax2, cv=5, n_jobs=4)
plt.tight_layout()
plt.show()

繪製學習曲線圖主要是評估訓練與測試資料的貼近程度,紅色與綠色線越貼近,表示該模型的泛化程度好,穩定性佳,顯示經過RFE方法建立的模型有更快的預測速度以及更好的泛化能力。
實作 RFE 的常見問題
Q1: 什麼是特徵工程中的 RFE 遞迴特徵消除法?
A: RFE 是一種「包裝法(Wrapper Method)」的特徵選擇技術。
它透過重複訓練模型,每次移除重要性最低的特徵,直到剩下預設數量的特徵為止,藉此優化資料分析模型的表現。
Q2: 在資料分析中使用 RFE 有什麼好處?
A: 使用 RFE 可以有效減少多餘特徵導致的「過擬合(Overfitting)」問題,並縮短模型預測時間,同時提升模型在處理新資料時的泛化能力。
Q3: RFE 與 RFECV 有什麼不同?
A: RFE 需要手動設定要保留的特徵數量;而 RFECV 加入了「交叉驗證(Cross-Validation)」,能自動幫你找出最理想的特徵數量,不需要憑感覺猜測。
Q4: RFE 適合搭配哪些模型使用?
A: RFE 必須配合「能提供特徵重要性」的模型,例如:具有係數(coefficients)的線性模型(SVM、邏輯迴歸)或隨機森林等決策樹模型。
Q5: 為什麼初學者應該學會遞迴特徵消除法?
A: 因為在現實世界的資料分析中,特徵往往數量眾多且複雜。
掌握 RFE 能幫助你理解哪些變數才是影響預測結果的關鍵,是從「跑模型」進階到「優化模型」的必經之路。
現在親自動手試試看吧!
我們已經將文中的「乳癌資料集」範例程式碼整理在 Colab 筆記本中。
馬上執行程式碼,看看特徵減少後,你的模型速度提升了多少倍!
如果你在實作 RFE 時遇到報錯,歡迎在下方留言,我會親自為你解答。

Good shout.