AI時代系列(1) 機器學習三部曲: 🔹 第一部:《機器學習 —— AI 智慧的啟航》
19/100 第二週:資料處理與特徵工程19. 類別不平衡問題的解決方案 🚦 用權重調整或數據合成技術(SMOTE),讓預測更公平!
1️⃣ 問題理解:什麼是類別不平衡?
在分類任務中,如果多數類別的數據量遠高於少數類別,模型往往會偏向多數類別,導致少數類別的識別效果非常差。
🔍 實際案例:詐欺交易檢測
類別 筆數
✅ 正常交易 95,000
❌ 詐欺交易 5,000
如果模型只預測「正常交易」,準確率看似高達 95%,但對於詐欺檢測完全無效。
2️⃣ 解決策略:兩大方向
🧩 A. 數據層面處理(Resampling Techniques)
方法 說明 適用場景
過採樣 增加少數類別數據 數據量較少時
欠採樣 減少多數類別數據 數據量巨大時
SMOTE 合成少數類別樣本 數據偏少,避免過擬合
🧩 B. 模型層面處理(Algorithm-Level Techniques)
方法 說明 適用場景
權重調整 讓模型更重視少數類別 數據量大不想更動數據集
特殊演算法 如 XGBoost、LightGBM 極端不平衡或大數據
3️⃣ 實戰流程演練!
💡 Step 1: 數據準備
import pandas as pd
from sklearn.datasets import make_classification
# 模擬不平衡數據集
X, y = make_classification(
n_samples=10000, n_features=20,
n_classes=2, weights=[0.95, 0.05],
random_state=42
)
print(pd.Series(y).value_counts())
💡 Step 2: 數據處理
✅ 過採樣 (RandomOverSampler)
from imblearn.over_sampling import RandomOverSampler
oversampler = RandomOverSampler(random_state=42)
X_resampled, y_resampled = oversampler.fit_resample(X, y)
print(pd.Series(y_resampled).value_counts())
✅ 欠採樣 (RandomUnderSampler)
from imblearn.under_sampling import RandomUnderSampler
undersampler = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)
print(pd.Series(y_resampled).value_counts())
✅ SMOTE 合成少數類別數據
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)
print(pd.Series(y_resampled).value_counts())
💡 Step 3: 模型層面處理
✅ 權重調整 (Class Weight)
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(class_weight="balanced", random_state=42)
model.fit(X_resampled, y_resampled)
✅ XGBoost 調整 scale_pos_weight
from xgboost import XGBClassifier
scale_pos_weight = (len(y_resampled[y_resampled == 0]) / len(y_resampled[y_resampled == 1]))
model = XGBClassifier(scale_pos_weight=scale_pos_weight, use_label_encoder=False, eval_metric='logloss')
model.fit(X_resampled, y_resampled)
💡 Step 4: 模型評估
不要只看準確率!用這組指標:
from sklearn.metrics import classification_report
# 假設已分割測試集
y_pred = model.predict(X_resampled)
print(classification_report(y_resampled, y_pred))
重點關注:
Precision 精確率:預測為「詐欺」的中,實際是詐欺的比例
Recall 召回率:所有詐欺中,被成功預測出的比例
F1-Score:綜合 Precision 和 Recall 的平均
AUC-ROC:多閾值下的效果
4️⃣ 方法選擇指南
面對類別不平衡問題,數據少時用 SMOTE,數據多用 欠採樣或權重調整,極端不平衡(99:1)選擇 XGBoost 的 scale_pos_weight,若數據難以修改,則採用 模型權重調整,靈活應對各種情境,提升模型表現。
🎉 結論:推薦配方!
📌 最穩定的組合建議:
✅ 數據層面:使用 SMOTE
✅ 模型層面:加上 class_weight="balanced"
✅ 評估指標:Precision / Recall / F1-Score / AUC-ROC
📌 千萬別只看準確率! 這樣能讓你的 AI 模型對少數類別也有公平對待,適合詐欺檢測、醫療診斷、品質異常檢測等高風險應用場景!




















