💥 项目专栏:sklearn实现经典机器学习算法(附代码+原理介绍)
文章目录
前言
🌟 哈喽,亲爱的小伙伴们,你们知道吗?最近我们的粉丝群里有好多小可爱私信问我一些关于决策树、逻辑回归等机器学习的超级有趣的问题呢!🌈 为了让大家更轻松地理解,我决定开一个超可爱的专栏,叫做 用sklearn玩转机器学习
,特别适合机器学习的小新手哦!
🍬 在这个专栏里,我们会用sklearn这个超级强大的魔法工具来实现各种闪闪发光的机器学习算法!不用担心难度哦,我会用最简单、最可爱的方式,带领大家一起探索算法的神秘世界!✨
🎈 适合哪些小伙伴加入呢?当然是对机器学习感兴趣的小新手们,还有那些刚开始接触sklearn的可爱宝宝们!我们会一起学习如何用sklearn轻松实现那些看起来好厉害的机器学习算法,让新手小白也能快快乐乐地理解它们哦!
🌸 在这个专栏里,大家可以看到用sklearn实现的机器学习算法,我们不仅仅是理论学习哦,每一篇文章都会附带 完整的代码+超级可爱的原理讲解
,让大家在轻松愉快的氛围中一起学习成长呢!🌼 快来加入我们的学习大冒险吧!
🚨 我的项目环境:
- 平台:Windows11
- 语言环境:Python 3.10
- 编译器:Jupyter Lab、PyCharm
- scikit-learn:1.2.1
- Pandas:1.3.5
- Numpy:1.19.3
- Scipy:1.7.3
- Matplotlib:3.1.3
💥 项目专栏:sklearn实现经典机器学习算法(附代码+原理介绍)
一、Ridge Classifier算法背景
🌟 岭回归分类器(Ridge Classifier)入门 🌟
在这篇文章中,我们将深入探索岭回归分类器——一种在统计学和机器学习领域广泛应用的算法,尤其适用于处理具有多重共线性特征的分类问题。岭回归分类器以其处理共线性问题的能力和强大的稳健性而著称,是解决线性分类问题的重要工具。
📖 起源与背景
- 发展历史:岭回归由统计学家Hoerl和Kennard于1970年代初期提出,起初用于解决线性回归中的共线性问题。
- 算法演进:从最初的线性回归问题扩展到分类任务,形成了岭回归分类器。
🌐 应用领域
- 生物统计:用于基因数据分析,处理高维数据集。
- 金融分析:用于投资风险评估和市场趋势预测。
- 工程领域:用于系统设计优化和可靠性分析。
- 社会科学:用于调查研究和预测模型。
✨ 特点
- 处理共线性:有效解决特征之间高度相关的问题,提高模型稳定性。
- 灵活应用:适用于多种数据集,特别是在特征数量众多时。
尽管在处理非线性数据方面有其局限性,岭回归分类器因其在处理特定类型问题上的优越性,在实际应用中仍然是一个重要的工具。
💡 本篇亮点
在本篇文章中,我们将使用 sklearn 实现 Ridge Classifier
。这篇文章旨在为初学者提供一个详细的实操指南,帮助他们理解和应用岭回归分类器来处理分类问题,特别是在面对具有共线性特征的数据集时。
二、算法原理
🌟 岭回归分类器:处理共线性的高效解决者 🌟
岭回归分类器是一种专门用于处理具有多重共线性特征的分类问题的统计方法,非常适用于高维数据集的情况。
🧩 基本原理
-
核心:岭回归分类器的关键在于它通过引入L2正则化项来解决共线性问题。这意味着在损失函数中添加了参数的平方和,以防止参数值过大,从而提高模型的泛化能力。
公式表达如下:
Minimize: ∣ ∣ Y − X β ∣ ∣ 2 + α ∣ ∣ β ∣ ∣ 2 \text{Minimize: } ||Y - X\beta||^2 + \alpha||\beta||^2 Minimize: ∣∣Y−Xβ∣∣2+α∣∣β∣∣2
其中, ∣ ∣ Y − X β ∣ ∣ 2 ||Y - X\beta||^2 ∣∣Y−Xβ∣∣2 是普通最小二乘法的损失函数, α ∣ ∣ β ∣ ∣ 2 \alpha||\beta||^2 α∣∣β∣∣2 是L2正则化项, α \alpha α 是正则化系数。
📊 参数估计
- 正则化强度( α \alpha α):通过调整正则化强度,岭回归分类器可以在偏差与方差之间找到平衡,从而优化模型性能。
📈 模型评估
- 准确率:表示模型正确分类的比例。
- 混淆矩阵:展示了模型预测的真实类别与预测类别的对比情况。
- 分类报告:提供精确度、召回率等详细指标。
⚙️ 优化
- 防止过拟合:通过调整正则化参数 α \alpha α,岭回归分类器能有效避免过拟合,特别是在特征数量较多的情况下。
🧪 模型假设
- 线性关系:假设自变量与分类决策之间存在线性关系。
- 多重共线性:适用于自变量之间存在多重共线性的数据集。
🌐 应用价值
岭回归分类器在处理高维数据集和具有共线性的特征时展示了其特有的价值。由于其强大的稳健性和有效的正则化特性,它在金融、生物统计和工程等领域的实际应用中非常受欢迎。
三、算法实现
3.1 导包
在这段代码中,导入的几个Python包及其模块都在机器学习和数据可视化领域有重要的应用。下面是对它们的简要介绍:
-
warnings
- 作用:用于控制警告的显示。在机器学习中,某些操作可能会触发警告,例如数据类型不一致、算法未完全收敛等。
warnings
模块可以用来抑制这些警告的显示。 - 使用场景:通常用于忽略不影响程序运行的警告信息。
- 作用:用于控制警告的显示。在机器学习中,某些操作可能会触发警告,例如数据类型不一致、算法未完全收敛等。
-
matplotlib.pyplot
- 作用:
matplotlib.pyplot
是matplotlib
库中一个用于绘制各种静态、动态、交互式图表的模块。 - 使用场景:广泛用于数据可视化,如绘制折线图、柱状图、散点图等。
- 作用:
-
numpy
- 作用:
numpy
是 Python 的一个科学计算库,提供了大量数学函数操作,特别擅长处理数组和矩阵。 - 使用场景:在机器学习中,经常用来进行数据的各种数值操作,如数组运算、线性代数、随机数生成等。
- 作用:
-
seaborn
- 作用:
seaborn
是基于matplotlib
的一个数据可视化库,提供了更高级的界面,用于绘制更加美观的统计图表。 - 使用场景:用于创建更复杂的图表,如热图、时间序列图等。
- 作用:
-
sklearn.datasets
- 作用:
sklearn.datasets
模块包含了许多用于实验的数据集。 - 使用场景:常用于加载标准数据集,例如在这段代码中加载鸢尾花(iris)数据集进行模型训练和测试。
- 作用:
-
sklearn.linear_model
- 作用:
sklearn.linear_model
模块包含了多种线性模型,包括回归、岭回归、逻辑回归等。 - 使用场景:在这段代码中,使用
RidgeClassifier
来构建分类模型。
- 作用:
-
sklearn.metrics
- 作用:提供了一系列用于评估预测模型性能的度量方法,如准确率、混淆矩阵等。
- 使用场景:用于评估分类模型的性能。
-
sklearn.model_selection
- 作用:包含了模型选择和评估的工具,如数据集分割、交叉验证和超参数优化。
- 使用场景:用于分割数据集、交叉验证以及网格搜索优化模型参数。
-
sklearn.preprocessing
- 作用:提供了数据预处理功能,如特征标准化、归一化等。
- 使用场景:用于标准化特征,确保模型能够更好地学习和理解数据集。
import warnings
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from sklearn.datasets import load_iris
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
3.2 加载数据集
这段代码是用于加载和预处理数据集的。具体步骤如下:
-
加载数据集:
iris = load_iris()
:这一行代码使用sklearn.datasets
模块中的load_iris()
函数来加载著名的鸢尾花(Iris)数据集。鸢尾花数据集是机器学习和统计分类中常用的一个入门级数据集,包含150个样本,分为三个类别,每类50个数据点。
-
提取特征和目标变量:
X, y = iris.data, iris.target
:这里将数据集分为特征集X
和目标变量y
。iris.data
包含了数据集的特征,即花的各种测量值;iris.target
包含了目标变量,即花的种类。
-
特征选择:
X = X[:, :2]
:这行代码将特征集X
缩减到前两个特征。鸢尾花数据集原本有四个特征(花萼长度、花萼宽度、花瓣长度和花瓣宽度),但这里仅选择了前两个(花萼长度和花萼宽度)。这种选择有时是为了简化问题,或是为了方便在二维空间中可视化数据。
通过这样的处理,您可以在后续步骤中使用这些数据来训练机器学习模型,尤其是当您关注的问题或可视化只需要两个维度时。
# 2. 加载数据集
iris = load_iris()
X, y = iris.data, iris.target
X = X[:, :2]
3.3 数据预处理
在这段代码中,我们进行了数据预处理的一个关键步骤:特征标准化。标准化是一种使数据符合标准正态分布(即均值为0,方差为1)的技术。这通常是机器学习中的一个重要步骤,因为许多算法的性能在标准化数据上会更好。具体来说,我们使用了 StandardScaler
类从 sklearn.preprocessing
包中。
-
实例化 StandardScaler:首先,我们创建了
StandardScaler
类的一个实例,命名为scaler
。这个实例将用于后续的标准化过程。 -
拟合并转换数据:通过调用
scaler.fit_transform(X)
,我们对数据集X
进行了拟合和转换。在这一步中,fit
方法会计算数据集X
的均值和标准差,然后transform
方法会使用这些参数将每个特征转换为标准正态分布。换句话说,对于每个特征,算法都会减去其均值并除以其标准差。
这个过程有助于消除不同特征之间的尺度差异,使得模型对于所有特征的敏感度相同。特别是当特征的尺度相差很大时,标准化是非常重要的步骤。
# 3. 数据预处理
# 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
3.4 划分训练集、测试集
在这段代码中,我们使用了 train_test_split
函数,这是 sklearn.model_selection
模块中的一个功能,用于将数据集划分为训练集和测试集。这是机器学习项目中的一个关键步骤,目的是确保模型可以在未见过的数据上进行测试,从而评估其泛化能力。
具体来说,train_test_split
接受几个参数:X_scaled
和 y
分别是经过预处理(如标准化)的特征数据和对应的标签。参数 test_size=0.3
指定了测试集应占总数据集的30%,这意味着剩余的70%将用作训练集。最后,random_state=42
确保了每次代码运行时划分的方式都相同,这有助于实验的可重复性。通过这种方式,我们可以确保模型在训练时有足够的数据,并且在测试时有代表性的数据来验证模型性能。
# 5. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
3.5 定义Ridge Classifier模型
在这部分代码中,我们定义了岭回归分类器(Ridge Classifier),这是一个用于解决分类任务的统计方法。这里使用的是 RidgeClassifier
类,它来自于Python的scikit-learn库。与逻辑回归不同,岭回归分类器通过引入L2正则化项来解决特征间可能存在的多重共线性问题,使其在处理具有高度相关特征的数据集时更加稳健。
L2正则化对模型参数的平方和进行惩罚,这有助于减少模型复杂度并提高其泛化能力。正则化强度由参数 alpha
控制,其值越大,正则化越强。在选择适当的 alpha
值时,岭回归分类器可以在偏差和方差之间找到一个良好的平衡,从而在训练集和未见数据上都取得较好的性能。
岭回归分类器特别适合于那些特征数量大于样本数量的情况,或者当各个特征之间存在一定程度的相关性时。通过定义这个模型,我们接下来将在训练数据上训练它,并用它来预测测试数据的类别。它在处理诸如鸢尾花数据集这样的相对较小且可能具有特征相关性的数据集时,表现尤为出色。
# 6. 定义RidgeClassifier模型和参数网格
model = RidgeClassifier()
以下是以表格形式展示的 sklearn
中 RidgeClassifier
类的常用参数,包括参数名称、描述以及可选的值或类型:
参数 | 描述 | 可选的值/类型 |
---|---|---|
alpha | 正则化强度,较大的值表示更强的正则化。 | 正浮点数 |
fit_intercept | 是否计算该模型的截距。如果设置为 False,则不会在计算中使用截距(即数据被假设已经居中)。 | 布尔值 |
normalize | 在拟合前是否对数据进行归一化处理。 | 布尔值 |
copy_X | 是否复制X值,否则它可能被覆盖。 | 布尔值 |
max_iter | 求解器进行迭代的最大次数。 | 正整数或 None |
tol | 解的精度(求解器停止的标准)。 | 正浮点数 |
class_weight | 类别权重,用于处理不平衡类别分布的情况。 | 字典、‘balanced’ 或 None |
solver | 用于计算岭回归系数的算法。 | ‘auto’, ‘svd’, ‘cholesky’, ‘lsqr’, ‘sparse_cg’, ‘sag’, ‘saga’ |
random_state | 当solver 使用’sag’或’saga’时,用于随机数生成器的种子。 | 整数或 None |
RidgeClassifier
适用于处理分类问题,特别是在特征间存在多重共线性时。它通过在最小二乘法的损失函数中加入L2正则化项(参数的平方和)来减少模型的复杂度,从而提高模型的稳定性和泛化能力。通过上述参数的灵活运用,可以在保持模型简单性的同时提高其预测性能。
3.6 网格搜索
这段代码使用了网格搜索(Grid Search)来优化 RidgeClassifier
模型的参数。具体步骤和功能如下:
-
定义参数网格:
- 代码中定义了一个名为
param_grid
的字典,用于指定希望优化的参数及其候选值。在这个例子中,我们关注的参数是alpha
,这是岭回归中控制正则化强度的参数。alpha
的候选值被设置为[0.1, 1, 10, 100]
。
- 代码中定义了一个名为
-
初始化和使用 GridSearchCV:
GridSearchCV
是 scikit-learn 提供的一个工具,它可以自动进行交叉验证,以确定最佳参数组合。它需要几个关键参数:模型(model
)、参数网格(param_grid
)、交叉验证折数(cv=5
表示五折交叉验证)和是否返回训练得分(return_train_score=True
)。grid_search.fit(X_train, y_train)
这一行代码启动了网格搜索过程,它会在给定的参数网格中尝试不同的参数组合,并评估每种组合的性能。
-
获取最佳参数和模型:
- 在网格搜索完成后,
grid_search.best_params_
提供了表现最佳的参数组合。这有助于理解哪个alpha
值在当前数据集上效果最好。 grid_search.best_estimator_
则是使用最佳参数设置好的模型实例,即best_model
。这个模型已经被训练并准备好用于预测或进一步分析。
- 在网格搜索完成后,
总的来说,这段代码非常重要,因为它通过自动化的网格搜索为模型提供了最佳的参数组合,这有助于提高模型的准确性和泛化能力。
param_grid = {
'alpha': [0.1, 1, 10, 100] # 正则化强度
}
# 使用网格搜索,寻找最佳参数(包含训练得分)
grid_search = GridSearchCV(model, param_grid, cv=5, return_train_score=True)
grid_search.fit(X_train, y_train)
# 7. 网格搜索后的最佳参数和模型
print("最佳参数:", grid_search.best_params_)
best_model = grid_search.best_estimator_
3.7 评估指标
下面代码用于评估经过网格搜索优化后的 RidgeClassifier
模型在训练集和测试集上的性能。
8. 计算并打印精度
-
计算精度:
accuracy_score(y_train, best_model.predict(X_train))
计算了模型在训练集上的精度。精度是正确分类的样本数除以总样本数。accuracy_score(y_test, best_model.predict(X_test))
计算了模型在测试集上的精度。
-
打印精度:
- 使用
print
语句,分别打印出训练集和测试集上的精度。精度用四位小数点表示,这提供了模型性能的直观理解。
- 使用
9. 打印模型评估指标
-
生成预测:
best_model.predict(X_train)
和best_model.predict(X_test)
分别生成了训练集和测试集的预测值。
-
评估指标:
- 使用
classification_report
函数,生成了一个包含主要分类指标的报告。这包括每个类别的精确度、召回率、F1分数等。
- 使用
-
打印评估报告:
- 分别为训练集和测试集打印了详细的分类报告。这些报告提供了模型性能的全面视图,帮助判断模型在各个类别上的表现。
# 8. 单独打印训练集和测试集的精度
train_accuracy = accuracy_score(y_train, best_model.predict(X_train))
test_accuracy = accuracy_score(y_test, best_model.predict(X_test))
print(f"训练集精度: {train_accuracy:.4f}")
print(f"测试集精度: {test_accuracy:.4f}")
# 9. 打印训练集和测试集的模型评估指标
train_predictions = best_model.predict(X_train)
test_predictions = best_model.predict(X_test)
print("网格搜索后的训练集评估指标:")
print(classification_report(y_train, train_predictions))
print("网格搜索后的测试集评估指标:")
print(classification_report(y_test, test_predictions))
打印结果:
训练集精度: 0.8000
测试集精度: 0.8222
网格搜索后的训练集评估指标:
precision recall f1-score support
0 0.97 0.97 0.97 31
1 0.75 0.65 0.70 37
2 0.71 0.81 0.76 37
accuracy 0.80 105
macro avg 0.81 0.81 0.81 105
weighted avg 0.80 0.80 0.80 105
网格搜索后的测试集评估指标:
precision recall f1-score support
0 0.95 1.00 0.97 19
1 0.78 0.54 0.64 13
2 0.69 0.85 0.76 13
accuracy 0.82 45
macro avg 0.81 0.79 0.79 45
weighted avg 0.82 0.82 0.81 45
这些步骤对于验证模型的有效性和理解其在不同数据集上的表现是非常重要的。精度给出了模型整体表现的快速概览,而分类报告则提供了更深入的性能细节。
3.8 结果可视化
之后,我们对结果进行了可视化,例如:决策边界、混淆矩阵、ROC曲线和AUC。
3.8.1 决策边界
决策边界是在机器学习和统计分类中使用的一个概念,特别是在监督学习任务中,如分类问题。简单来说,决策边界是在特征空间中划定的一条界线,它区分了不同类别的数据点。
基本概念
- 定义:在特征空间中,决策边界是一个超平面,它将数据点根据分类模型的预测结果分为不同的类别。在二维空间中,这个边界通常是一条线;在三维空间中,它是一个平面;在更高维度中,它是一个超平面。
- 作用:决策边界的主要作用是帮助可视化分类模型是如何区分不同类别的数据点的。它是理解模型分类决策过程的一个直观工具。
在逻辑回归中的应用
- 逻辑回归决策边界:在逻辑回归中,决策边界是由模型参数决定的线性边界。逻辑回归通常用于二分类问题,其决策边界是特征空间中将两个类别分开的直线(或超平面)。
- 确定边界:在逻辑回归中,决策边界是由模型参数(权重)和阈值(如Sigmoid函数的0.5阈值)共同确定的。当模型预测的概率等于0.5时,所对应的特征点位于决策边界上。
重要性
- 模型解释:通过分析决策边界,可以对模型的分类逻辑有更直观的理解。例如,可以看出模型是否能有效地区分不同类别,或者是否对某些数据过于敏感(过拟合)。
- 特征关系:决策边界还可以帮助揭示不同特征与分类结果之间的关系。
注意事项
- 高维数据:对于超过两个特征的高维数据,直接可视化决策边界变得困难。在这种情况下,可能需要使用降维技术或选择特定的特征对进行可视化。
- 非线性关系:对于非线性关系,线性模型(如逻辑回归)的决策边界可能无法提供足够的区分度。在这种情况下,可能需要使用更复杂的非线性模型。
这段代码用于绘制分类模型的决策边界,帮助我们直观地理解模型是如何区分不同类别的。决策边界是模型根据输入特征对类别做出决策的界限。代码中首先定义了一个函数 plot_decision_boundary
来生成和绘制决策边界,然后分别对训练集和测试集应用这个函数。
函数 plot_decision_boundary
的工作流程如下:
- 确定图表的x轴和y轴范围(基于特征值的最小和最大值)。
- 使用
np.meshgrid
创建一个网格,这个网格覆盖了所有可能的点。 - 对于网格中的每个点,使用模型进行预测(
model.predict
)。 - 用
plt.contourf
根据预测结果绘制决策区域。 - 使用
plt.scatter
在同一图表上绘制原始数据点,颜色表示它们的实际类别。
然后,代码分别对训练集和测试集的数据执行这个函数,并在两个子图中展示结果。这样,我们可以直观地看到模型在训练集上是如何学习分类的,以及模型在未见过的测试集数据上表现得如何。通过比较两个决策边界,可以对模型的泛化能力有一个更好的理解。
# 11. 绘制决策边界的函数保持不变
# 函数:绘制决策边界
def plot_decision_boundary(X, y, model):
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')
# 绘制训练集和测试集的决策边界
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plot_decision_boundary(X_train, y_train, best_model)
plt.title("训练集的决策边界")
plt.subplot(1, 2, 2)
plot_decision_boundary(X_test, y_test, best_model)
plt.title("测试集的决策边界")
plt.show()
3.8.2 混淆矩阵
混淆矩阵(Confusion Matrix)是一种特别用于评估分类模型性能的表格布局。它是机器学习中常用的工具,用于可视化算法在分类任务中的表现。混淆矩阵显示了模型对测试数据的预测结果与实际结果的比较。
结构
混淆矩阵的结构取决于分类问题的类别数。对于二分类问题,它是一个2x2的矩阵:
- 真正(True Positives, TP):模型正确预测正类的次数。
- 假正(False Positives, FP):模型错误地将负类预测为正类的次数。
- 真负(True Negatives, TN):模型正确预测负类的次数。
- 假负(False Negatives, FN):模型错误地将正类预测为负类的次数。
应用
通过混淆矩阵,可以计算出多种性能指标,如准确率(Accuracy)、精确度(Precision)、召回率(Recall)和F1得分(F1 Score)。这些指标为评估和比较不同模型的性能提供了有用的方法。
- 准确率:正确预测的比例((TP + TN) / 总数)。
- 精确度:正预测中实际为正的比例(TP / (TP + FP))。
- 召回率:实际正类中被正确预测的比例(TP / (TP + FN))。
- F1得分:精确度和召回率的调和平均数。
重要性
混淆矩阵提供了比单纯的准确率更全面的性能评估。在实际应用中,根据具体问题的不同,我们可能更关注精确度、召回率或两者的平衡。例如,在医疗诊断中,提高召回率(减少假负)可能比提高精确度更重要。通过混淆矩阵,我们能够更深入地了解模型的行为和潜在的改进方向。
这段代码用于可视化混淆矩阵,是评估分类模型性能的一个重要工具。具体步骤和含义如下:
-
生成混淆矩阵:
cm = confusion_matrix(y_test, best_model.predict(X_test))
:这行代码首先使用confusion_matrix
函数生成了混淆矩阵。混淆矩阵是一个表格,用于描述分类模型的性能,通过比较模型的预测结果和实际标签。
-
设置图表大小:
plt.figure(figsize=(6, 6))
:设置了图表的大小,确保图表足够大,以便清晰地展示混淆矩阵。
-
使用热图绘制混淆矩阵:
sns.heatmap(cm, annot=True, fmt="d", square=True, cmap='Blues', ...)
:使用 seaborn 的heatmap
函数将混淆矩阵以热图的形式绘制出来。其中:annot=True
:在每个格子中标注数值。fmt="d"
:设置标注的数值格式为整数。square=True
:确保每个格子是正方形。cmap='Blues'
:使用蓝色调色板。
-
添加坐标轴标签和标题:
xticklabels
和yticklabels
设置了x轴和y轴的标签,这里使用了鸢尾花数据集的目标类别名称。plt.xlabel('预测标签')
和plt.ylabel('真实标签')
分别设置了x轴和y轴的标签,说明了图表的纵横轴分别代表预测标签和真实标签。plt.title('混淆矩阵')
:添加了图表的标题。
-
展示图表:
plt.show()
:显示绘制好的图表。
通过混淆矩阵的可视化,可以直观地了解模型在不同类别上的预测准确性和误判情况,例如哪些类别容易被混淆。这对于理解和改进模型非常有帮助。
# 混淆矩阵可视化
cm = confusion_matrix(y_test, best_model.predict(X_test))
plt.figure(figsize=(6, 6))
sns.heatmap(cm, annot=True, fmt="d", square=True, cmap='Blues',
xticklabels=iris.target_names, yticklabels=iris.target_names)
plt.xlabel('预测标签')
plt.ylabel('真实标签')
plt.title('混淆矩阵')
plt.show()
3.8.3 模型的训练曲线
这段代码用于绘制模型在不同参数设置下的训练和验证性能曲线。具体步骤和目的如下:
-
提取网格搜索结果:
cv_results = grid_search.cv_results_
:这行代码从之前执行的网格搜索(GridSearchCV
)中提取了详细的结果。cv_results_
是一个字典,其中包含了在网格搜索的每一组参数配置下模型的性能指标。
-
提取训练和测试得分:
mean_train_score = cv_results['mean_train_score']
:这提取了在每个参数设置下模型在训练集上的平均得分。mean_test_score = cv_results['mean_test_score']
:这提取了模型在交叉验证测试集上的平均得分。
-
绘制性能曲线:
plt.figure(figsize=(10, 6))
:设置图表的大小。plt.plot(mean_train_score, label='训练得分')
:绘制了模型在训练集上的性能曲线。plt.plot(mean_test_score, label='测试得分')
:绘制了模型在测试集上的性能曲线。- 这两条曲线可以帮助我们评估不同参数设置下模型的性能表现。
-
添加图表元素:
plt.title('模型性能曲线')
:设置图表标题。plt.xlabel('参数组合编号')
和plt.ylabel('得分')
:设置横纵坐标轴的标签。plt.legend()
:添加图例,用于区分不同的曲线。
-
展示图表:
plt.show()
:显示绘制好的图表。
通过这个性能曲线图,我们可以直观地看到模型在训练集和测试集上的表现随参数变化的趋势,从而帮助我们理解不同参数配置对模型性能的影响。这是模型选择和调优过程中一个非常有用的分析工具。
# 10. 绘制模型的训练曲线
cv_results = grid_search.cv_results_
mean_train_score = cv_results['mean_train_score']
mean_test_score = cv_results['mean_test_score']
plt.figure(figsize=(10, 6))
plt.plot(mean_train_score, label='训练得分')
plt.plot(mean_test_score, label='测试得分')
plt.title('模型性能曲线')
plt.xlabel('参数组合编号')
plt.ylabel('得分')
plt.legend()
plt.show()
完整源码
import warnings
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from sklearn.datasets import load_iris
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
warnings.filterwarnings('ignore')
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams["axes.unicode_minus"] = False
# 1. 导入所需的库
# 已在代码开头导入
# 2. 加载数据集
iris = load_iris()
X, y = iris.data, iris.target
X = X[:, :2]
# 3. 数据预处理
# 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 4. 特征工程
# 在这个例子中,我们直接使用了原始特征,没有进行额外的特征工程
# 5. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
# 6. 定义RidgeClassifier模型和参数网格
model = RidgeClassifier()
param_grid = {
'alpha': [0.1, 1, 10, 100] # 正则化强度
}
# 使用网格搜索,寻找最佳参数(包含训练得分)
grid_search = GridSearchCV(model, param_grid, cv=5, return_train_score=True)
grid_search.fit(X_train, y_train)
# 7. 网格搜索后的最佳参数和模型
print("最佳参数:", grid_search.best_params_)
best_model = grid_search.best_estimator_
# 8. 单独打印训练集和测试集的精度
train_accuracy = accuracy_score(y_train, best_model.predict(X_train))
test_accuracy = accuracy_score(y_test, best_model.predict(X_test))
print(f"训练集精度: {train_accuracy:.4f}")
print(f"测试集精度: {test_accuracy:.4f}")
# 9. 打印训练集和测试集的模型评估指标
train_predictions = best_model.predict(X_train)
test_predictions = best_model.predict(X_test)
print("网格搜索后的训练集评估指标:")
print(classification_report(y_train, train_predictions))
print("网格搜索后的测试集评估指标:")
print(classification_report(y_test, test_predictions))
# 10. 绘制模型的训练曲线
cv_results = grid_search.cv_results_
mean_train_score = cv_results['mean_train_score']
mean_test_score = cv_results['mean_test_score']
plt.figure(figsize=(10, 6))
plt.plot(mean_train_score, label='训练得分')
plt.plot(mean_test_score, label='测试得分')
plt.title('模型性能曲线')
plt.xlabel('参数组合编号')
plt.ylabel('得分')
plt.legend()
plt.show()
# 11. 绘制决策边界的函数保持不变
# 函数:绘制决策边界
def plot_decision_boundary(X, y, model):
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')
# 绘制训练集和测试集的决策边界
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plot_decision_boundary(X_train, y_train, best_model)
plt.title("训练集的决策边界")
plt.subplot(1, 2, 2)
plot_decision_boundary(X_test, y_test, best_model)
plt.title("测试集的决策边界")
plt.show()
# 混淆矩阵可视化
cm = confusion_matrix(y_test, best_model.predict(X_test))
plt.figure(figsize=(6, 6))
sns.heatmap(cm, annot=True, fmt="d", square=True, cmap='Blues',
xticklabels=iris.target_names, yticklabels=iris.target_names)
plt.xlabel('预测标签')
plt.ylabel('真实标签')
plt.title('混淆矩阵')
plt.show()