Python在糖尿病分類問題上尋找具有最佳 ROC AUC 分數和 PR AUC 分數(決策樹、邏輯回歸、KNN、SVM)
- 問題
- 模板
- 解題思路
- 1. 導入必要的庫
- 2. 加載數據
- 3. 劃分訓練集和測試集
- 4. 數據預處理
- 5. 定義算法及其參數
- 6. 存儲算法和對應指標
- 7. 訓練模型并計算指標
- 8. 找出最佳算法
- 9. 輸出結果
- 代碼
問題
我們建議您使用 4 種不同的算法來解決糖尿病數據集上的二元分類問題:
Decision Tree (1) Logistic Regression (2) KNN (3) SVC (4)
您的任務是找到具有最佳 ROC AUC 分數和 PR AUC 分數的算法。作為答案,請指出數字 a b,其中 a 是 ROC AUC 分數方面的最佳算法,b 是 PR AUC 分數方面的最佳算法。
例如,答案 43 將被解釋如下:算法 4(SVM)在 roc_auc_score 方面是最好的,算法 3(KNN)在 pr_auc_score 方面是最好的。
選擇默認設置作為參數。對于 KNN,選擇 k=5。將隨機狀態設置為 42。分成訓練和測試,參數 test_size=0.3。
不要忘記對數據進行額外的預處理,使用 StandardScaler 將其調整到單一比例。
注意
-
請注意,StandardScaler 可能會影響算法的結果。因此,我們建議使用它。
-
當我們將數據分成訓練和測試時,我們必須明白所有算法都必須僅在訓練上進行訓練。訓練期間不使用測試。而且,在現實生活中我們對測試根本就一無所知。因此,StandardScaler 應該僅在 X_train 上進行訓練,并且只應對 X_test 進行變換(而不是 fit_transform)。
模板
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
"""
TODO: make additional imports here
TODO:在此處進行額外導入
"""data = fetch_openml(data_id=42608)
X, y = data['data'].drop(columns='Outcome').values, data['data']['Outcome'].astype(int).valuesX_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42
)"""
In the following part of code specify algorithms with their own parameters by yourself
在下面的代碼部分中,您可以自己指定具有自己參數的算法
"""
tree = DecisionTreeClassifier()
lr = LogisticRegression()
knn = KNeighborsClassifier()
svm = SVC(probability=True)"""
TODO: fit estimators and find best one
TODO:擬合估算器并找到最佳估算器
"""
解題思路
1. 導入必要的庫
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScalerfrom sklearn.metrics import roc_auc_score, auc
from sklearn.metrics import precision_recall_curve
import numpy as np
這些庫的作用分別為:
fetch_openml
:從 OpenML 平臺加載數據集。train_test_split
:把數據集劃分成訓練集和測試集。KNeighborsClassifier
、LogisticRegression
、DecisionTreeClassifier
、SVC
:四種不同的機器學習分類算法。StandardScaler
:對數據進行標準化處理。roc_auc_score
、auc
、precision_recall_curve
:用于計算評估指標。numpy
:用于數值計算。
2. 加載數據
data = fetch_openml(data_id=42608)
X, y = data['data'].drop(columns='Outcome').values, data['data']['Outcome'].astype(int).values
- 借助
fetch_openml
加載 ID 為 42608 的數據集,把特征數據存于X
中,目標變量存于y
中,同時將目標變量轉換為整數類型。 - 特征數據
X
:data['data']
取出的是數據集的特征數據部分,這是一個pandas
的DataFrame
對象。drop(columns='Outcome')
會從特征數據中移除名為Outcome
的列,因為Outcome
通常代表目標變量。.values
把DataFrame
轉換為NumPy
數組,這樣更適合用于機器學習模型的輸入。
- 目標變量
y
:data['data']['Outcome']
提取出Outcome
列的數據,它同樣是一個pandas
的Series
對象。.astype(int)
將目標變量的數據類型轉換為整數類型。.values
把Series
轉換為NumPy
數組。
3. 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42
)
使用 train_test_split
函數按 7:3 的比例將數據集劃分為訓練集和測試集,并且設置隨機種子為 42 以保證結果的可重復性。
4. 數據預處理
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
- 利用
StandardScaler
對訓練集和測試集的數據進行標準化處理,保證所有特征具有相同的尺度。(StandardScaler 是 sklearn 庫中用于數據標準化的類,它可以將數據轉換為均值為 0,標準差為 1 的標準正態分布。) fit_transform
方法結合了fit
和transform
兩個步驟:fit
方法:計算訓練集的均值和標準差。具體來說,它會遍歷訓練集中的每個特征,計算其均值和標準差,這些統計信息會被存儲在scaler
對象中,后續用于對測試集進行轉換。transform
方法:使用計算得到的均值和標準差對訓練集進行標準化處理。標準化的公式為:
x s c a l e d = x ? μ σ x_{scaled} = \frac{x - \mu}{\sigma} xscaled?=σx?μ?
其中, x x x 是原始數據, μ \mu μ 是均值, σ \sigma σ 是標準差。經過標準化處理后,每個特征的均值變為 0,標準差變為 1。
scaler.transform(X_test)
:這里只使用了 transform 方法,而沒有再次使用 fit 方法。這是因為在機器學習中,我們必須使用訓練集的統計信息(均值和標準差)來對測試集進行標準化處理,以保證訓練集和測試集具有相同的尺度。如果對測試集也使用 fit_transform 方法,那么 scaler 會重新計算測試集的均值和標準差,這會導致訓練集和測試集的尺度不一致,從而影響模型的性能。
5. 定義算法及其參數
tree = DecisionTreeClassifier(random_state=42)
lr = LogisticRegression(random_state=42, max_iter=1000)
knn = KNeighborsClassifier(n_neighbors=5)
svm = SVC(probability=True, random_state=42)
定義了四種分類算法,分別是決策樹、邏輯回歸、K 近鄰和支持向量機,同時設置了相應的參數。
6. 存儲算法和對應指標
algorithms = [tree, lr, knn, svm]
roc_aucs = []
pr_aucs = []
把四種算法存于 algorithms
列表中,并且創建兩個空列表 roc_aucs
和 pr_aucs
用于存儲每種算法的 ROC AUC 和 PR AUC 指標。
7. 訓練模型并計算指標
for algorithm in algorithms:algorithm.fit(X_train, y_train)y_score = algorithm.predict_proba(X_test)[:, 1]# 計算ROC AUCroc_auc = roc_auc_score(y_test, y_score)roc_aucs.append(roc_auc)# 計算PR AUCprecision, recall, _ = precision_recall_curve(y_test, y_score)pr_auc = auc(recall, precision)pr_aucs.append(pr_auc)
- 通過循環依次對每種算法進行訓練,接著預測測試集的概率得分,計算 ROC AUC 和 PR AUC 指標,并將結果分別存儲在
roc_aucs
和pr_aucs
列表中。 algorithm.fit(X_train, y_train)
:對當前算法進行訓練,使用訓練集的特征數據 X_train 和對應的目標變量 y_train 來學習特征和目標之間的關系。algorithm.predict_proba(X_test)[:, 1]
:使用訓練好的模型對測試集 X_test 進行預測,得到每個樣本屬于正類的概率。[:, 1] 表示只取屬于正類的概率值
8. 找出最佳算法
best_roc_algorithm = np.argmax(roc_aucs) + 1
best_pr_algorithm = np.argmax(pr_aucs) + 1
運用 np.argmax
函數找出 roc_aucs
和 pr_aucs
列表中最大值的索引,加 1 后得到對應的算法編號。
9. 輸出結果
result = int(str(best_roc_algorithm) + str(best_pr_algorithm))
print(result)
把最佳 ROC AUC 算法編號和最佳 PR AUC 算法編號拼接成一個字符串,再轉換為整數后輸出。
代碼
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScalerfrom sklearn.metrics import roc_auc_score, auc
from sklearn.metrics import precision_recall_curve
import numpy as np# 加載數據
data = fetch_openml(data_id=42608)
X, y = data['data'].drop(columns='Outcome').values, data['data']['Outcome'].astype(int).values# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42
)# 數據預處理
scaler = StandardScaler() # 對數據進行標準化處理,確保所有特征具有相同的尺度。
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)# 定義算法及其參數
tree = DecisionTreeClassifier(random_state=42)
lr = LogisticRegression(random_state=42, max_iter=1000)
knn = KNeighborsClassifier(n_neighbors=5)
svm = SVC(probability=True, random_state=42)# 存儲算法和對應指標
algorithms = [tree, lr, knn, svm]
roc_aucs = []
pr_aucs = []# 訓練模型并計算指標
for algorithm in algorithms:algorithm.fit(X_train, y_train)y_score = algorithm.predict_proba(X_test)[:, 1]# 計算ROC AUCroc_auc = roc_auc_score(y_test, y_score)roc_aucs.append(roc_auc)# 計算PR AUCprecision, recall, _ = precision_recall_curve(y_test, y_score)pr_auc = auc(recall, precision)pr_aucs.append(pr_auc)# 找出最佳算法
best_roc_algorithm = np.argmax(roc_aucs) + 1
best_pr_algorithm = np.argmax(pr_aucs) + 1# 輸出結果
result = int(str(best_roc_algorithm) + str(best_pr_algorithm))
print(result)
輸出:21