跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Python 数据分析:模型评估与选择实战

机器学习模型评估与选择的完整流程。涵盖数据集划分、交叉验证方法、回归模型指标(MAE、MSE、RMSE、R²)、分类模型指标(混淆矩阵、准确率、召回率、F1-score)及 ROC-AUC 分析。通过 sklearn 实战代码演示了基准模型对比、学习曲线绘制及分类报告生成,帮助读者掌握模型性能优化与选择的关键技术。

星星泡饭发布于 2025/2/6更新于 2026/6/1529 浏览
Python 数据分析:模型评估与选择实战

Python 数据分析:模型评估与选择实战

引言

在机器学习任务中,数据预处理完成后,需要根据研究目标建立模型。选择合适的模型首先需要对其效果进行评估。本文介绍如何使用 sklearn 进行模型评估。

模型评估的基本步骤如下:

  • 将数据集分为训练集和测试集
  • 对训练集进行模型拟合
  • 确定合适的评估指标
  • 计算在测试集上的评估指标

1. 数据集划分

在机器学习问题中,理论上需要将数据集划分为训练集、验证集、测试集。

  • 训练集:用于拟合模型(平常的作业和测试)
  • 验证集:用于计算验证集误差,选择模型(模拟考)
  • 测试集:用于评估模型(最终考试)

但在实际应用中,一般分为训练集和测试集两个部分。通常训练集占 70%,测试集占 30%。这个比例在深度学习中可以进行相应的调整。我们可以使用 sklearn 中的 train_test_split 划分数据集。

# 导入相关库
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import metrics
from sklearn.model_selection import KFold, cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
import pandas as pd
# 导入数据
df = pd.read_csv(r'C:\Users\DELL\data-science-learning\seaborn-data\iris.csv')
print(df.shape)

输出:(150, 5)

# 划分数据集和测试集
train_set, test_set = train_test_split(df, test_size=0.3,
                                       random_state=12345)
print(train_set.shape, test_set.shape)

输出:((105, 5), (45, 5))

可以看出此时训练集有 105 个数据,测试集有 45 个数据。

2. 交叉验证模型

评估模型时,最常用的方法之一就是交叉验证。下面以一个具体案例来看如何实现。

# 加载数据
digits = datasets.load_digits()

# 创建特征矩阵
features = digits.data
target = digits.target

# 进行标准化
stand = StandardScaler()

# 创建逻辑回归器
logistic = LogisticRegression()

# 创建一个包含数据标准化和逻辑回归的流水线
pipeline = make_pipeline(stand, logistic)  # 先对数据进行标准化,再用逻辑回归拟合

# 创建 k 折交叉验证对象
kf = KFold(n_splits=10, shuffle=True, random_state=1)

使用 shuffle 打乱数据,保证我们验证集和训练集是独立同分布的 (IID) 的。

# 进行 k 折交叉验证
cv_results = cross_val_score(pipeline,
                             features,
                             target,
                             cv=kf,
                             scoring='accuracy',  # 评估的指标
                             n_jobs=-1)  # 调用所有的 cpu

print(cv_results.mean())

输出:0.9693916821849783

使用 pipeline 方法可以使得这个过程很方便。上述我们是直接对数据集进行了交叉验证,在实际应用中,建议先对数据集进行划分,再对训练集使用交叉验证。

from sklearn.model_selection import train_test_split

# 划分数据集
features_train, features_test, target_train, target_test = train_test_split(features, 
                                                                            target,
                                                                            test_size=0.1,
                                                                            random_state=1)

# 使用训练集来计算标准化参数
stand.fit(features_train)

# 然后在训练集和测试集上运用
features_train_std = stand.transform(features_train)
features_test_std = stand.transform(features_test)

这里之所以这样处理是因为我们的测试集是未知数据,如果使用测试集和训练集一起训练预处理器的话,测试集的信息有一部分就会泄露,因此是不科学的。更通用的做法是先将训练集训练模型,用验证集评估选择模型,最后再用训练集和验证集一起来训练选择好的模型,再来在测试集上进行测试。

pipeline = make_pipeline(stand, logistic)

cv_results = cross_val_score(pipeline,
                             features_train_std,
                             target_train,
                             cv=kf,
                             scoring='accuracy',
                             n_jobs=-1)

print(cv_results.mean())

输出:0.9635112338010889

3. 回归模型评估指标

评估回归模型的主要指标有以下几个:

  • MAE (平均绝对误差): $MAE = \frac{1}{m}\sum_{i=1}^{N}|y_i - \hat{y}_i|$
  • MSE (均方误差): $MSE = \frac{1}{m}\sum_{i=1}^{N}(y_i - \hat{y}_i)^2$
  • RMSE: $RMSE = \sqrt{\frac{1}{m}\sum_{i=1}^{N}(y_i - \hat{y}_i)^2}$
  • R²: $R^2 = \frac{ESS}{TSS}$

下面我们来看看具体代码。

# 导入相关库
from sklearn.datasets import make_regression
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn import metrics

# 建立模拟数据集
features, target = make_regression(n_samples=100,
                                   n_features=3,
                                   n_informative=3,
                                   n_targets=1,
                                   noise=50,
                                   coef=False,
                                   random_state=1)

# 创建 LinearRegression 回归器
ols = LinearRegression()

print(metrics.SCORERS.keys())

输出包含多种评分器,如 'explained_variance', 'r2', 'max_error', 'neg_mean_absolute_error' 等。

# 使用 MSE 对线性回归做交叉验证
print(cross_val_score(ols, features, target, scoring='neg_mean_squared_error', cv=5))

# 使用 R² 进行交叉验证
print(cross_val_score(ols, features, target, scoring='r2'))

4. 创建一个基准回归模型

from sklearn.datasets import fetch_california_housing
from sklearn.dummy import DummyRegressor
from sklearn.model_selection import train_test_split

# 加载数据
housing = fetch_california_housing()
features, target = housing.data, housing.target

# 将数据分为测试集和训练集
features_train, features_test, target_train, target_test = train_test_split(features, target,
                                                                           random_state=0)

# 创建 dummyregression 对象
dummy = DummyRegressor(strategy='mean')

# 训练模型
dummy.fit(features_train, target_train)

# 在测试集上评估
dummy_score = dummy.score(features_test, target_test)
print(f"Dummy Score: {dummy_score}")

# 下面我们训练自己的模型进行对比
from sklearn.linear_model import LinearRegression
ols = LinearRegression()
ols.fit(features_train, target_train)

ols_score = ols.score(features_test, target_test)
print(f"Linear Regression Score: {ols_score}")

通过与基准模型的对比,我们可以发现线性回归模型的优势。

5. 混淆矩阵

评估分类器性能的一个重要方法是查看混淆矩阵。一般的想法是计算 A 类实例被分类为 B 类的次数,以及 B 类被预测为 A 类的个数。要计算混淆矩阵,首先需要有一组预测,以便与实际目标进行比较。

其中:

  • TP (True Positive):正确预测正类的个数
  • FP (False Positive):错误预测正类的个数
  • TN (True Negative):正确预测负类的个数
  • FN (False Negative):错误预测负类的个数

下面我们来看如何使用具体的代码得到混淆矩阵。

# 导入相关库
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import pandas as pd

# 加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
class_names = iris.target_names

features_train, features_test, target_train, target_test = train_test_split(
    features, target, random_state=1)

classifier = LogisticRegression()

# 训练并预测
target_predicted = classifier.fit(features_train, target_train).predict(features_test)

# 创建一个混淆矩阵
matrix = confusion_matrix(target_test, target_predicted)
df = pd.DataFrame(matrix, index=class_names, columns=class_names)

sns.heatmap(df, annot=True, cbar=None, cmap='Blues')
plt.ylabel('True Class')
plt.xlabel('Predict Class')
plt.title('Confusion Matrix')
plt.show()

6. 分类评估指标

对于分类问题的评估指标主要包含以下几个:

  • F1-score: $F1 = \frac{2}{\frac{1}{precision} + \frac{1}{recall}}$
  • 准确率: $Accuracy = \frac{TP + TN}{FP + TP + FN + TN}$
  • 召回率: $Recall = \frac{TP}{TP + FN}$
  • 精确率: $Precision = \frac{TP}{TP + FP}$

其中,对于非均衡数据,使用 F1-score 比较合理。下面我们来看具体如何得到这些评估指标。

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

# 创建模拟数据集
X, y = make_classification(random_state=1,
                          n_samples=1000,
                          n_features=3,
                          n_informative=3,
                          n_redundant=0,
                          n_classes=2)

# 创建逻辑回归器
logit = LogisticRegression()

# 使用准确率对模型进行交叉验证
print(cross_val_score(logit, X, y, scoring='accuracy'))

# 使用 F1 分数
print(cross_val_score(logit, X, y, scoring='f1'))

# 使用精确率
print(cross_val_score(logit, X, y, scoring='precision'))

可以看出,召回率和精确率两个往往不会同时增加(增加样本量可能可以让两个指标同时增加),这有点像假设检验中的第一类错误和第二类错误。因此,我们要保证这两个指标都不能太小。下面我们介绍 ROC 和 AUC。

7. ROC 和 AUC

7.1 ROC 曲线

ROC 曲线是用于二分类器的另一个常用工具。它与精密度/召回率非常相似,但不是绘制精密度与召回率的关系,而是绘制真阳性率(召回率的另一个名称)与假阳性率(FPR)的关系。FPR 是未正确归类为正的负实例的比率。通过 ROC 曲线来进行评估,计算出每个阈值下的真阳性率和假阳性率。

  • $TPR = TP / (TP + FN)$
  • $FPR = FP / (FP + TN)$
# 导入相关库
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, roc_auc_score
from sklearn.model_selection import train_test_split

features, target = make_classification(n_samples=1000,
                                      n_features=10,
                                      n_classes=2,
                                      n_informative=3,
                                      random_state=3)

features_train, features_test, target_train, target_test = train_test_split(features,
                                                                            target,
                                                                            test_size=0.1,
                                                                            random_state=1)

logit = LogisticRegression()
logit.fit(features_train, target_train)

# 预测为 1 的概率
target_probabilities = logit.predict_proba(features_test)[:, 1]

false_positive_rate, true_positive_rate, thresholds = roc_curve(target_test, target_probabilities)

# 绘制 ROC 曲线
plt.plot(false_positive_rate, true_positive_rate)
plt.plot([0, 1], ls='--')
plt.plot([0, 0], [1, 0], c='.7')
plt.plot([1, 1], c='.7')
plt.title('ROC Curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()

7.2 AUC 值

比较分类器的一种方法是测量曲线下面积(AUC)。完美分类器的 AUC 等于 1,而适当的随机分类器的 AUC 等于 0.5。Sklearn 提供了一个计算 AUC 的函数 roc_auc_score。

auc_value = roc_auc_score(target_test, target_probabilities)
print(f"AUC Value: {auc_value}")

可以看出该分类器的 AUC 值为 0.97,说明该模型的效果很好。

由于 ROC 曲线与精度/召回(PR)曲线非常相似,您可能想知道如何决定使用哪一条曲线。根据经验,当阳性类别很少,或者当你更关心假阳性而不是假阴性时,你应该更喜欢 PR 曲线。否则,使用 ROC 曲线。

8. 创建一个基准分类模型

from sklearn.datasets import load_iris
from sklearn.dummy import DummyClassifier
from sklearn.model_selection import train_test_split

iris = load_iris()
features, target = iris.data, iris.target

# 划分数据集
features_train, features_test, target_train, target_test = train_test_split(features, target,
                                                                           random_state=0)

dummy = DummyClassifier(strategy='uniform', random_state=1)
dummy.fit(features_train, target_train)
print(f"Dummy Classifier Score: {dummy.score(features_test, target_test)}")

# 接下来我们创建自己的模型
from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier()
classifier.fit(features_train, target_train)
print(f"Random Forest Score: {classifier.score(features_test, target_test)}")

可以看出,随机森林模型效果更好。

9. 可视化训练集规模的影响

我们都知道,只要给我们足够多的数据集,那我们基本能训练一个效果很好的模型。接下来我们来看看如何绘制训练集大小对模型效果的影响(learning curve)。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_digits
from sklearn.model_selection import learning_curve

digits = load_digits()
features, target = digits.data, digits.target

# 使用交叉验证为不同规模的训练集计算训练和测试得分
train_sizes, train_scores, test_scores = learning_curve(RandomForestClassifier(),
                                                       features,
                                                       target,
                                                       cv=10,
                                                       scoring='accuracy',
                                                       n_jobs=-1,
                                                       train_sizes=np.linspace(0.01, 1, 50))

# 计算训练集得分的平均值和标准差
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)

test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)

plt.plot(train_sizes, train_mean, '--', color='black', label='Training score')
plt.plot(train_sizes, test_mean, color='black', label='Cross-validation score')
plt.fill_between(train_sizes, train_mean-train_std,
                train_mean + train_std, color='#DDDDDD')
plt.fill_between(train_sizes, test_mean-test_std,
                test_mean + test_std, color='#DDDDDD')
plt.title('Learning Curve')
plt.xlabel('Training Set Size')
plt.ylabel('Accuracy Score')
plt.legend(loc='best')
plt.tight_layout()
plt.show()

10. 生成评估指标报告

from sklearn.metrics import classification_report

iris = datasets.load_iris()
features = iris.data
target = iris.target
class_names = iris.target_names

features_train, features_test, target_train, target_test = train_test_split(
    features, target, random_state=1)

classifier = LogisticRegression()
model = classifier.fit(features_train, target_train)
target_predicted = model.predict(features_test)

# 生成分类器的性能报告
print(classification_report(target_test,
                           target_predicted,
                           target_names=class_names))

总结

本文系统介绍了机器学习模型评估的核心流程与关键指标。通过 sklearn 库的实战演示,涵盖了从数据集划分、交叉验证到各类评估指标(回归与分类)的计算方法。重点讲解了混淆矩阵、ROC-AUC 曲线及学习曲线的分析与绘制。掌握这些技能有助于科学地选择模型、诊断模型性能瓶颈并进行有效优化。在实际项目中,建议结合业务场景选择合适的评估指标,避免单一指标的局限性。

目录

  1. Python 数据分析:模型评估与选择实战
  2. 引言
  3. 1. 数据集划分
  4. 导入相关库
  5. 导入数据
  6. 划分数据集和测试集
  7. 2. 交叉验证模型
  8. 加载数据
  9. 创建特征矩阵
  10. 进行标准化
  11. 创建逻辑回归器
  12. 创建一个包含数据标准化和逻辑回归的流水线
  13. 创建 k 折交叉验证对象
  14. 进行 k 折交叉验证
  15. 划分数据集
  16. 使用训练集来计算标准化参数
  17. 然后在训练集和测试集上运用
  18. 3. 回归模型评估指标
  19. 导入相关库
  20. 建立模拟数据集
  21. 创建 LinearRegression 回归器
  22. 使用 MSE 对线性回归做交叉验证
  23. 使用 R² 进行交叉验证
  24. 4. 创建一个基准回归模型
  25. 加载数据
  26. 将数据分为测试集和训练集
  27. 创建 dummyregression 对象
  28. 训练模型
  29. 在测试集上评估
  30. 下面我们训练自己的模型进行对比
  31. 5. 混淆矩阵
  32. 导入相关库
  33. 加载数据
  34. 训练并预测
  35. 创建一个混淆矩阵
  36. 6. 分类评估指标
  37. 创建模拟数据集
  38. 创建逻辑回归器
  39. 使用准确率对模型进行交叉验证
  40. 使用 F1 分数
  41. 使用精确率
  42. 7. ROC 和 AUC
  43. 7.1 ROC 曲线
  44. 导入相关库
  45. 预测为 1 的概率
  46. 绘制 ROC 曲线
  47. 7.2 AUC 值
  48. 8. 创建一个基准分类模型
  49. 划分数据集
  50. 接下来我们创建自己的模型
  51. 9. 可视化训练集规模的影响
  52. 使用交叉验证为不同规模的训练集计算训练和测试得分
  53. 计算训练集得分的平均值和标准差
  54. 10. 生成评估指标报告
  55. 生成分类器的性能报告
  56. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Windows 系统安装与配置 Neo4j 图数据库指南
  • 2026 年度技术趋势预测:AI 从生成走向执行,八大方向重塑 IT 行业
  • 网络安全入门指南:核心技能与学习路线
  • OpenClaw vs AutoGPT:AI Agent 核心能力、部署与落地场景实测
  • 2026 年 3 月 GitHub 榜单深度解析:AI 代理与工业级落地
  • Spring Web 模块核心概念与 RESTful API 调用详解
  • 双延迟深度确定性策略梯度算法 (TD3) 详解与实现
  • 清华大学 AIGC 发展研究报告 4.0 节选
  • Nvidia Nemotron 3 Super 架构全解析:精度与效率兼顾的开源 LLM
  • Spring MVC 入门:MVC 模式与 RequestMapping 注解详解
  • 网络安全入门指南:技术方向与学习路线详解
  • 算法练习题解:哈希表、前缀和与贪心算法实战
  • 35 岁程序员失业危机:现状分析与破局策略
  • 9 款 AI 写作辅助工具与开题报告撰写优化指南
  • Web Unlocker API 实战:AI 训练数据集自动化获取方案
  • 基于 Python 的三角洲行动战术小队模拟器
  • Git 安装配置与基础工作流实战指南
  • Git 安装流程与基础使用步骤
  • SeaweedFS 轻量分布式存储:中小规模 LoRA 训练部署方案
  • AI 原生低代码平台的技术架构与核心能力解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online