跳轉到

3.2 Binary Classification

範例程式:Open In Colab

二元分類是最常見的深度學習任務之一。它的問題形式很直覺:輸入一筆資料,模型要回答「是」或「不是」。例如客戶是否流失、設備是否故障、交易是否詐騙、病患是否有風險、使用者是否會點擊廣告。

本篇使用 Breast Cancer Dataset 示範表格資料的二元分類流程。重點包含資料標準化、Dense DNN、sigmoid 輸出、binary_crossentropy、AUC、precision、recall、confusion matrix 與 threshold 調整。

1. 二元分類在學什麼?

二元分類的標籤通常是 01。模型最後不會直接輸出「類別名稱」,而是輸出一個機率。例如輸出 0.82,可以解讀成模型認為這筆資料屬於正類的機率是 82%。

輸出層通常寫成:

tf.keras.layers.Dense(1, activation='sigmoid')

sigmoid 會把任意實數壓到 0 到 1,因此適合當作二元分類機率。

2. 載入 Breast Cancer Dataset

Notebook 使用 scikit-learn 的 Breast Cancer Dataset。每一列是一筆樣本,每個欄位是數值特徵,目標欄位是二元類別。

data = load_breast_cancer(as_frame=True)
df = data.frame
print(df.shape)
df.head()

這份資料很適合教學,因為它是乾淨的表格資料,不需要先處理圖片、文字或複雜類別欄位。實務上,你可以把它替換成自己的 CSV,只要最後整理成 Xy 即可。

3. 切分資料與標準化

分類任務切分資料時,建議加上 stratify=y

x_train, x_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

stratify 會讓 train/test 保持相近的正負類比例。接著使用 StandardScaler

scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)

這裡要特別注意:fit_transform() 只能用在訓練集,測試集只能 transform(),避免測試資料資訊提前洩漏。

4. 建立 DNN 二元分類模型

model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(x_train.shape[1],)),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(16, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

前兩層 Dense 負責學習特徵組合,最後一層 sigmoid 輸出正類機率。這是一個表格資料二元分類的基本模板。

5. Compile:Loss 與 Metrics

model.compile(
    optimizer='adam',
    loss='binary_crossentropy',
    metrics=['accuracy', tf.keras.metrics.AUC(name='auc')]
)

二元分類使用 binary_crossentropy。Accuracy 可以快速看整體答對率,但不一定足夠,所以本篇也加入 AUC。AUC 可以衡量模型排序能力,不只依賴單一 threshold。

6. 評估:Confusion Matrix 很重要

Notebook 會輸出 confusion matrix 與 classification report:

print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred, target_names=data.target_names))
指標 解讀
Accuracy 全部樣本中答對比例
Precision 預測為正類的樣本,有多少是真的正類
Recall 真正的正類樣本,有多少被找出來
F1-score precision 和 recall 的折衷
AUC 模型整體排序能力

如果任務是疾病篩檢或設備異常偵測,通常會更重視 recall;如果人工複查成本很高,可能會更重視 precision。

7. Threshold:0.5 不是唯一答案

model.predict() 回傳的是機率:

prob = model.predict(x_test, verbose=0).ravel()
y_pred = (prob >= 0.5).astype(int)

0.5 是常見預設門檻,但正式專案應該依任務成本調整。降低 threshold 會讓模型更容易判定為正類,通常提高 recall;提高 threshold 會讓模型更保守,通常提高 precision。

8. 模型保存與部署提醒

模型訓練完成後,Keras 建議使用 .keras 格式保存:

model.save('dnn_binary_classification.keras')
loaded_model = tf.keras.models.load_model('dnn_binary_classification.keras')

但如果標準化是在模型外做的,也要保存同一個 scaler。部署時,新資料必須使用同一組 scaler 轉換,模型輸入才會和訓練時一致。

9. 如何套用自己的資料?

df = pd.read_csv('your_data.csv')
target_col = 'target'
feature_cols = [col for col in df.columns if col != target_col]
X = df[feature_cols].values.astype('float32')
y = df[target_col].values.astype('int64')

如果標籤不是 0/1,請先轉成二元數值。若資料包含類別欄位,可以先 one-hot,或直接使用 3.6 Mixed Feature DNN 的做法。

10. 小結

Binary Classification 的核心是 sigmoid、binary crossentropy、threshold 與多指標評估。這篇是所有二元判斷任務的基礎模板。