這個章節主要為訓練機器學習的基礎應用與訓練流程,從資料載入、訓練模型到模型評估。第四章的練習主要以鳶尾花資料集當作範例,每個小節練習了資料分割、特徵縮放、KNN訓練與評估的各個步驟。Exercise 2則將第四章所學的技術應用於手寫數字辨識,考驗如何將資料集視覺化和訓練簡易KNN模型進行分類評估。兩者皆使用scikit-learn實現標準化處理、模型訓練和效能評估,並透過rich庫增強呈現結果,學習如何將相同原則應用於不同的分類問題。
OS: Windows 11 23H2
CPU: Intel Core i7-13700K
GPU: NVIDIA GeForce RTX 4070 SUPER 12G
RAM: DDR5 64G 5600MT/s
Python Package Manager: uv
Python Version: 3.10.16
Python Package: numpy, pandas, sklearn, rich, seaborn, matplotlib
IDE: Visual Studio Code
為方便查看數據處理前與處理後的差別,故額外使用rich函式庫建立兩個Function格式化印出指定內容。
4.3 The First Application: Iris Flower Classification
Code:
Explanation:
此程式碼主要為載入鳶尾花(Iris)資料集的基本結構。首先從sklearn透過load_iris()載入資料集,然後使用type方法查看其型態,使用keys查看其所有鍵值,使用target_names方法查看所有目標名稱。使用DESCR可察看資料集的詳細介紹,而data與target分別可取得資料集的特徵資料與目標值(標籤)。
透過bincount方法可以計算出每個類別的樣本數量,而feature_names可取得資料集中的每個column名稱。
Discussion:
此程式碼主要在快速熟悉機器學習資料集的基本架構,有助於後續分析。
Result:
4.4 Test Set for Model Assessment
Code:
Explanation:
此程式碼主要將Iris資料集的訓練集與測試集分割。使用train_test_split將原始特徵資料(iris.data)以3:1的比例分離為訓練集與測試集,同時設定random_state為100以確保結果可重現,並使用stratify參數確保分割後各類別樣本比例維持一致。最後使用bincount計算訓練集中各類別的樣本數量。
Discussion:
此方法主要透過分層抽樣確保訓練與測試集具有相同的類別分布,有助於減少樣本偏差。
Result:
4.5 Data Visualization
Code:
Explanation:
此程式碼將Iris資料集的訓練資料轉換為pandas的Dataframe格式。首先將特徵資料X_train轉換為DataFrame並使用特徵名稱作為column標籤,然後將目標分類y_train也轉換為DataFrame並將column命名為class。接著使用concat方法將兩個Dataframe合併,最後使用seaborn的pairplot函數繪製所有特徵間的散點圖,以不同顏色區分不同的花種類別。這邊palette參數主要設定整體圖片的顏色風格。
Discussion:
此程式碼能夠直觀地呈現不同特徵間的關係以及各類別在特徵空間中的分布情況,有助於識別哪些特徵對分類最具區分性。
Result:
4.6 Feature Scaling (Normalization)
Code:
Explanation:
此程式碼使用了兩種特徵標準化的方式。第一種方法是透過手動計算訓練資料的平均值和標準差,然後使用這些統計量對訓練集和測試集進行標準化處理。第二種方法是使用sklearn提供的StandardScaler方法實現相同功能,先透過fit方法在訓練集上擬合計算統計量,再透過transform方法轉換訓練集和測試集。最後將標準化後的資料集使用numpy提供的savez方法以NPZ格式儲存,方便後續使用。
Discussion:
特徵標準化是使不同尺度的特徵具有可比性,能加速梯度下降收斂並改善模型性能。然而,此方法依賴於資料的常態分布假設,對於含異常值的特徵效果有限。此外,標準化參數僅基於訓練集計算,可能無法完全適應測試集的特徵分布,特別是當資料量不足或分布差異較大時。
Result:
4.7 Model Training
Code:
Explanation:
此程式碼使用KNN分類器來訓練已標準化的訓練集。透過使用sklearn提供的KNeighborsClassifier方法,將其簡稱為KNN。接著創建一個KNN分類器實例,並設定參數n_neighbors為3,表示分類時將考慮目標點周圍最近的3個鄰居。最後,使用fit方法將之前標準化處理過的訓練特徵(X_train_scaled)及對應標籤(y_train)餵入模型進行訓練,使模型學習資料的結構特徵。
Discussion:
KNN方法的優點是概念簡單直觀、無需假設資料分布、訓練速度快,且對於局部特徵有良好的適應性。然而其缺點包括預測時計算成本高、對特徵尺度敏感、易受噪音影響等。選擇合適的K值也需要反覆調整,過大或過小都可能導致欠擬合或過擬合。
Result:
4.8 Prediction Using the Trained Model
Code:
Explanation:
此程式碼使用上個小節已訓練好的KNN模型進行預測。首先使用numpy建立了一個測試資料,並使用shape方法確認其形狀。接著使用先前定義的scaler對此測試資料進行標準化處理,保持與訓練集相同的尺度。然後用訓練好的KNN模型對此測試資料進行預測,並透過target_names方法將預測結果轉換為對應的鳶尾花品種名稱。後方兩個部分分為對整個測試集進行預測,以及在單一程式行中同時完成模型訓練和預測兩個步驟的簡潔寫法。
Discussion:
此預測方法能夠直觀地展示模型如何實際應用在新數據上,且確保了新資料與訓練資料使用一致的標準化處理。
Result:
4.9 Model Evaluation (Error Estimation)
Code:
Explanation:
此程式碼計算KNN模型在測試集上的預測錯誤率和準確率。首先通過比較預測結果與真實標籤是否不同,創建了一個布林值陣列errors,然後透過將錯誤數量除以總樣本數來計算錯誤率。接著使用sklearn提供的accuracy_score方法計算準確率。而另外一種測試準確率的方法是直接使用KNN模型的score方法計算在測試集上的準確率,這個方法與accuracy_score的功能相同。
Discussion:
此方法提供了兩種計算模型性能的方式,便於相互驗證結果的一致性。然而,單純的準確率指標在類別不平衡的情況下可能產生錯誤。
Result:
Exercise 2-1:
Code:
Explanation:
這段程式碼首先透過load_digits()方法載入手寫數字的資料集,並將資料分配給data變數,對應標籤分配給target變數。透過matplotlib提供的plt.figure方法創建一個12 X 12大小的視窗,並使用subplot方法創建一個10 X 10的圖形網格。對於每個樣本,透過reshape將一維特徵向量重塑為8×8的矩陣(圖片),並使用seaborn提供的heatmap方法繪製圖片,其中的cmap參數為設定熱度圖的顏色主題,而透過將cbar設為False可將每個圖片右方的熱度條隱藏,再來透過plt.axis方法將座標軸顯示設為關閉。最後透過subplots_adjust方法中的wspace與hspace調整每個子圖之間的間距,最後使用plt.show()顯示結果圖片。
Discussion:
此視覺化方法可以同時呈現多個樣本,並快速比較不同數字的形態特徵,有助於理解資料集的結構和特徵分佈。
Result:
Exercise 2-2:
Code:
Explanation:
這段程式碼首先使用sklearn提供的train_test_split方法將資料分為訓練集和評估集,比例為75% : 25%,random_state設為42,並使用stratify參數確保各類別在分割後的資料集中保持原有分佈。
接著透過StandardScaler方法將訓練資料標準化,並使用transform方法將相同的縮放參數應用於評估資料集。
透過mean與std方法計算了評估資料的平均值和標準差。
然後建立一個KNN分類器,設定n_neighbors值為3,並用標準化後的訓練資料進行模型訓練,最後使用knn.score在評估集上計算準確率,衡量模型效能。
Discussion:
此程式碼透過資料標準化減少特徵間的尺度差異,提高模型效能,並使用stratify確保訓練和評估集中類別分佈一致,使評估結果更可靠。而KNN算法實作簡單且不需假設資料分佈。然而,其限制在於KNN在大型資料集上計算成本高且記憶體消耗大、對異常值和不相關特徵敏感、n_neighbors的選擇需依靠經驗或交叉驗證等。
Result:
Difficulties Encountered and Solutions
1. 同時印出100張資料集中的圖片處理
Difficulties:如何透過matplotlib與seaborn合作印出100張資料集中的圖片並具有指定排版設定。
Solution:如何首先建立一個figure可以放置指定數量的圖,並透過for迴圈將matplotlib的plt.subplot方法與seaborn的heatmap配合印出指定數量的圖片,其中plt.subplot(10, 10, i+1)中,前兩個10代表長與寬各有幾張圖,最後一個代表目前圖片在網格中的位置(從 1 開始編號)。
References
[1] Supervised Learning in Practice: the First Application Using Scikit-Learn, Amin Zollanvari, Springer Cham, 2023, ISBN: 9783031333415
[2] 機器學習入門:使用Scikit-Learn與TensorFlow, 黃建庭, 碁峰, 2021, ISBN: 9786263240285
[3] 精通機器學習:使用Scikit-Learn, Keras與TensorFlow(第三版), Aurélien Géron, 歐萊禮, 2024, ISBN: 9786263246676
[4] scikit-learn 機器學習實戰, 鄧立國 郭雅秋 陳子堯 鄧淇文, 清華大學, 2022, ISBN: 9787302604396
[5] Python數據分析與可視化實踐, 孫玉林、余本國, 清華大學出版社, 2024, ISBN: 9787302673576