序言
比较多种不同机器学习算法的性能非常重要。我们将了解如何创建测试工具进行比较Python中使用scikit-learn的多种不同的机器学习算法。我们可以用这个测试工具作为自己的机器学习问题的模板,并添加更多不同的要比较的算法。通过本文后,我们将了解:
1. 如何制定一个实验直接比较机器学习算法。
2. 一个可重用的模板,用于评估一个数据集上多个算法性能。
3. 在比较算法性能时如何报告和可视化结果。
选择最佳的机器学习模型
当我们在处理一个机器学习项目时,通常会有多个好的模型可以选择。每个模型都将具有不同的性能特征。使用像交叉验证这样的重采样方法,可以估计每个模型在未见数据上的可能准确性。我们需要能够使用这些估计来从创建的一系列模型中选择一两个最佳模型。
当有一个新数据集时,使用不同的技术可视化数据是一个好主意,以便从不同的角度查看数据。同样的原则适用于模型选择。我们应该使用多种方法来查看机器学习算法的估计准确性,以便选择一两个算法进行最终确定。一种这样做的方式是使用可视化方法来显示模型准确性的分布的平均准确性、方差和其他特性。
比较机器学习算法
确保每个算法在相同的数据上以相同的方式进行评估,是公正比较机器学习算法的关键。我们可以通过迫使每个算法在一个一致的测试工具上进行评估来实现这一点。在下面的例子中,对单个数据集进行了六个不同的分类算法的比较:
-
逻辑回归 (Logistic Regression, LR)
-
线性判别分析 (Linear Discriminant Analysis, LDA)
-
k-最近邻 (k-Nearest Neighbors, KNN)
-
分类和回归树 (Classification and Regression Trees, CART)
-
朴素贝叶斯 (Naive Bayes)
-
支持向量机 (Support Vector Machines, SVM)
数据集是皮马印第安人糖尿病发病问题。该问题具有两个类别和八个数值输入变量,它们的尺度各不相同。使用10折交叉验证过程来评估每个算法,重要的是使用相同的随机种子配置,以确保对训练数据进行相同的划分,并且每个算法都以精确相同的方式进行评估。每个算法都有一个简短的名称,这对于之后总结结果很有用。
案例演示代码
# coding: utf-8
"""
该Python脚本用于加载数据,对数据进行预处理,并通过交叉验证比较不同机器学习模型的准确性
主要步骤包括:
1. 加载数据
2. 数据预处理(如缺失值删除,特征标准化)
3. 评估多个机器学习模型的性能
"""
# 导入必要的库
from pathlib import Path # 用于处理文件路径
import pandas as pd # 用于数据处理和分析
import matplotlib.pyplot as plt # 用于数据可视化
from sklearn.preprocessing import StandardScaler # 用于数据标准化
from sklearn.model_selection import KFold, cross_val_score # 用于交叉验证
from sklearn.linear_model import LogisticRegression # 逻辑回归模型
from sklearn.tree import DecisionTreeClassifier # 决策树模型
from sklearn.neighbors import KNeighborsClassifier # K近邻模型
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # 线性判别分析
from sklearn.naive_bayes import GaussianNB #高斯朴素贝叶斯模型
from sklearn.svm import SVC # 支持向量机模型
# 定义文件路径
filename = Path(__file__).parent / 'data/pima-indians-diabetes.csv'
# 加载数据
data = pd.read_csv(filename)
# 重命名列名以提高可读性
column_names = {'Pregnancies': 'pregnant_times',
'Glucose': 'glucose',
'BloodPressure': 'blood_pressure',
'SkinThickness': 'skin_thickness',
'Insulin': 'insulin',
'BMI': 'BMI',
'DiabetesPedigreeFunction': 'DPF',
'Age': 'age',
'Outcome': 'outcome'}
data.rename(columns=column_names, inplace=True)
# 删除含有缺失值的行以进行数据清洗
data.dropna(inplace=True)
# 对特征数据进行标准化处理
scaler = StandardScaler()
X = scaler.fit_transform(data.iloc[:, :-1])
# 提取目标变量
Y = data.iloc[:, -1]
print(X.shape, Y.shape)
# 定义要评估的模型及其名称
models = [('LR', LogisticRegression(random_state=0, max_iter=1000)),
('LDA', LinearDiscriminantAnalysis()),
('KNN', KNeighborsClassifier()),
('CART', DecisionTreeClassifier()),
('NB', GaussianNB()),
('SVC', SVC())]
# 初始化存储模型结果和名称的列表
results, names = [], []
scoring = 'accuracy' # 定义评估指标为准确性
# 遍历模型集合评估每个模型的性能
"""
对提供的模型集合进行交叉验证,计算并打印每个模型的平均分数和标准差。
参数:
- models: 模型迭代器,每个元素是一个名称和模型的元组。
- X: 特征数据集,用于模型的训练。
- Y: 目标数据集,对应于特征数据的标签。
- scoring: 用于评估模型的评分方法。
返回值:
- 无。该函数主要为了打印每个模型的性能指标。
"""
for name, model in models:
# 初始化10折交叉验证
kfold = KFold(n_splits=10, shuffle=True, random_state=7)
# 计算模型的交叉验证分数
cv = cross_val_score(model, X, Y, cv=kfold, scoring=scoring)
# 将结果添加到结果列表中
results.append(cv)
# 添加模型名称到名称列表中
names.append(name)
# 打印模型名称、平均分数和标准差
print('%s: %f (%f)' % (name, cv.mean(), cv.std()))
# 绘制模型性能比较的箱线图
"""
生成一个包含算法比较的箱线图。
参数:
- results: 一个列表的列表,包含了要比较的算法的各个数据点。
- names: 一个列表,包含了对应算法的标签名称。
返回值:
- 无。该函数直接展示图形并不返回任何对象。
"""
# 创建一个新的图形
fig = plt.figure()
# 设置图形的主标题
fig.suptitle('Algorithm Comparison')
# 添加一个子图,并返回其轴对象
ax = fig.add_subplot(111)
# 在当前子图上绘制箱线图
plt.boxplot(results)
# 设置x轴的标签
ax.set_xticklabels(names)
# 显示绘制的图形
plt.show()
#输出(略)