返回文章列表

糖尿病分類別模型訓練與評估流程

本文詳細介紹使用 PyTorch 訓練糖尿病分類別模型的流程,包含 Spark 資料預處理、模型訓練、評估指標計算以及 K 折交叉驗證的實作。文章涵蓋從 Amazon S3 讀取資料、使用 Spark 進行預處理、PyTorch 建立模型、訓練及評估等步驟,並以準確率、精確率、召回率、F1 分數和 ROC-AUC

機器學習 資料科學

利用 PyTorch 框架和 Apache Spark 分散式運算能力,可以有效地訓練糖尿病分類別模型。首先,透過 boto3 從 Amazon S3 下載資料,接著使用 Spark 建立資料處理流程,將資料轉換成適合 PyTorch 訓練的格式。模型訓練階段採用 BCEWithLogitsLoss 損失函式和 Adam 最佳化器,並監控訓練過程中的損失變化。模型評估則涵蓋了準確率、精確率、召回率、F1 分數和 ROC-AUC 等多個指標,以全面評估模型效能。此外,本文也探討了使用 K 折交叉驗證方法,更精確地評估模型的泛化能力,並提供程式碼範例說明如何在 PyTorch 中實作 K 折交叉驗證,提升模型評估的可靠性。

糖尿病分類別模型的訓練與評估流程詳解

本章節將探討如何使用 PyTorch 進行糖尿病分類別模型的訓練與評估,並結合 Apache Spark 進行資料預處理。整個流程涵蓋了資料處理、模型訓練、評估指標等多個重要環節。

資料處理流程

首先,我們需要從 Amazon S3 儲存桶中複製所需的資料檔案到本地目錄。這一過程透過 copy_file_from_s3 函式實作,該函式利用 boto3 函式庫建立 S3 客戶端並下載指定的檔案。

def copy_file_from_s3(bucket_name, file_name, local_dir):
    s3 = boto3.client('s3')
    s3.download_file(bucket_name, file_name, f'{local_dir}/{file_name}')

內容解密:

  1. boto3.client('s3'):建立一個 S3 客戶端,用於與 S3 儲存桶互動。
  2. s3.download_file:下載指定的檔案從 S3 儲存桶到本地目錄。

接著,建立一個 Spark 會話,並組態應用程式名稱為「DiabetesClassifier」。然後,呼叫 copy_file_from_s3 函式將名為「diabetes.csv」的檔案從 S3 儲存桶「instance1bucket」複製到本地目錄「/home/ubuntu/airflow/dags/」。

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("DiabetesClassifier").getOrCreate()
copy_file_from_s3('instance1bucket', 'diabetes.csv', '/home/ubuntu/airflow/dags/')

內容解密:

  1. SparkSession.builder.appName("DiabetesClassifier").getOrCreate():建立或取得一個名為「DiabetesClassifier」的 Spark 會話。
  2. copy_file_from_s3:將指定的 CSV 檔案從 S3 下載到本地。

資料預處理

建立 DataPreprocessor 類別的例項,並呼叫其 preprocess 方法對資料進行預處理,生成訓練集和測試集 DataFrames。

from DataPreprocessor import DataPreprocessor

preprocessor = DataPreprocessor(spark, '/home/ubuntu/airflow/dags/diabetes.csv')
train_df, test_df = preprocessor.preprocess()

內容解密:

  1. DataPreprocessor:一個自定義的類別,用於處理資料預處理任務。
  2. preprocess 方法:執行資料預處理並傳回訓練集和測試集。

模型訓練與評估

將訓練集和測試集轉換為 NumPy 陣列,並使用 PyTorch 的 DataLoaderTensorDataset 建立訓練和測試資料集。

import torch
from torch.utils.data import DataLoader, TensorDataset

X_train_np, y_train_np, X_test_np, y_test_np = train_df.to_numpy(), test_df.to_numpy()[:, 0], test_df.to_numpy()[:, 1:], train_df.to_numpy()[:, 0]
train_dataset = TensorDataset(torch.tensor(X_train_np, dtype=torch.float32), torch.tensor(y_train_np, dtype=torch.long))
test_dataset = TensorDataset(torch.tensor(X_test_np, dtype=torch.float32), torch.tensor(y_test_np, dtype=torch.long))
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

內容解密:

  1. TensorDataset:將 NumPy 陣列轉換為 PyTorch 張量資料集。
  2. DataLoader:用於批次載入資料並進行洗牌操作。

例項化糖尿病分類別模型、BCEWithLogitsLoss損失函式和 Adam 最佳化器,並使用 ModelTrainer 類別訓練模型。

from DiabetesClassifierModel import DiabetesClassifierModel
from ModelTrainer import ModelTrainer

model = DiabetesClassifierModel()
criterion = torch.nn.BCEWithLogitsLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
trainer = ModelTrainer(model, criterion, optimizer, train_loader)
trainer.train()

內容解密:

  1. DiabetesClassifierModel:自定義的糖尿病分類別模型。
  2. BCEWithLogitsLoss:二元交叉熵損失函式,適用於二分類別任務。
  3. Adam 最佳化器:用於更新模型引數。

最後,使用 ModelEvaluator 類別評估模型的效能。

from ModelEvaluator import ModelEvaluator

evaluator = ModelEvaluator(model, test_loader)
metrics = evaluator.evaluate()

內容解密:

  1. ModelEvaluator:用於評估模型效能的類別。
  2. evaluate 方法:計算並傳回模型的評估指標。

結果分析

訓練過程輸出了每個 epoch 的損失值,可以觀察到損失值隨著訓練的進行而下降,表明模型的效能在逐步改善。

Epoch Loss
10 0.5899
20 0.4330
...
100 0.3203

評估結果給出了多項指標,包括準確率(Accuracy)、精確率(Precision)、召回率(Recall)、F1 分數和 ROC-AUC 分數。

Metric Value
accuracy 0.7607
precision 0.6585
recall 0.6585
f1 score 0.6585
roC-aUC score 0.8135

指標解析:

  • 準確率:衡量模型正確分類別的樣本比例。
  • 精確率:衡量模型預測為正類別的樣本中,實際為正類別的比例。
  • 召回率:衡量模型正確識別的正類別樣本佔所有正類別樣本的比例。
  • F1 分數:綜合考慮精確率和召回率的指標。
  • ROC-AUC 分數:衡量模型區分正負類別的能力。

這些指標共同反映了模型的整體效能和在不同方面的表現,為進一步最佳化和改進提供了依據。

深度學習模型評估與改進

模型效能分析

在前述章節中,我們探討了一個用於糖尿病預測的深度學習模型的實作與評估。該模型的混淆矩陣輸出如下: [[62 14] [14 27]]

此混淆矩陣提供了模型效能的詳細分解:

  • 真陽性(TP):27
  • 假陽性(FP):14
  • 真陰性(TN):62
  • 假陰性(FN):14

根據這些數值,我們可以計算出各種評估指標:

內容解密:

  1. 準確率(Accuracy) = (TP + TN) / (TP + TN + FP + FN) = (27 + 62) / (27 + 62 + 14 + 14) = 89 / 117 = 0.7607
  2. 精確度(Precision) = TP / (TP + FP) = 27 / (27 + 14) = 27 / 41 = 0.6585
  3. 召回率(Recall) = TP / (TP + FN) = 27 / (27 + 14) = 27 / 41 = 0.6585
  4. F1 分數 = 2 × [(Precision × Recall) / (Precision + Recall)] = 2 × [(0.6585 × 0.6585) / (0.6585 + 0.6585)] = 0.6585

模型效能的影響因素與改進方向

根據模型的評估結果和資料探索階段的觀察,我們發現幾個影響模型效能的關鍵因素,包括類別不平衡、樣本量有限以及潛在的資料品質問題。為此,我們提出了以下改進方向:

資料品質改進

確保資料品質的重要性不言而喻,尤其是在樣本量有限的情況下。資料探索過程中發現的一些異常值,例如 Glucose 特徵的最小值為44,可能指示低血糖,進而引發對資料完整性的質疑。同樣,BloodPressure 的最小值為24,極度偏離正常血壓範圍,表明可能存在資料收集錯誤。此外,DiabetesPedigreeFunction 的最小值為0.078,對於與糖尿病相關的遺傳風險因子來說過低。Pregnancies 特徵的最大值為17,雖然在生物學上是可能的,但極為罕見。這些觀察結果強調了進一步審查和驗證資料可靠性的必要性。

重取樣技術

透過重取樣技術,如對少數類別進行過取樣或對多數類別進行欠取樣,可以幫助平衡資料集中的類別分佈,從而改善模型效能並減少對多數類別的偏見。

資料增強

儘管資料增強通常與影像資料相關,但在 Pima 資料集上仍然可以發揮作用。透過對特徵值進行擾動或引入噪聲來生成額外的合成資料點,可以有效地增加資料集的大小並提高模型的泛化能力。例如,對血糖水平、血壓測量值、BMI 值或其他數值特徵引入小的隨機變化,可以幫助生成多樣化的訓練樣本,防止模型過度依賴特定的值或模式。

遷移學習

雖然遷移學習在非影像任務中不常見,但仍然可以為 Pima 資料集帶來益處。透過利用在相關任務或資料集上預訓練的模型的知識,可以對這些模型進行微調,以適應我們的小型資料集。這種適應過程有助於模型更有效地捕捉相關模式,從而在有限的訓練資料下提高效能。

模型複雜度調整

在處理像 Pima 這樣的小型資料集時,平衡模型複雜度至關重要。過於複雜的模型可能會導致過擬合,因此找到模型複雜度和資料集大小之間的適當平衡非常重要。在資料探索過程中,我們觀察到 Glucose 和 BMI 是最強的預測因子。根據這些特徵構建一個較小的模型可能會提供更好的結果。

資料表示最佳化

有效的資料表示對於像 Pima 這樣的小型資料集至關重要。預處理技術,如特徵提取或降維,可以提高輸入資料的品質並促進深度神經網路中的學習。

超引數調優

進一步調優超引數,如學習率、批次大小和網路架構,可能會改善模型的收斂性和效能。採用正則化、丟棄法或不同的最佳化演算法等高階技術也可能有助於緩解過擬合問題並提高泛化能力。

K-折交叉驗證增強模型評估

K-折交叉驗證是一種可靠的模型效能評估方法,尤其是在資料有限的情況下。透過將資料集分成 K 個折疊,並在這些折疊上迭代訓練和測試過程,可以確保每個資料點都被用於訓練和驗證。這種方法透過在多個子集上平均效能來減少過擬合和欠擬合的風險,從而得到更平衡的評估。此外,K-折交叉驗證還可以最大限度地利用可用資料,幫助進行超引數調優,並解決類別不平衡等問題,最終得到能夠更好地泛化到未見資料的模型。

from sklearn.model_selection import KFold

# 定義折疊數量
k_folds = 5
kfold = KFold(n_splits=k_folds, shuffle=True, random_state=42)

內容解密:

  1. 匯入 KFold:從 Scikit-Learn 中匯入 KFold 類別,這是實作 K-折交叉驗證的關鍵。
  2. 定義折疊數量:設定 K-折交叉驗證的折疊數量為5,並在分割前對資料進行洗牌,使用隨機種子確保可重複性。
  3. KFold 初始化:透過指定 n_splitsshufflerandom_state 引數來初始化 KFold 物件,這些引數控制著交叉驗證的行為。

透過實施 K-折交叉驗證,我們可以獲得對模型效能更可靠的估計,並進一步最佳化模型的泛化能力。

深度學習模型評估與K折交叉驗證實作

在機器學習領域中,模型的評估與驗證是至關重要的環節。為了確保模型的泛化能力,採用K折交叉驗證(K-fold Cross Validation)是一種常見且有效的方法。本篇文章將探討如何使用PyTorch實作深度學習模型的K折交叉驗證,並對Pima糖尿病資料集進行分類別預測。

K折交叉驗證原理與實作步驟

K折交叉驗證是一種統計學方法,用於評估模型的效能。其基本原理是將資料集分成K個子集,每次使用其中一個子集作為測試集,其餘K-1個子集作為訓練集,重複K次,以確保每個子集都被用作測試集一次。

實作步驟:

  1. 資料預處理:首先,需要對資料進行預處理,包括資料載入、缺失值處理、資料標準化等。
  2. 資料集分割:使用Scikit-learn的KFold類別將資料集分割成K個折疊。
  3. 模型初始化與訓練:在每個折疊中,初始化模型、定義損失函式和最佳化器,並進行模型訓練。
  4. 模型評估:使用測試集對模型進行評估,計算準確率、精確率、召回率、F1分數和ROC-AUC分數等指標。
  5. 結果匯總:將每個折疊的評估結果匯總,計算平均值,以獲得模型的整體效能指標。

程式碼實作

import numpy as np
import torch
from torch.utils.data import TensorDataset, DataLoader
from sklearn.model_selection import KFold
from your_module import DiabetesClassifierModel, ModelTrainer, ModelEvaluator  # 匯入自定義的模型和訓練、評估類別

# 假設X_np和y_np是已經預處理好的特徵和標籤的NumPy陣列
k_folds = 5
kfold = KFold(n_splits=k_folds, shuffle=True)

fold_results = []
for fold, (train_idx, test_idx) in enumerate(kfold.split(X_np)):
    logging.info(f"Training fold {fold + 1}/{k_folds}")
    X_train, X_test = X_np[train_idx], X_np[test_idx]
    y_train, y_test = y_np[train_idx], y_np[test_idx]
    
    # 轉換為PyTorch資料集
    train_dataset = TensorDataset(torch.tensor(X_train), torch.tensor(y_train))
    test_dataset = TensorDataset(torch.tensor(X_test), torch.tensor(y_test))
    
    # 建立DataLoader
    train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
    
    # 初始化模型、損失函式和最佳化器
    input_size = X_train.shape[1]
    output_size = 1
    model = DiabetesClassifierModel(input_size, output_size)
    criterion = torch.nn.BCEWithLogitsLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
    
    # 訓練模型
    model_trainer = ModelTrainer(model, criterion, optimizer, train_loader)
    model_trainer.train()
    
    # 評估模型
    model_evaluator = ModelEvaluator(model, test_loader, y_test)
    results = model_evaluator.evaluate()
    fold_results.append(results)

#### 內容解密:
1. **K折交叉驗證迴圈**遍歷每個折疊分割訓練和測試資料
2. **資料轉換**將NumPy陣列轉換為PyTorch的TensorDataset並建立DataLoader以便於批次處理
3. **模型訓練與評估**初始化模型損失函式和最佳化器使用ModelTrainer進行訓練並使用ModelEvaluator評估模型效能
4. **結果儲存**將每個折疊的評估結果儲存在`fold_results`列表中

### 結果匯總與分析

在完成所有折疊的訓練和評估後計算各項指標的平均值以獲得模型的整體效能

```python
avg_accuracy = np.mean([result['accuracy'] for result in fold_results])
avg_precision = np.mean([result['precision'] for result in fold_results])
avg_recall = np.mean([result['recall'] for result in fold_results])
avg_f1 = np.mean([result['f1'] for result in fold_results])
avg_roc_auc = np.mean([result['roc_auc'] for result in fold_results])

logging.info(f"Average Accuracy: {avg_accuracy:.4f}")
logging.info(f"Average Precision: {avg_precision:.4f}")
logging.info(f"Average Recall: {avg_recall:.4f}")
logging.info(f"Average F1 Score: {avg_f1:.4f}")
logging.info(f"Average ROC-AUC Score: {avg_roc_auc:.4f}")

內容解密:

  1. 平均值計算:從fold_results中提取各項指標,並計算平均值。
  2. 日誌記錄:將平均值記錄到日誌中,以便於檢視模型的整體效能。