背景
wine
葡萄酒數據集,提供了對三種不同品種的意大利葡萄酒的化學分析結果
主要特點:
- 數據集規模:總共有 178 個樣本
- 特征數量:每個樣本有 13 個化學特征,包括酒精、蘋果酸、灰分、鎂等
- 類別數量:總共有 3 個類別,分別代表三種不同的葡萄酒品種
步驟
- 加載數據集
- 拆分訓練集、測試集
- 數據預處理(標準化)
- 選擇模型
- 模型訓練(擬合)
- 測試模型效果
- 評估模型
分析方法
對數據集使用 7 種分類方法進行分析
- K 近鄰(K-NN)
- 決策樹
- 支持向量機(SVM)
- 邏輯回歸
- 隨機森林
- 樸素貝葉斯
- 多層感知機(MLP)
分析結果
不同模型的 ROC 及 AUC
不同模型效果
--- 模型訓練與評估 ------ 正在訓練 K近鄰 (K-NN) 模型 ---
K近鄰 (K-NN) 模型的準確率: 0.9630
K近鄰 (K-NN) 模型的分類報告:precision recall f1-score supportclass_0 0.95 1.00 0.97 19class_1 1.00 0.90 0.95 21class_2 0.93 1.00 0.97 14accuracy 0.96 54macro avg 0.96 0.97 0.96 54
weighted avg 0.97 0.96 0.96 54--- 正在訓練 決策樹 模型 ---
決策樹 模型的準確率: 0.9630
決策樹 模型的分類報告:precision recall f1-score supportclass_0 0.95 0.95 0.95 19class_1 0.95 1.00 0.98 21class_2 1.00 0.93 0.96 14accuracy 0.96 54macro avg 0.97 0.96 0.96 54
weighted avg 0.96 0.96 0.96 54--- 正在訓練 支持向量機 (SVM) 模型 ---
支持向量機 (SVM) 模型的準確率: 0.9815
支持向量機 (SVM) 模型的分類報告:precision recall f1-score supportclass_0 1.00 1.00 1.00 19class_1 0.95 1.00 0.98 21class_2 1.00 0.93 0.96 14accuracy 0.98 54macro avg 0.98 0.98 0.98 54
weighted avg 0.98 0.98 0.98 54--- 正在訓練 邏輯回歸 模型 ---
邏輯回歸 模型的準確率: 0.9815
邏輯回歸 模型的分類報告:precision recall f1-score supportclass_0 1.00 1.00 1.00 19class_1 1.00 0.95 0.98 21class_2 0.93 1.00 0.97 14accuracy 0.98 54macro avg 0.98 0.98 0.98 54
weighted avg 0.98 0.98 0.98 54--- 正在訓練 隨機森林 模型 ---
隨機森林 模型的準確率: 1.0000
隨機森林 模型的分類報告:precision recall f1-score supportclass_0 1.00 1.00 1.00 19class_1 1.00 1.00 1.00 21class_2 1.00 1.00 1.00 14accuracy 1.00 54macro avg 1.00 1.00 1.00 54
weighted avg 1.00 1.00 1.00 54--- 正在訓練 樸素貝葉斯 模型 ---
樸素貝葉斯 模型的準確率: 1.0000
樸素貝葉斯 模型的分類報告:precision recall f1-score supportclass_0 1.00 1.00 1.00 19class_1 1.00 1.00 1.00 21class_2 1.00 1.00 1.00 14accuracy 1.00 54macro avg 1.00 1.00 1.00 54
weighted avg 1.00 1.00 1.00 54--- 正在訓練 多層感知器 (MLP) 模型 ---
多層感知器 (MLP) 模型的準確率: 0.9815
多層感知器 (MLP) 模型的分類報告:precision recall f1-score supportclass_0 1.00 1.00 1.00 19class_1 1.00 0.95 0.98 21class_2 0.93 1.00 0.97 14accuracy 0.98 54macro avg 0.98 0.98 0.98 54
weighted avg 0.98 0.98 0.98 54
代碼
from sklearn.datasets import load_winefrom sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.neural_network import MLPClassifierfrom sklearn.metrics import accuracy_score, classification_report, roc_curve, auc
from sklearn.preprocessing import label_binarizeimport matplotlib.pyplot as plt
import numpy as np# 設置 Matplotlib 字體以正確顯示中文
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Zen Hei', 'STHeiti', 'Arial Unicode MS']
# 解決保存圖像時負號'-'顯示為方塊的問題
plt.rcParams['axes.unicode_minus'] = False def perform_wine_analysis():"""使用 scikit-learn 對葡萄酒數據集進行全面的分析。該函數包含數據加載、預處理、模型訓練、評估和 ROC/AUC 可視化。"""print("--- 正在加載葡萄酒數據集 ---")# 加載葡萄酒數據集wine = load_wine()# 獲取數據特征和目標標簽X = wine.datay = wine.targettarget_names = wine.target_namesprint("\n--- 數據集概覽 ---")print(f"數據形狀: {X.shape}")print(f"目標名稱: {target_names}")# 將數據集劃分為訓練集和測試集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)print("\n--- 數據劃分結果 ---")print(f"訓練集形狀: {X_train.shape}")print(f"測試集形狀: {X_test.shape}")# 數據標準化print("\n--- 正在對數據進行標準化處理 ---")scaler = StandardScaler()X_train_scaled = scaler.fit_transform(X_train)X_test_scaled = scaler.transform(X_test)# 定義并訓練多個分類器模型models = {"K近鄰 (K-NN)": KNeighborsClassifier(n_neighbors=5),"決策樹": DecisionTreeClassifier(random_state=42),"支持向量機 (SVM)": SVC(kernel='rbf', C=1.0, random_state=42, probability=True),"邏輯回歸": LogisticRegression(random_state=42, max_iter=10000),"隨機森林": RandomForestClassifier(random_state=42),"樸素貝葉斯": GaussianNB(),"多層感知器 (MLP)": MLPClassifier(random_state=42, max_iter=10000)}print("\n--- 模型訓練與評估 ---")for name, model in models.items():print(f"\n--- 正在訓練 {name} 模型 ---")model.fit(X_train_scaled, y_train)y_pred = model.predict(X_test_scaled)accuracy = accuracy_score(y_test, y_pred)report = classification_report(y_test, y_pred, target_names=target_names)print(f"{name} 模型的準確率: {accuracy:.4f}")print(f"{name} 模型的分類報告:\n{report}")print("\n--- ROC 曲線和 AUC 對比 ---")num_models = len(models)cols = 3rows = (num_models + cols - 1) // colsfig, axes = plt.subplots(rows, cols, figsize=(18, 6 * rows))axes = axes.flatten()# 將多分類標簽二值化,用于 ROC 曲線計算y_test_bin = label_binarize(y_test, classes=np.arange(len(target_names)))for i, (name, model) in enumerate(models.items()):ax = axes[i]# 獲取預測概率if hasattr(model, "predict_proba"):y_score = model.predict_proba(X_test_scaled)else:y_score = model.decision_function(X_test_scaled)# 計算每個類別的 ROC 曲線和 AUCfpr = dict()tpr = dict()roc_auc = dict()for j in range(len(target_names)):fpr[j], tpr[j], _ = roc_curve(y_test_bin[:, j], y_score[:, j])roc_auc[j] = auc(fpr[j], tpr[j])# 計算微平均 ROC 曲線和 AUCfpr["micro"], tpr["micro"], _ = roc_curve(y_test_bin.ravel(), y_score.ravel())roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])# 繪制所有類別的 ROC 曲線并填充for j in range(len(target_names)):ax.plot(fpr[j], tpr[j], label=f'類別 {target_names[j]} (AUC = {roc_auc[j]:.2f})', alpha=0.7)ax.fill_between(fpr[j], tpr[j], alpha=0.1)# 繪制微平均 ROC 曲線ax.plot(fpr["micro"], tpr["micro"], label=f'微平均 (AUC = {roc_auc["micro"]:.2f})',color='deeppink', linestyle=':', linewidth=4)# 繪制對角線 (隨機猜測)ax.plot([0, 1], [0, 1], 'k--', lw=2)# 設置圖表屬性ax.set_xlim([0.0, 1.0])ax.set_ylim([0.0, 1.05])ax.set_xlabel('假正率 (FPR)')ax.set_ylabel('真正率 (TPR)')ax.set_title(f'{name} - ROC 曲線')ax.legend(loc="lower right", fontsize='small')ax.grid(True)# 隱藏未使用的子圖邊框for j in range(num_models, len(axes)):axes[j].axis('off')plt.tight_layout()plt.show()if __name__ == "__main__":perform_wine_analysis()