在这里插入图片描述

💥 项目专栏:sklearn实现经典机器学习算法(附代码+原理介绍)


前言

🌟 哈喽,亲爱的小伙伴们,你们知道吗?最近我们的粉丝群里有好多小可爱私信问我一些关于决策树、逻辑回归等机器学习的超级有趣的问题呢!🌈 为了让大家更轻松地理解,我决定开一个超可爱的专栏,叫做 用sklearn玩转机器学习,特别适合机器学习的小新手哦!

🍬 在这个专栏里,我们会用sklearn这个超级强大的魔法工具来实现各种闪闪发光的机器学习算法!不用担心难度哦,我会用最简单、最可爱的方式,带领大家一起探索算法的神秘世界!✨

🎈 适合哪些小伙伴加入呢?当然是对机器学习感兴趣的小新手们,还有那些刚开始接触sklearn的可爱宝宝们!我们会一起学习如何用sklearn轻松实现那些看起来好厉害的机器学习算法,让新手小白也能快快乐乐地理解它们哦!

🌸 在这个专栏里,大家可以看到用sklearn实现的机器学习算法,我们不仅仅是理论学习哦,每一篇文章都会附带 完整的代码+超级可爱的原理讲解,让大家在轻松愉快的氛围中一起学习成长呢!🌼 快来加入我们的学习大冒险吧!


Python_副本

🚨 我的项目环境:

  • 平台: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实现经典机器学习算法(附代码+原理介绍)


一、逻辑回归算法背景

🌟 逻辑回归(Logistic Regression)入门 🌟

在这篇文章中,我们将深入探索逻辑回归——一种在统计学和机器学习领域广泛应用的分类算法,特别是在处理二分类问题时。逻辑回归不仅以其简洁性和强大的解释性著称,还因其在多个领域的广泛应用而备受青睐。

📖 起源与背景

  • 发展历史:逻辑回归由统计学家David Cox于1958年提出,其根源可追溯至早期的概率论和统计学。
  • 跨领域应用:从统计学方法转变为机器学习领域的重要工具,尤其在二分类问题中发挥关键作用。

🌐 应用领域

  • 医学:用于疾病诊断和治疗效果评估。
  • 金融:用于信用评分和欺诈检测。
  • 市场营销:用于预测客户购买行为和流失率。
  • 社会科学:用于选举预测和社会行为研究。

✨ 特点

  • 解释性强:提供易于理解的概率结果,明确显示因素对结果的影响。
  • 广泛应用:适用于多种领域,尤其是在需要快速可靠分类决策的场景。

虽然在处理复杂或高度非线性数据时可能有局限,但逻辑回归因其简洁和强大,在许多实际应用中仍然是不可或缺的工具。

💡 本篇亮点

在本篇文章中,我们将使用sklearn实现 Logistic Regression。这不仅是本专栏的第一篇文章,而且是一个详细的实操指南,旨在帮助初学者快速建立起机器学习算法训练的框架,深入理解其实现细节。

二、算法原理

🌟 逻辑回归:二分类问题的强大解决者 🌟

逻辑回归是一种专门处理二分类问题的统计方法,非常适用于预测那些取值为二元的目标变量,如是/否,成功/失败,赢/输等。

🧩 基本原理

  • 核心:逻辑回归的关键在于逻辑函数(通常是Sigmoid函数),这个函数能将任意实数值映射到(0,1)区间内,提供了一种概率的表达方式。

    公式表达如下:
    P ( Y = 1 ∣ X ) = 1 1 + e − ( β 0 + β 1 X 1 + β 2 X 2 + . . . + β n X n ) P(Y=1|X) = \frac{1}{1 + e^{-(\beta_0 + \beta_1X_1 + \beta_2X_2 + ... + \beta_nX_n)}} P(Y=1∣X)=1+e(β0+β1X1+β2X2+...+βnXn)1
    其中, P ( Y = 1 ∣ X ) P(Y=1|X) P(Y=1∣X) 表示在给定自变量 X X X 的条件下,因变量 Y Y Y 为1的概率; β 0 , β 1 , . . . , β n \beta_0, \beta_1, ..., \beta_n β0,β1,...,βn 是模型参数; X 1 , X 2 , . . . , X n X_1, X_2, ..., X_n X1,X2,...,Xn 是自变量。

📊 参数估计

  • 最大似然估计(MLE):逻辑回归模型通常通过MLE来估计参数,目标是找到能使得观测到的样本概率最大化的参数值。

📈 模型评估

  • 混淆矩阵:展示了模型预测正确与错误的数量。
  • 准确率:表示模型正确预测的比例。
  • ROC曲线和AUC:用于展示模型在不同阈值下的真阳性率和假阳性率。

⚙️ 优化

  • 防止过拟合:在高维数据场景下,逻辑回归可能过拟合。为了避免这一问题,经常采用L1或L2正则化等技术来优化模型。

🧪 模型假设

  • 二元因变量:假设因变量是二元的。
  • 线性关系:假设自变量和对数几率(log odds)之间存在线性关系。
  • 无多重共线性:假设自变量之间相互独立,不存在多重共线性。

🌐 应用价值

作为一种简单而强大的统计方法,逻辑回归在多个领域内解决二分类问题时展现出了其独特的价值。因其易于理解和实施,逻辑回归在实际应用中广受欢迎。

三、算法实现

3.1 导包

对于本项目主要使用到的第三方库有以下几种,都是比较常见的

🌈 欢迎来到逻辑回归模型的小工具箱! 在我们的项目中,我们用到了一些超级可爱又实用的小工具(也就是第三方库啦),它们帮助我们轻松愉快地完成了数据分析和模型构建哦!🛠️

  1. numpy:想象一下有一个神奇的魔法包,可以轻松处理大大的数字阵列和复杂的数学问题!Numpy就是这样一个包,它让科学计算变得像玩乐高一样有趣!🧱

  2. matplotlib.pyplot:这个库就像我们的小画板,让我们用代码就能画出美丽的图表!就像使用魔法画笔,可以把枯燥的数据变成五彩斑斓的图形,让人一看就爱上!🎨

  3. seaborn:Seaborn是matplotlib的时尚小伙伴,提供了更多华丽丽的图表样式。用它来绘图,就像给数据穿上了漂亮的小裙子,让每个图表都变得超级迷人!👗

  4. sklearn.datasets:想要玩转机器学习,怎么能少了数据呢?sklearn.datasets就像一个装满了各种有趣数据的宝箱,比如我们用到的超级名气的鸢尾花数据集哦!🌸

  5. sklearn.model_selection.train_test_split:这个工具就像把数据分成两个小队伍,一个训练小队,一个测试小队,帮助我们训练出最棒的模型!🏋️‍♂️🏋️‍♀️

  6. sklearn.linear_model.LogisticRegression:这里有一个小小的逻辑回归分类器,它可以帮助我们找出事物是非、成败的小秘密!🔍

  7. sklearn.metrics:要知道我们的模型表现得怎么样,就需要这个工具箱里的小助手们,它们可以告诉我们模型是不是真的聪明哦!📊

  8. sklearn.model_selection.GridSearchCV:想要找到最棒的参数组合,就要用到这个像宝藏地图一样的工具,它可以帮助我们在参数的海洋中找到宝藏!🗺️

  9. sklearn.preprocessing.StandardScaler:这个小工具就像是给数据做美容,让它们变得整整齐齐,更适合做机器学习的模特啦!💇‍♂️💇‍♀️

使用这些小工具,我们可以愉快地在数据科学和机器学习的世界里遨游,它们每一个都承担着特别的任务,帮我们把数据变得更有趣、更有用呢!

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 LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
from sklearn.metrics import confusion_matrix, roc_curve, auc
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler

3.2 加载数据集

这段代码主要用于加载和预处理数据集,以便进行逻辑回归分析。首先,通过 load_iris() 函数从 sklearn.datasets 模块中加载了著名的鸢尾花(Iris)数据集。这个数据集包含了三种鸢尾花的特征数据和分类标签。每种鸢尾花有50个样本,每个样本有4个特征:萼片长度、萼片宽度、花瓣长度和花瓣宽度。

由于逻辑回归通常用于处理二分类问题,因此代码接下来进行了一些预处理工作。首先,它通过 X = X[y != 2, :2] 选择了数据集中前两种鸢尾花(标签为0和1)的样本,并且只选取了每个样本的前两个特征(萼片长度和萼片宽度)。其次,通过 y = y[y != 2],它筛选出了对应的目标变量,即只保留了前两种鸢尾花的分类标签。这样,我们就得到了一个适合进行逻辑回归分析的二分类问题数据集。

# 2. 加载数据集
iris = load_iris()
X, y = iris.data, iris.target

# 仅保留前两种类别的样本和前两个特征(逻辑回归通常用于二分类问题)
X = X[y != 2, :2]
y = y[y != 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_scaledy 分别是经过预处理(如标准化)的特征数据和对应的标签。参数 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 定义逻辑回归模型

在这一部分代码中,我们定义了逻辑回归模型,它是用于分类任务的统计方法。这里使用的是 LogisticRegression 类,来自于Python的scikit-learn库。我们指定了参数 solver='liblinear',这意味着模型将使用liblinear库来优化问题。Liblinear是一个专门为大规模线性分类设计的库,非常适合处理二元分类以及有大量特征的数据集。这个选择在处理相对较小的数据集,如鸢尾花数据集时,效果尤为明显。通过定义这个模型,我们接下来将在训练数据上训练它,并用它来预测测试数据的类别。"

# 6. 定义逻辑回归模型和参数网格
model = LogisticRegression(solver='liblinear')

以下是以 表格形式展示的 sklearnLogisticRegression 类的常用参数,包括参数名称、描述以及可选的值或类型:

参数描述可选的值/类型
penalty用于指定正则化的类型。‘l1’, ‘l2’, ‘elasticnet’, ‘none’
C正则化强度的倒数,较小的值表示更强的正则化。正浮点数
solver优化问题的算法。不同的算法支持不同类型的正则化。‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’
max_iter求解器的最大迭代次数。正整数
multi_class多类策略选择,适用于多分类问题。‘ovr’, ‘multinomial’, ‘auto’
class_weight类别权重,用于处理不平衡类别分布的情况。字典、‘balanced’ 或 None
random_state随机数生成器的种子。整数或 None
fit_intercept是否应该添加一个常数项(即偏置或截距)。布尔值
warm_start当设置为 True 时,使用前一个调用的解作为初始化,否则,仅使用初始参数。布尔值

这些参数允许您在构建逻辑回归模型时进行细粒度的调整,以适应您的特定数据集和性能需求。理解每个参数及其影响是优化模型和提高预测准确性的关键。

3.6 网格搜索

这段代码演示了如何使用网格搜索(Grid Search)方法来优化逻辑回归模型的超参数。网格搜索是一种自动化的参数调优技术,它通过尝试给定参数网格中的所有参数组合来找到最佳的模型参数。在这个例子中,我们关注两个参数:正则化强度的倒数 C 和惩罚类型 penalty

  1. 定义参数网格:在 param_grid 字典中,我们指定了要调优的参数。C 参数有四个候选值 [0.1, 1, 10, 100],用于控制模型的正则化强度,而 penalty 参数有两个候选值 ['l1', 'l2'],指定了正则化的类型。

  2. 创建并配置GridSearchCV对象:我们使用 GridSearchCV 类,传入逻辑回归模型 model 和参数网格 param_gridcv=5 指定了5折交叉验证,而 return_train_score=True 表明我们希望返回训练集的得分。

  3. 执行网格搜索:调用 grid_search.fit(X_train, y_train) 开始网格搜索过程,其中 X_trainy_train 是训练数据集。网格搜索会对每一种参数组合进行训练,并使用交叉验证评估模型性能。

  4. 输出最佳参数和模型:最后,通过 grid_search.best_params_ 获取最佳参数组合,通过 grid_search.best_estimator_ 获取配置了最佳参数的模型实例。这允许我们看到哪一组参数在训练过程中表现最佳,并使用这最优化的模型进行后续的预测或分析。

总的来说,这段代码展示了如何利用网格搜索来自动调整逻辑回归模型的参数,以获得更好的性能。这是机器学习模型优化过程中非常重要和常用的一步。

param_grid = {
    'C': [0.1, 1, 10, 100],  # 正则化强度的倒数
    'penalty': ['l1', 'l2']  # 惩罚类型
}

# 使用网格搜索,寻找最佳参数(包含训练得分)
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 评估指标

这段代码主要用于评估逻辑回归模型在训练集和测试集上的性能。首先,我们使用 accuracy_score 方法计算模型在训练集(X_train)和测试集(X_test)上的准确率,这个准确率表明了模型正确预测样本标签的比例。通过打印出的训练集和测试集的精度,我们可以直观地了解模型的预测能力。

接着,代码使用 classification_report 方法来生成一个关于模型性能的详细报告,包括每个类别的精确度(precision)、召回率(recall)、F1分数(F1-score)和支持度(support)。精确度是指模型正确预测为正类的样本占所有预测为正类的样本的比例;召回率是指模型正确预测为正类的样本占所有实际正类的样本的比例;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))

打印结果:

训练集精度: 1.0000
测试集精度: 1.0000
网格搜索后的训练集评估指标:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00        33
           1       1.00      1.00      1.00        37

    accuracy                           1.00        70
   macro avg       1.00      1.00      1.00        70
weighted avg       1.00      1.00      1.00        70

网格搜索后的测试集评估指标:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00        17
           1       1.00      1.00      1.00        13

    accuracy                           1.00        30
   macro avg       1.00      1.00      1.00        30
weighted avg       1.00      1.00      1.00        30

通过这些评估指标,我们能够全面了解模型在训练数据和未知数据上的表现,判断模型是否出现了过拟合或欠拟合的现象,并对模型的泛化能力做出判断。这对于理解和改进机器学习模型至关重要。

3.8 结果可视化

之后,我们对结果进行了可视化,例如:决策边界、混淆矩阵、ROC曲线和AUC。

3.8.1 决策边界

决策边界是在机器学习和统计分类中使用的一个概念,特别是在监督学习任务中,如分类问题。简单来说,决策边界是在特征空间中划定的一条界线,它区分了不同类别的数据点。

基本概念

  • 定义:在特征空间中,决策边界是一个超平面,它将数据点根据分类模型的预测结果分为不同的类别。在二维空间中,这个边界通常是一条线;在三维空间中,它是一个平面;在更高维度中,它是一个超平面。
  • 作用:决策边界的主要作用是帮助可视化分类模型是如何区分不同类别的数据点的。它是理解模型分类决策过程的一个直观工具。

在逻辑回归中的应用

  • 逻辑回归决策边界:在逻辑回归中,决策边界是由模型参数决定的线性边界。逻辑回归通常用于二分类问题,其决策边界是特征空间中将两个类别分开的直线(或超平面)。
  • 确定边界:在逻辑回归中,决策边界是由模型参数(权重)和阈值(如Sigmoid函数的0.5阈值)共同确定的。当模型预测的概率等于0.5时,所对应的特征点位于决策边界上。

重要性

  • 模型解释:通过分析决策边界,可以对模型的分类逻辑有更直观的理解。例如,可以看出模型是否能有效地区分不同类别,或者是否对某些数据过于敏感(过拟合)。
  • 特征关系:决策边界还可以帮助揭示不同特征与分类结果之间的关系。

注意事项

  • 高维数据:对于超过两个特征的高维数据,直接可视化决策边界变得困难。在这种情况下,可能需要使用降维技术或选择特定的特征对进行可视化。
  • 非线性关系:对于非线性关系,线性模型(如逻辑回归)的决策边界可能无法提供足够的区分度。在这种情况下,可能需要使用更复杂的非线性模型。

image-20240107143026006

这段代码的目的是为了可视化逻辑回归模型在训练集和测试集上的决策边界。决策边界是机器学习模型用来区分不同类别的线或曲面,在二维空间中,这通常表现为一条线。

代码解释

  1. 定义决策边界绘制函数:首先定义了一个名为 plot_decision_boundary 的函数,它接受输入特征 X、目标变量 y 以及训练好的模型 model。函数内部的步骤包括:

    • 计算输入特征的最小值和最大值,以此来确定绘图的范围。
    • 使用 numpymeshgrid 函数在这个范围内生成一个密集的点网格。
    • 使用模型对这些点进行预测,并将预测结果 Z 重塑为与网格相同的形状。
    • 使用 plt.contourf 绘制等高线图,这些等高线代表模型的决策边界。
    • 使用 plt.scatter 绘制原始数据点,不同类别的点以不同颜色显示。
  2. 绘制训练集和测试集的决策边界:接下来的代码块中,我们使用 matplotlib 的子图功能创建两个并排的图表。每个子图中,我们分别调用 plot_decision_boundary 函数来展示模型在训练集和测试集上的决策边界。

    • 第一个子图展示了模型在训练集上如何划分不同类别。
    • 第二个子图展示了模型在未见过的测试集上的表现。

重要性

通过可视化决策边界,我们可以直观地理解模型是如何区分不同类别的,以及模型在训练集和测试集上的表现是否一致。这对于评估模型的泛化能力和识别过拟合或欠拟合的问题非常有帮助。

# 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()

# 绘制训练集和测试集的决策边界
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得分:精确度和召回率的调和平均数。

重要性

混淆矩阵提供了比单纯的准确率更全面的性能评估。在实际应用中,根据具体问题的不同,我们可能更关注精确度、召回率或两者的平衡。例如,在医疗诊断中,提高召回率(减少假负)可能比提高精确度更重要。通过混淆矩阵,我们能够更深入地了解模型的行为和潜在的改进方向。

image-20240107143034318

在这段代码中,我们使用了Seaborn库的heatmap函数来可视化逻辑回归模型的混淆矩阵。混淆矩阵是一个非常有用的工具,用于评估分类模型的性能,特别是在二分类问题中。它显示了模型预测的准确性和误差类型。

首先,我们使用confusion_matrix函数从scikit-learn的metrics模块计算了混淆矩阵,它比较了测试数据集的真实标签和模型预测的标签。然后,我们使用heatmap函数创建了一个热图来表示这个矩阵。在热图中,每个方格的颜色深度代表了对应类别的预测数量,颜色越深表示数量越多。

我们还对热图进行了一些自定义设置,如设置图像大小为6x6英寸,方格为正方形,并使用蓝色调的颜色图。每个方格中的数字表示预测的数量,通过annot=Truefmt="d"参数来实现。此外,我们还设置了x轴和y轴的标签分别为’预测标签’和’真实标签’,以及将热图的标题设置为’混淆矩阵’。

通过这个混淆矩阵的可视化,我们可以直观地看到模型在不同类别上的预测表现,包括正确分类和误分类的情况。这对于理解和评估分类模型的性能非常重要。

# 混淆矩阵可视化
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=['类别1', '类别2'], yticklabels=['类别1', '类别2'])
plt.xlabel('预测标签')
plt.ylabel('真实标签')
plt.title('混淆矩阵')
plt.show()

3.8.3 ROC曲线和AUC

ROC曲线(Receiver Operating Characteristic Curve)和AUC(Area Under the Curve)是评估分类模型性能的重要工具,特别是在处理二分类问题时。

ROC曲线

  • 定义:ROC曲线是一个图形化的评估方法,用于展示分类模型在不同阈值下的性能。它通过绘制真正率(True Positive Rate, TPR)对假正率(False Positive Rate, FPR)的曲线来实现。
  • 真正率(TPR):也称为灵敏度,计算公式为TP/(TP+FN),其中TP是真正例数量,FN是假负例数量。
  • 假正率(FPR):计算公式为FP/(FP+TN),其中FP是假正例数量,TN是真负例数量。
  • 应用:ROC曲线用于展示在不同阈值下,模型识别正例的能力如何变化。曲线越接近左上角,模型的性能越好。

AUC

  • 定义:AUC是ROC曲线下的面积,数值介于0和1之间。
  • 解释:AUC提供了一个单一数值来总结ROC曲线下的整体性能。它表示随机选择的正例样本被模型预测为正例的概率高于随机选择的负例样本被预测为正例的概率。
  • 应用:AUC越高,模型的区分能力越好。AUC为0.5时,模型的性能等同于随机猜测;AUC为1时,表示模型在这个任务上有完美的表现。

ROC曲线和AUC常用于不平衡分类问题,因为它们对类别分布不平衡不敏感,能够提供关于模型性能的更准确的信息。在实践中,它们被广泛用于比较和选择不同的分类模型。

image-20240107143044758

这段代码用于计算并可视化逻辑回归模型的接收者操作特征曲线(Receiver Operating Characteristic Curve,简称ROC曲线),以及相应的曲线下面积(Area Under Curve,简称AUC)。ROC曲线是一个重要的评估分类模型性能的工具,尤其是在数据集不平衡的情况下。

首先,使用 roc_curve 函数计算了测试集上的假正率(False Positive Rate, FPR)和真正率(True Positive Rate, TPR)。这里,best_model.predict_proba(X_test)[:, 1] 表示模型预测每个样本属于正类的概率。接着,使用 auc 函数计算了ROC曲线下的面积(AUC),这个值用于量化模型整体的分类性能,值越大表示模型性能越好。

然后,代码中绘制了ROC曲线,其中横坐标是假正率,纵坐标是真正率。曲线以橙色显示,并标注了AUC值。作为对比,还绘制了一条虚线表示随机分类器的表现(即FPR和TPR相等的情况)。

最后,设置了图表的标题、坐标轴标签、图例,并展示了这个图表。ROC曲线提供了一种直观的方式来查看模型在不同分类阈值下的表现,是理解和解释模型性能的一个重要工具。

# 计算ROC曲线和AUC
fpr, tpr, _ = roc_curve(y_test, best_model.predict_proba(X_test)[:, 1])
roc_auc = auc(fpr, tpr)

# ROC曲线可视化
plt.figure(figsize=(6, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC曲线 (AUC = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假正率')
plt.ylabel('真正率')
plt.title('接收者操作特征曲线')
plt.legend(loc="lower right")
plt.show()

3.8.4 模型的训练曲线

image-20240107142955685

这段代码用于绘制逻辑回归模型在网格搜索过程中的性能曲线。首先,通过访问 grid_search.cv_results_,获取了网格搜索的结果,其中包括每一组参数对应的训练得分(mean_train_score)和测试得分(mean_test_score)。然后,使用Matplotlib库创建了一个图形(大小为10x6英寸),并在同一图上绘制了训练得分和测试得分的曲线。训练得分曲线显示了模型在训练数据上的性能,而测试得分曲线则显示了模型在交叉验证过程中的性能。这两条曲线提供了关于模型在不同参数设置下的泛化能力的重要信息。图表通过标题、坐标轴标签和图例来增强可读性,使得观众可以轻松地理解模型的性能变化。

# 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 LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
from sklearn.metrics import confusion_matrix, roc_curve, auc
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[y != 2, :2]
y = y[y != 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. 定义逻辑回归模型和参数网格
model = LogisticRegression(solver='liblinear')
param_grid = {
    'C': [0.1, 1, 10, 100],  # 正则化强度的倒数
    'penalty': ['l1', 'l2']  # 惩罚类型
}

# 使用网格搜索,寻找最佳参数(包含训练得分)
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()

# 绘制训练集和测试集的决策边界
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=['类别1', '类别2'], yticklabels=['类别1', '类别2'])
plt.xlabel('预测标签')
plt.ylabel('真实标签')
plt.title('混淆矩阵')
plt.show()

# 计算ROC曲线和AUC
fpr, tpr, _ = roc_curve(y_test, best_model.predict_proba(X_test)[:, 1])
roc_auc = auc(fpr, tpr)

# ROC曲线可视化
plt.figure(figsize=(6, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC曲线 (AUC = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假正率')
plt.ylabel('真正率')
plt.title('接收者操作特征曲线')
plt.legend(loc="lower right")
plt.show()
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐