[機器學習]特徵工程_特徵選取_SFS

2024/01/06閱讀時間約 12 分鐘

Sequential Feature Selection(SFS)

用中文來解釋為,逐一特徵選取訓練,找出最重要的特徵,以提高模型的性能和效率

SFS 的一些用途包括:

  • 維度縮減: 在高維度數據中,許多特徵可能是多餘或不重要的,使用 SFS 可以找到最能代表數據的特徵,從而減少計算和記憶體需求。
  • 模型性能提升: 選擇最重要的特徵可以提高模型的性能,降低過擬合的風險,同時提高模型的泛化能力。
  • 解釋性: 減少特徵數目有助於更容易解釋和理解模型,使模型更具可解釋性。


  • 以下用程式碼實作說明,SFS的應用,資料集選用sklearn.數據集,葡萄酒數據集(分類),模型選用LogisticRegression()

實驗方法 : 同樣的資料集訓練,比較使用特徵選取的差異性,此資料夾總共有13種特徵,我們利用SFS來挑選出前三個最重要的特徵,在來評估準確率到底差異多少

範例連結

程式碼說明

導入必要套件

from sklearn.datasets import load_wine
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import seaborn as sns
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

# 設定中文字型
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
# 矯正負號
plt.rcParams['axes.unicode_minus'] = False

from sklearn.datasets import load_wine: 這裡導入了 scikit-learn 中的 load_wine 函數,用於加載葡萄酒數據集

用from 套件 import 函式,當你使用這樣的導入語句時,你就可以直接使用 load_wine 函數而不必在代碼中使用完整的模塊路徑sklearn.datasets.load_wine

import sklearn.datasets
data = sklearn.datasets.load_wine() #繁長的語句
from sklearn.datasets import load_wine
data = load_wine() #簡潔的語句

from sklearn.neighbors import KNeighborsClassifier: 從 scikit-learn 中導入 K 最近鄰(K-Nearest Neighbors)分類器,這是一種基於鄰近點的分類算法

from sklearn.model_selection import train_test_split: 導入了 scikit-learn 中的 train_test_split 函數,用於將數據集分割為訓練集和測試集,以進行模型的訓練和測試

import seaborn as sns: 導入了 Seaborn,這是一個用於繪製統計圖形的 Python 库。它通常與 Matplotlib 搭配使用,提供了更漂亮和更有吸引力的圖形。

import pandas as pd: 導入了 Pandas 庫,用於數據操作和分析。通常在數據科學和機器學習中使用 Pandas 來處理和操作數據。

import numpy as np: 導入了 NumPy 庫,這是一個用於科學計算的 Python 库。在數據處理和數學運算中經常使用 NumPy。

from matplotlib import pyplot as plt: 導入了 Matplotlib 庫,這是一個用於繪製圖形的庫。pyplot 提供了一個類似於 MATLAB 的繪圖接口


載入資料

X, y = load_wine(return_X_y=True, as_frame=True)

導入sklearn.數據集,葡萄酒數據集(分類)

  1. return_X_y=True: 這個參數的作用是讓 load_wine 函數返回特徵矩陣 X 和目標數組 y。默認情況下,load_wine 返回的是一個字典,包含特徵和目標。
  2. as_frame=True: 這個參數的作用是將數據返回為 Pandas 的 DataFrame 格式。當 as_frame=True 時,X 和 y 將被轉換成 DataFrame。

資料分割

X_train, X_test, y_train, y_test = train_test_split(X.values, y, test_size=0.5, random_state=42)

train_test_split 函數將數據集分割為訓練集X_train, y_train和測試集X_test, y_test。

X.values: 這裡的 X 是一個 DataFrame,而 train_test_split 函數通常期望輸入是 NumPy 數組(或類似的數據結構)。X.values 返回 DataFrame 中的數據作為 NumPy 數組,這樣就可以正確地傳遞給 train_test_split

y: 這是目標變數,它通常是一維的數組或列表。

test_size=0.5: 這個參數指定了測試集的大小。在這裡,測試集的大小為整個數據集的一半,即 50%。

random_state=42: 是一個種子值(seed),用來初始化隨機數生成器。在機器學習中,我們經常使用隨機過程(例如數據的分割、初始模型的權重等),而設定種子值可以確保這些隨機過程在不同的運行中保持一致。

特徵縮放

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler() # 創建標準化縮放器
X_train_std = scaler.fit_transform(X_train) # 使用訓練數據擬合並轉換特徵
X_test_std = scaler.transform(X_test) # 使用相同的轉換器對測試數據進行縮放,測試資料請勿用fit轉換
  1. from sklearn.preprocessing import StandardScaler: 導入 scikit-learn 中的 StandardScaler 類別。
  2. scaler = StandardScaler(): 創建一個 StandardScaler 的,這將用於對數據進行標準化。
  3. X_train_std = scaler.fit_transform(X_train): 使用訓練數據 X_train 來擬合(fit)標準化縮放器,同時將其轉換(transform)為標準化的特徵。fit_transform 方法首先計算訓練數據的均值和標準差。
  4. X_test_std = scaler.transform(X_test): 使用相同的標準化縮放器對測試數據 X_test 進行特徵縮放,這是因為我們希望使用訓練數據的均值和標準差來轉換測試數據。在這裡,我們使用 transform 而不是 fit_transform,因為我們不想重新計算均值和標準差,而是使用訓練數據中計算的值,這樣就失去了在訓練數據上學到的轉換規則,可能導致不準確的結果。

選擇演算法

使用scikit-learn中的LogisticRegression模型,這是一種用於二元分類的線性模型。

from sklearn.linear_model import LogisticRegression
# 創建Logistic Regression模型
clf = LogisticRegression()
raw-image

模型訓練

# 使用訓練數據進行模型訓練
#標準化訓練資料 ( X_train_std) 和對應的標籤 ( y_train)
clf.fit(X_train_std, y_train)

模型評估

目前出來的準確率,是使用了全部的特徵,13種,後面會使用SFS來做特徵選取三種,訓練比較其差異性

clf.score(X_test_std, y_test)

score(X_test_std, y_test): 這是一個用於計算模型性能的方法。通常,score 方法接受測試數據 X_test_std 和相應的目標變數 y_test 作為參數,然後返回模型在測試集上的準確度。

測試選取3個特徵的所有組合

from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SequentialFeatureSelector

knn = KNeighborsClassifier(n_neighbors=11) #特徵空間去算距離,適合少量的特徵
sfs = SequentialFeatureSelector(knn, n_features_to_select=3)
sfs.fit(X_train_std, y_train)
# 特徵選取名稱
column_list = np.array(X.columns.to_list())
column_list[sfs.get_support()]
raw-image

結果是挑選出三個特徵對預測結果最具影響力的

  1. from sklearn.metrics import accuracy_score: 導入 accuracy_score 函數,這是一個用於計算準確度的評估指標。
  2. from sklearn.feature_selection import SequentialFeatureSelector: 導入 SequentialFeatureSelector 類,這是 scikit-learn 提供的一個用於特徵選擇的工具。
  3. knn = KNeighborsClassifier(n_neighbors=11): 創建了一個 K 最近鄰分類器的實例 knn,並設置了鄰居的數量為 11。
  4. sfs = SequentialFeatureSelector(knn, n_features_to_select=3): 創建了一個 SequentialFeatureSelector 的實例 sfs,並指定了要選擇的特徵數量為 3。這個類將使用 K 最近鄰分類器來進行特徵選擇。
  5. sfs.fit(X_train_std, y_train): 使用訓練數據 X_train_std 和相應的目標變數 y_train 來擬合 SequentialFeatureSelector。這將執行特徵選擇過程。
  6. column_list = np.array(X.columns.to_list()): 這行代碼假設 X 是一個 DataFrame,通過 X.columns.to_list() 獲取所有特徵的名稱,然後使用 NumPy 將它們轉換為一個 NumPy 數組。
  7. column_list[sfs.get_support()]: 使用 sfs.get_support() 獲取經過特徵選擇後被選中的特徵的bool list,然後使用這個bool list來選擇相應的特徵名稱。這將返回被選中的特徵名稱的 NumPy 數組。

重新載入模型,使用SFS後的訓練集資料,來比較與使用SFS的差異

from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()

模型訓練

clf.fit(sfs.transform(X_train_std), y_train)

模型評估

clf.score(sfs.transform(X_test_std), y_test)
raw-image

使用SFS,準確率從0.988下滑至0.85

但在高維度的資料集應用中使用SFS來做特徵選取還是有必要性,反過來想在13種特徵只挑3種特徵來做訓練,還能有0.85,應該算不錯了

謝謝大家觀看,若喜歡,在給點愛心或留言鼓勵 謝謝~



48會員
83內容數
Python程式設計師,不是在學習就是在學習的路上
留言0
查看全部
發表第一個留言支持創作者!
從 Google News 追蹤更多 vocus 的最新精選內容