攝影或3C

Python 機器學習:手把手教你用 sklearn.preprocessing .StandardScaler 做數據標準化(Standardization); from sklearn.preprocessing import StandardScaler ; 儲存/載入 scaler or model: joblib.dump() / joblib.load()

加入好友加入好友
加入社群加入社群
Python 機器學習:手把手教你用 sklearn.preprocessing .StandardScaler 做數據標準化(Standardization); from sklearn.preprocessing import StandardScaler ; 儲存/載入 scaler or model: joblib.dump() / joblib.load() - 儲蓄保險王Python 機器學習:手把手教你用 sklearn.preprocessing .StandardScaler 做數據標準化(Standardization); from sklearn.preprocessing import StandardScaler ; 儲存/載入 scaler or model: joblib.dump() / joblib.load() - 儲蓄保險王

在機器學習中,數據標準化(Standardization)
是一個非常重要的步驟。
sklearn.preprocessing.StandardScaler
是一個專門用於標準化數據的工具,
它可以讓模型訓練更加高效,
並提升模型的魯棒性(robustness,抗干擾能力)。

這篇文章將分步教你如何使用 StandardScaler
並解釋如何保存和加載處理器以便在實際應用中重複使用。


1. 為什麼要標準化數據?

當數據的數值範圍相差很大時,
不同特徵對模型的影響可能會失衡。例如:

  • 特徵 A 的數值範圍是 1 到 1000
  • 特徵 B 的數值範圍是 0.1 到 1

在這種情況下,特徵 A 的數值範圍遠大於特徵 B,
模型可能會更傾向於依賴特徵 A,導致訓練結果不準確。

標準化的作用

  • 平衡特徵影響:將數據轉換為均值為 0,標準差為 1 的分佈。
  • 加速模型訓練:讓梯度下降算法更快收斂。
  • 提升模型效果:適合對數值範圍敏感的算法(如 SVM、KNN、線性迴歸等)。

2. 什麼是 StandardScaler

StandardScalerscikit-learn 提供的數據標準化工具,
根據以下公式對數據進行轉換:

  • μ 是特徵的均值(Mean)。
  • σ 是特徵的標準差(Standard Deviation)。

3. 基本使用:對數據進行標準化

步驟 1:準備數據

我們先準備一個簡單的數據集:

注意:X是一個2D數據,即使第二維長度僅有1,
StandardScaler 不支持 1D 數據
因為它需要明確的數據結構(樣本數 × 特徵數)。

步驟 2:使用 StandardScaler 標準化數據

解釋

  • 標準化後的數據具有以下特性:
    • 均值為 0。
    • 標準差為 1。

步驟 3:還原數據

當我們需要將標準化後的數據還原成原始數據時,
可以使用 inverse_transform 方法:

4. 使用 pandas 進行批量標準化

在實際項目中,我們通常會處理多個特徵的數據集(例如 DataFrame)。
以下是如何使用 StandardScaler 對多列數據進行標準化的範例:

5. 保存和加載 StandardScaler:使用 joblib

在實際應用中,我們通常需要將訓練好的處理器保存起來,
以便後續使用(例如處理測試數據或部署模型)。
這時可以使用 joblib 來保存和加載 StandardScaler

保存 Scaler

import joblib

# 保存 Scaler 到文件
joblib.dump(scaler, "scaler.joblib")
print("Scaler 已保存到文件:scaler.joblib")

加載 Scaler

# 從文件加載 Scaler
loaded_scaler = joblib.load("scaler.joblib")

# 使用加載的 Scaler 進行標準化
X_test = np.array([[4.0]])
X_test_scaled = loaded_scaler.transform(X_test)
print("測試數據標準化後:", X_test_scaled)

6. 如何處理目標值(y)的標準化?

如果我們的目標值(如迴歸任務中的 y)也需要標準化,
可以同樣使用 StandardScaler

7. 總結

StandardScaler 的核心功能

  • 標準化數據:將數據轉換為均值為 0,標準差為 1 的分佈。
  • 還原數據:可以將標準化後的數據還原為原始數據。

典型使用流程

  1. 初始化和訓練 Scalerscaler.fit(X)
  2. 標準化數據scaler.transform(X)
  3. 還原數據scaler.inverse_transform(X_scaled)
  4. 保存和加載 Scaler:用 joblib.dump() 保存,用 joblib.load() 加載。

推薦hahow線上學習python: https://igrape.net/30afN

StandardScaler 無法直接用於 1D 數據
這是因為它期望輸入數據是 2D 數據(如 (樣本數, 特徵數) 的形狀)。
即使你的數據只有一個特徵(如一列數據),
也需要將其展開為 2D 格式,否則會導致錯誤。


為什麼 StandardScaler 需要 2D 數據?

StandardScaler 是設計用來處理 多個樣本和多個特徵 的工具:

  • 每一列(特徵)會單獨計算均值和標準差。
  • 每一行(樣本)代表一個數據點。

當你傳入 1D 數據(如 [1, 2, 3]),
StandardScaler 無法分辨出數據的結構:
它不知道這是 3 個樣本的單column數據,
還是 1 個樣本的 3 個特徵。

如何解決?

如果你的數據是 1D 的,
可以使用 reshape(-1, 1) 將其轉換為 2D 格式,
這樣 StandardScaler 就能正確處理。


範例:1D 數據會報錯

# %%
from sklearn.preprocessing import StandardScaler

# 1D 數據
X = [1, 2, 3]  # 只有一個特徵

# 初始化 StandardScaler
scaler = StandardScaler()

# 嘗試標準化
X_scaled = scaler.fit_transform(X)  # 這會報錯

錯誤信息:

ValueError: Expected 2D array, got 1D array instead: array=[1. 2. 3.]. 
Reshape your data either using 
array.reshape(-1, 1) if your data has a single feature or 
array.reshape(1, -1) if it contains a single sample.

正確方法:將 1D 數據轉換為 2D

為什麼 .reshape(-1, 1) 可以解決問題?

  • reshape(-1, 1) 的意思是將數據重塑為 2D 數組,其中:
    • -1 會自動計算rows(樣本數)。
    • 1 表示只有一欄特徵。

例如:

np.array([1, 2, 3]).reshape(-1, 1)
# 變成
array([[1],
       [2],
       [3]])

這樣,StandardScaler 就能理解這是 3 個樣本的單column數據。


為什麼 StandardScaler 不直接支持 1D 數據?

StandardScaler 的設計目的是為了處理多列特徵(多維數據),
用於機器學習的典型場景。
對於 1D 數據,scikit-learn 的開發者選擇了更嚴格的接口設計,
強制用戶顯式提供數據的結構,來避免潛在的誤用。

例如,如果允許 1D 數據:

  • [1, 2, 3] 可能被誤解為 1 個樣本的 3 個特徵,而不是 3 個樣本的單個特徵。

通過要求 2D 格式,scikit-learn 可以清楚地區分數據的結構(行為樣本,列為特徵)。

使用 1D 數據的替代方法

如果你確實只需要對 1D 數據進行標準化,
並且不想轉換為 2D,完全可以用 numpy 手動計算均值和標準差:

總結

  • StandardScaler 不支持 1D 數據,因為它需要明確的數據結構(樣本數 × 特徵數)。
  • 解決方法:
    1. 將 1D 數據轉換為 2D,使用 .reshape(-1, 1)
    2. 或者直接用 numpy 手動標準化。
  • 嚴格要求 2D 格式是為了避免數據結構模糊的問題,提高接口的清晰性和穩定性。

部分code:

正確的標準化數據步驟:避免數據洩漏

在機器學習或深度學習中,數據標準化是非常重要的一步。
本文將解釋如何正確進行訓練集和測試集的標準化,
並說明每個步驟背後的原因。


1. 背景與問題

假設我們有以下數據集:

  • 訓練集 X_train:用於訓練模型。
  • 測試集 X_test:用於驗證模型的性能。

當我們對數據進行標準化時,必須遵循以下原則:

  1. 訓練集:使用 fit_transform(),計算均值和標準差,並對數據進行轉換。
  2. 測試集:使用 transform(),直接使用從訓練集計算的均值和標準差進行轉換。

2. 為什麼這麼做?

2.1 訓練集使用 fit_transform()

  • fit:計算訓練集每個特徵的均值和標準差。
  • transform:使用這些均值和標準差將數據縮放為標準化格式(均值為 0,標準差為 1)。

2.2 測試集使用 transform()

  • 測試集的數據必須用訓練集的統計量(均值和標準差)進行縮放,
    這模擬了模型在真實場景中處理「未見數據」的情況。

2.3 如果對測試集使用 fit_transform() 會怎麼樣?

  • 數據洩漏 (Data Leakage):測試集的統計量影響了模型的訓練過程,
    這相當於提前讓模型「偷看」了測試數據。
  • 不符合實際情況:在真實應用中,模型接觸的數據是未知的,
    因此測試集應該始終使用訓練集的統計量進行轉換。

3. 正確的數據標準化步驟

以下是正確的實現方式,基於 StandardScalernumpy

範例程式碼

# %%
from sklearn.preprocessing import StandardScaler
import numpy as np

# 假設訓練集和測試集
X_train = np.random.rand(604, 44)  # 訓練數據
X_test = np.random.rand(260, 44)  # 測試數據

# 初始化標準化器
scaler_X = StandardScaler()

# 對訓練集進行標準化
X_train_scaled = scaler_X.fit_transform(X_train)

# 使用訓練集的均值和標準差對測試集進行標準化
X_test_scaled = scaler_X.transform(X_test)

print("訓練集標準化後的形狀:", X_train_scaled.shape)
print("測試集標準化後的形狀:", X_test_scaled.shape)

輸出結果:

4. 適用於目標值(y)的標準化

對於迴歸任務,我們也可以對目標值 y進行標準化。以下是範例:

6. 常見錯誤與解決方法

  1. 未先使用 fit_transform() 就直接 transform()
    • 錯誤提示:NotFittedError
    • 解決方法:確保在使用 transform() 之前,先對訓練集使用 fit_transform()
  2. 對測試集使用了 fit_transform()
    • 問題:導致數據洩漏。
    • 解決方法:測試集僅使用 transform()
  3. 數據格式錯誤
    • 問題:Keras 模型需要 numpy 陣列,而 pandas DataFrame 可能未轉換。
    • 解決方法:使用 .values.to_numpy() 將 DataFrame 轉為 numpy 陣列。

7. 總結

正確的標準化步驟

  1. 訓練集:使用 fit_transform()
  2. 測試集:使用 transform()
  3. 避免數據洩漏:測試集始終使用訓練集的統計量。

為什麼重要?

  • 保證模型的泛化能力(對未見數據的表現)。
  • 避免不必要的數據洩漏,模擬實際應用場景。

關於目標值

  • 對目標值 y 的標準化同樣需要遵守這些原則。

這些步驟不僅適用於 StandardScaler
還適用於其他縮放器(如 MinMaxScaler)。

推薦hahow線上學習python: https://igrape.net/30afN

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡

Share
Published by
儲蓄保險王