Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM)
问题
我们建议您使用 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).values
X_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 StandardScaler
from 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 AUC
roc_auc = roc_auc_score(y_test, y_score)
roc_aucs.append(roc_auc)
# 计算PR AUC
precision, 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 StandardScaler
from 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 AUC
roc_auc = roc_auc_score(y_test, y_score)
roc_aucs.append(roc_auc)
# 计算PR AUC
precision, 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