重生之从零开始的神经网络算法学习之路——第二篇 深入Scikit-learn(分类问题与交叉验证)

昔日朱元璋在建立大明王朝的过程中,不仅需要攻城略地,更要懂得巩固治理、任用贤能。而今重生后的你,在掌握了线性回归这一"基本功"后,正面临着机器学习中更加复杂而精彩的分类世界。

前情回顾

在第一篇中,你成功使用线性回归算法预测了糖尿病进展,掌握了数据加载、模型训练、预测评估的完整流程。此刻,你站在新的起点上,准备探索机器学习中另一重要领域——分类问题。

分类问题:从回归到分类的思维转变

与回归问题预测连续值不同,分类问题旨在预测离散的类别标签。就像当年朱元璋需要判断一个城池是敌是友,而不是预测它能提供多少粮草。

为何选择随机森林和鸢尾花数据集?

随机森林是一种集成学习算法,通过构建多棵决策树并综合它们的预测结果来提高模型性能。而鸢尾花数据集是机器学习中最经典的数据集之一,包含三种鸢尾花的特征测量数据,非常适合作为分类算法的入门案例。(其实最重要的是该数据集是sklearn模块安装后自带的,虽然数据量小了点)

实验二:随机森林分类鸢尾花

1. 环境准备

确保已安装必要的库:

pip install scikit-learn matplotlib numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 代码实现

代码可以直接拉取,远程仓库代码地址:https://gitee.com/cmx1998/Scikit-Learning.git

  • 具体文件为Scikit-learn-2.py

3. 代码解析

这段代码实现了以下功能:

  1. 数据加载:使用Scikit-learn内置的鸢尾花数据集
  2. 数据分割:将数据分为训练集(80%)和测试集(20%)
  3. 模型训练:使用随机森林算法训练分类器
  4. 预测评估:在测试集上进行预测并评估模型性能
  5. 可视化输出:生成混淆矩阵和ROC曲线帮助理解模型表现
  • 导入所需模块
from sklearn.datasets import load_iris                  # 鸢尾花数据集
from sklearn.model_selection import train_test_split    # 训练集和测试集划分器
from sklearn.ensemble import RandomForestClassifier     # 随机森林分类器
from sklearn.metrics import ConfusionMatrixDisplay      # 混淆矩阵
from sklearn.metrics import classification_report       # 分类报告
from sklearn.metrics import roc_curve, auc              # ROC曲线
from sklearn.preprocessing import label_binarize
import matplotlib.pyplot as plt
import numpy as np
import os
  • 1、加载鸢尾花数据集
datasets_iris = load_iris()
X = datasets_iris.data
y = datasets_iris.target
class_names_en = datasets_iris.target_names
"""
    class_names_en =[
        np.str_('setosa'),      # 山鸢尾
        np.str_('versicolor'),  # 变色鸢尾
        np.str_('virginica')    # 维吉尼亚鸢尾
    ]
"""
feature_names_en = datasets_iris.feature_names
"""
    feature_names_en = [
        "sepal length (cm)",    # 萼片长度(厘米)
        "sepal width (cm)",     # 萼片宽度(厘米)
        "petal length (cm)",    # 花瓣长度(厘米)
        "petal width (cm)",     # 花瓣宽度(厘米)
    ]
"""
  • 2、划分训练集和测试集(80%训练,20%测试)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=0
)
  • 3、训练随机森林分类器,设置n_estimators=100
clf = RandomForestClassifier(n_estimators=100, max_depth=2, random_state=0)
clf.fit(X_train, y_train)
  • 4、在测试集上进行预测
y_pred = clf.predict(X_test)
# 获取预测概率
y_pred_proba = clf.predict_proba(X_test)
print("预测结果:", y_pred)
print("预测概率:", y_pred_proba)
  • 5、评估模型
# 评估模型
accuracy = np.mean(y_pred == y_test)

# 使用混淆矩阵评估模型
fig, ax = plt.subplots(figsize=(8, 6))
disp = ConfusionMatrixDisplay.from_estimator(
    clf, X_test, y_test,
    display_labels=class_names_zh,   # 使用中文类别名称
    cmap=plt.cm.Blues,
    ax=ax
)
disp.ax_.set_title("鸢尾花分类混淆矩阵")

# 5.2 使用分类报告评估模型
print(classification_report(y_test, y_pred, target_names=class_names_zh))   # 使用中文类别名称
  • 6、绘制ROC曲线
# 将标签二值化
y_test_bin = label_binarize(y_test, classes=[0, 1, 2])
n_classes = y_test_bin.shape[1]

# 计算每个类的ROC曲线和AUC
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test_bin[:, i], y_pred_proba[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])

# 绘制所有ROC曲线
plt.figure(figsize=(10, 8))
colors = ['blue', 'red', 'green']
for i, color in zip(range(n_classes), colors):
    plt.plot(fpr[i], tpr[i], color=color, lw=2,
             label='ROC curve of class {0} (AUC = {1:0.2f})'
             ''.format(class_names_zh[i], roc_auc[i]))   # 使用中文类别名称
  • 7、可视化输出结果
plt.show()

4. 运行结果

运行代码后,你将会看到类似以下的输出:

============================================================
实验二:随机森林分类鸢尾花
============================================================
正在加载鸢尾花数据集...
数据集形状: (150, 4)
类别数量: 3
类别名称(英文): setosa, versicolor, virginica
类别名称(中文): 山鸢尾, 变色鸢尾, 维吉尼亚鸢尾
特征数量: 4
特征名称(英文): sepal length (cm), sepal width (cm), petal length (cm), petal width (cm)
特征名称(中文): 萼片长度(厘米), 萼片宽度(厘米), 花瓣长度(厘米), 花瓣宽度(厘米)
训练集样本数: 120
测试集样本数: 30
训练随机森林分类器中...
训练完成!
预测结果: [2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0]
预测概率: [[3.03698509e-03 1.53453185e-01 8.43509830e-01]
 [1.23153175e-02 8.90456011e-01 9.72286716e-02]
 [8.99390614e-01 9.56772837e-02 4.93210188e-03]
 [0.00000000e+00 6.15016570e-02 9.38498343e-01]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]
 [2.17391304e-04 7.60205991e-02 9.23762010e-01]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]
 [1.13475756e-02 8.44337851e-01 1.44314574e-01]
 [1.01711050e-02 7.31929132e-01 2.57899763e-01]
 [1.23153175e-02 8.73717763e-01 1.13966919e-01]
 [8.00837651e-03 4.94787316e-01 4.97204308e-01]
 [1.13475756e-02 8.44337851e-01 1.44314574e-01]
 [1.23153175e-02 8.73717763e-01 1.13966919e-01]
 [1.13475756e-02 8.44337851e-01 1.44314574e-01]
 [1.23153175e-02 8.73717763e-01 1.13966919e-01]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]
 [1.23153175e-02 8.90456011e-01 9.72286716e-02]
 [1.28971465e-02 9.18119802e-01 6.89830520e-02]
 [9.89017347e-01 1.02419121e-02 7.40740741e-04]
 [9.88657197e-01 1.10725322e-02 2.70270270e-04]
 [5.95006419e-03 3.47424538e-01 6.46625398e-01]
 [3.28214137e-02 9.03072149e-01 6.41064373e-02]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]
 [9.79669521e-01 1.79230716e-02 2.40740741e-03]
 [3.34786171e-03 3.58295439e-01 6.38356699e-01]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]
 [1.13475756e-02 8.62248701e-01 1.26403724e-01]
 [2.03957115e-02 9.04045402e-01 7.55588866e-02]
 [9.96639179e-01 3.36082053e-03 0.00000000e+00]]
============================================================
模型性能评估
============================================================
准确率: 1.0000

混淆矩阵:
混淆矩阵已保存为 'img\iris_confusion_matrix.png'

分类报告:
              precision    recall  f1-score   support

         山鸢尾       1.00      1.00      1.00        11
        变色鸢尾       1.00      1.00      1.00        13
      维吉尼亚鸢尾       1.00      1.00      1.00         6

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

ROC曲线已保存为 'img\iris_roc_curve.png'
============================================================
实验二顺利完成!
============================================================

同时,程序还会生成混淆矩阵和ROC曲线的可视化结果。

深入理解

1. 随机森林算法原理

随机森林是一种集成学习方法,通过构建多棵决策树并综合它们的预测结果来提高模型性能。每棵树都是在随机选择的特征子集和数据子集上训练的,这种随机性有助于减少过拟合风险。

2. 评估指标解读

  • 准确率(Accuracy):正确预测的样本比例。在上述运行结果中,准确率为100%,意味着模型正确分类了所有的测试样本。这是一个非常理想的结果,在实际应用中很少见,主要得益于鸢尾花数据集的特征区分度很高。

  • 精确率(Precision):预测为正例的样本中实际为正例的比例。衡量模型的"查准"能力。所有类别的精确率均为1.00,表示模型没有误报。

  • 召回率(Recall):实际为正例的样本中被预测为正例的比例。衡量模型的"查全"能力。所有类别的召回率均为1.00,表示模型没有漏报。

  • F1分数:精确率和召回率的调和平均数,综合衡量模型的性能。所有类别的F1分数均为1.00,表明模型在各个类别上都达到了完美平衡。

结果分析:从分类报告可以看出,模型在所有三个类别上都表现完美(所有指标均为1.00)。这表明随机森林算法在处理鸢尾花这种特征区分度高的数据集时具有极佳的性能。预测概率的输出也显示了模型对每个预测的高置信度。

3. 多分类问题的ROC曲线

对于多分类问题,ROC曲线需要为每个类别分别绘制。从运行结果可以看出:

  • 山鸢尾(setosa):AUC = 1.00(完美分类)
  • 变色鸢尾(versicolor):AUC = 1.00(完美分类)
  • 维吉尼亚鸢尾(virginica):AUC = 1.00(完美分类)

所有类别的AUC值均为1.00,这表示模型对每个类别都具有完美的分类能力。AUC值为1是ROC曲线的理想状态,表示模型能够完全区分正例和负例。

完美性能的原因分析

  1. 鸢尾花数据集本身特征区分度高,不同类别的花在萼片和花瓣的测量值上有明显差异
  2. 随机森林算法适合处理这类特征区分度高的分类问题
  3. 数据量较小(150个样本),降低了模型的复杂度要求
  4. 特征数量适中(4个特征),既提供了足够信息又避免了维度灾难

交叉验证:提高模型评估的可靠性

1. 为什么需要交叉验证?

在之前的实验中,我们使用单一的训练-测试分割来评估模型性能。这种方法有一个明显缺点:评估结果可能受到数据分割随机性的影响。交叉验证通过多次不同的数据分割来评估模型,提供更可靠性能估计。

2. 交叉验证的实现

Scikit-learn提供了多种交叉验证方法,最常用的是k折交叉验证:

from sklearn.model_selection import cross_val_score

# 使用5折交叉验证评估随机森林模型
scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
print("交叉验证得分:", scores)
print("平均得分: {:.4f} (± {:.4f})".format(scores.mean(), scores.std() * 2))

3. 交叉验证的优势

  1. 更可靠的性能估计:通过多次评估减少随机性影响
  2. 充分利用数据:每个样本都被用于训练和测试
  3. 模型选择:帮助选择最佳模型和超参数

遇到的挑战与解决

在完成这个分类项目的过程中,你遇到了一些新挑战:

  1. 多分类问题的处理:通过了解One-vs-Rest和One-vs-One策略,理解多分类问题的处理方式
  2. ROC曲线的绘制:学习如何为多分类问题绘制ROC曲线,并理解Auc值的含义
  3. 评估指标的理解:区分准确率、精确率、召回率和F1分数的不同应用场景
  4. 完美性能的分析:理解为何模型能在鸢尾花数据集上达到完美性能,以及这在现实问题中的罕见性

结语

完成了鸢尾花分类项目后,你不仅掌握了随机森林这一强大算法,还深入理解了分类问题的评估方法和交叉验证的重要性。这就像朱元璋在建立明朝后,不仅拥有了强大的军队,还建立了完善的官僚制度来巩固统治。

值得注意的是,鸢尾花数据集上的完美性能在实际业务问题中并不常见。现实世界的数据往往更加复杂,存在噪声、缺失值和类别不平衡等问题。这个实验的价值在于让你熟悉分类问题的基本流程和评估方法,为处理更复杂的现实问题打下基础。

机器学习之路如同治国平天下,需要不断学习新的技能和方法。分类世界的大门已经向你敞开,前方还有更多精彩的算法和技术等待你去探索。


下集预告:第三篇 ???

posted on 2025-08-26 21:57  cmxcxd  阅读(15)  评论(0)    收藏  举报