3.1 分类任务


文档摘要

3.1 分类任务 Scikit-learn 实践应用领域:分类任务详解 Scikit-learn (也称为 sklearn) 是 Python 中最受欢迎的机器学习库之一。它提供了丰富的工具和算法,涵盖了分类、回归、聚类、降维、模型选择和预处理等多个方面。在众多应用领域中,分类任务 是机器学习的核心任务之一,而 Scikit-learn 在分类任务中表现出色,提供了多种高效且易于使用的分类算法和评估工具。 3.1 分类任务详解 3.1.1 分类任务概述 分类任务是机器学习中的一种监督学习任务,其目标是根据已知的特征将数据样本划分到预定义的类别中。简单来说,分类模型学习从输入特征到离散类别标签的映射关系。 分类任务的常见应用场景: 垃圾邮件检测: 将邮件分为“垃圾邮件”和“非垃圾邮件”两类。

3.1 分类任务

Scikit-learn 实践应用领域:分类任务详解

Scikit-learn (也称为 sklearn) 是 Python 中最受欢迎的机器学习库之一。它提供了丰富的工具和算法,涵盖了分类、回归、聚类、降维、模型选择和预处理等多个方面。在众多应用领域中,分类任务 是机器学习的核心任务之一,而 Scikit-learn 在分类任务中表现出色,提供了多种高效且易于使用的分类算法和评估工具。

3.1 分类任务详解

3.1.1 分类任务概述

分类任务是机器学习中的一种监督学习任务,其目标是根据已知的特征将数据样本划分到预定义的类别中。简单来说,分类模型学习从输入特征到离散类别标签的映射关系。

分类任务的常见应用场景:

  • 垃圾邮件检测: 将邮件分为“垃圾邮件”和“非垃圾邮件”两类。

  • 图像识别: 识别图像中的物体,例如将图片分类为“猫”、“狗”、“汽车”等。

  • 医学诊断: 根据患者的症状和检查结果,判断患者是否患有某种疾病。

  • 客户流失预测: 预测哪些客户可能会流失,以便进行挽留。

  • 情感分析: 分析文本的情感倾向,例如将评论分为“正面”、“负面”或“中性”。

分类任务的类型:

  • 二分类: 将数据样本分为两个类别,例如“是/否”、“正/负”、“0/1”。

  • 多分类: 将数据样本分为两个以上的类别,例如“猫/狗/鱼”、“红/绿/蓝”。

  • 多标签分类: 一个数据样本可以同时属于多个类别,例如一篇新闻可以同时属于“政治”和“经济”类别。

3.1.2 Scikit-learn 中的分类算法

Scikit-learn 提供了丰富的分类算法,涵盖了各种不同的模型类型,包括:

  • 线性模型:

    • 逻辑回归 (Logistic Regression): 用于二分类和多分类,通过 sigmoid 函数将线性模型的输出映射到概率值。

    • 支持向量机 (Support Vector Machines, SVM): 通过寻找最优超平面进行分类,在高维空间中表现出色。

    • 线性判别分析 (Linear Discriminant Analysis, LDA): 假设每个类别的数据都服从高斯分布,通过寻找最优投影方向进行分类。

    • 岭回归分类器 (RidgeClassifier): 基于岭回归的分类器,适用于特征之间存在多重共线性的情况。

    • 被动攻击分类器 (PassiveAggressiveClassifier): 一种在线学习算法,适用于处理大规模数据流。

    • 感知器 (Perceptron): 最简单的神经网络模型,用于线性可分数据的二分类。

  • 基于树的模型:

    • 决策树 (Decision Tree): 通过树状结构进行分类,易于理解和解释。

    • 随机森林 (Random Forest): 集成学习方法,通过构建多个决策树并进行投票来提高分类性能和鲁棒性。

    • 梯度提升树 (Gradient Boosting Trees, GBT): 另一种集成学习方法,通过迭代地训练弱学习器 (通常是决策树) 来构建强分类器。

    • 极端梯度提升 (Extreme Gradient Boosting, XGBoost): 梯度提升树的一种高效实现,在各种机器学习竞赛中表现出色。

    • 轻量级梯度提升机 (LightGBM): 另一种高效的梯度提升框架,特别适用于大规模数据集。

    • CatBoost: 由 Yandex 开发的梯度提升算法,在处理类别特征方面具有优势。

  • 最近邻算法:

    • K 近邻 (K-Nearest Neighbors, KNN): 根据距离最近的 K 个邻居的类别进行投票分类,简单直观。
  • 朴素贝叶斯 (Naive Bayes):

    • 高斯朴素贝叶斯 (Gaussian Naive Bayes): 假设特征服从高斯分布。

    • 多项式朴素贝叶斯 (Multinomial Naive Bayes): 适用于离散特征,例如文本分类中的词频。

    • 伯努利朴素贝叶斯 (Bernoulli Naive Bayes): 适用于二元特征,例如文档中词语是否出现。

    • 补充朴素贝叶斯 (Complement Naive Bayes): 对不平衡数据集的朴素贝叶斯算法的改进。

  • 神经网络模型:

    • 多层感知器分类器 (MLPClassifier): 基本的前馈神经网络分类器。

3.1.3 分类模型的评估指标

选择合适的评估指标对于评估分类模型的性能至关重要。Scikit-learn 提供了多种评估指标,常用的包括:

  • 准确率 (Accuracy): 分类正确的样本数占总样本数的比例。适用于类别分布均衡的数据集。

  • 精确率 (Precision): 预测为正例的样本中,真正为正例的比例。关注模型预测正例的准确性。

  • 召回率 (Recall): 真正为正例的样本中,被模型预测为正例的比例。关注模型对正例的识别能力。

  • F1 值 (F1-score): 精确率和召回率的调和平均值,综合考虑了精确率和召回率。

  • AUC-ROC 曲线: 受试者工作特征 (Receiver Operating Characteristic) 曲线下的面积。用于评估二分类模型在不同阈值下的性能,尤其适用于不平衡数据集。

  • 混淆矩阵 (Confusion Matrix): 用于可视化分类结果,展示模型在各个类别上的预测情况。

  • 分类报告 (Classification Report): Scikit-learn 提供的便捷工具,包含精确率、召回率、F1 值和支持度 (每个类别的样本数量) 等指标。

3.1.4 分类任务的基本流程

使用 Scikit-learn 进行分类任务通常包括以下步骤:

  1. 数据准备:

    • 加载数据集。

    • 数据探索和可视化 (可选)。

    • 数据预处理:

      • 特征工程 (特征选择、特征构建)。

      • 数据清洗 (处理缺失值、异常值)。

      • 特征缩放 (标准化、归一化)。

      • 类别编码 (对于类别特征)。

    • 划分训练集和测试集。

  2. 模型选择:

    • 根据任务需求和数据特点选择合适的分类算法。

    • 考虑模型的复杂度、可解释性、训练速度和预测性能等因素。

  3. 模型训练:

    • 使用训练集数据训练选定的分类模型。

    • 设置模型超参数 (可选)。

  4. 模型评估:

    • 使用测试集数据评估模型的性能。

    • 选择合适的评估指标。

    • 分析评估结果,例如混淆矩阵、分类报告、AUC-ROC 曲线等。

  5. 模型优化 (可选):

    • 超参数调优 (例如使用 GridSearchCV 或 RandomizedSearchCV)。

    • 特征选择或特征工程改进。

    • 尝试不同的模型或模型组合。

  6. 模型部署 (可选):

    • 将训练好的模型部署到实际应用中。

3.2 分类任务代码实践及内容详解

接下来,我们将通过具体的代码示例,详细介绍如何使用 Scikit-learn 进行分类任务。我们将涵盖数据准备、模型选择、模型训练、模型评估和模型优化的各个环节。

3.2.1 数据准备

我们使用 Scikit-learn 内置的 iris (鸢尾花) 数据集作为示例。iris 数据集是一个经典的多分类数据集,包含 3 个类别 (setosa, versicolor, virginica) 的鸢尾花,每个类别包含 50 个样本。数据集包含 4 个特征:花萼长度 (sepal length)、花萼宽度 (sepal width)、花瓣长度 (petal length) 和花瓣宽度 (petal width)。

from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 1. 加载数据集 iris = load_iris() X = iris.data # 特征数据 y = iris.target # 类别标签 feature_names = iris.feature_names # 特征名称 target_names = iris.target_names # 类别名称 print("特征名称:", feature_names) print("类别名称:", target_names) print("数据形状:", X.shape) # (150, 4) - 150个样本,4个特征 print("类别分布:", set(y)) # {0, 1, 2} - 3个类别 # 2. 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y) # test_size=0.3: 测试集占总数据的 30% # random_state=42: 设置随机种子,保证结果可重复 # stratify=y: 分层抽样,保证训练集和测试集中各类别比例与原始数据集中一致 print("训练集数据形状:", X_train.shape) # (105, 4) print("测试集数据形状:", X_test.shape) # (45, 4) # 3. 特征缩放 (标准化) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) # fit_transform 在训练集上拟合和转换 X_test_scaled = scaler.transform(X_test) # transform 在测试集上使用训练集上学习到的参数进行转换 print("标准化后的训练集数据 (前 5 行):\n", X_train_scaled[:5])

代码详解:

  • load_iris(): 加载 iris 数据集。

  • iris.data: 获取特征数据 (NumPy 数组)。

  • iris.target: 获取类别标签 (NumPy 数组)。

  • iris.feature_names: 获取特征名称列表。

  • iris.target_names: 获取类别名称列表。

  • train_test_split(): 将数据集划分为训练集和测试集。

    • test_size: 设置测试集大小比例。

    • random_state: 设置随机种子,保证结果可重复。

    • stratify: 分层抽样,保持类别比例一致。

  • StandardScaler(): 创建标准化缩放器对象。

  • scaler.fit_transform(X_train): 在训练集上拟合标准化器并进行转换。

    • fit(): 计算训练集的均值和标准差。

    • transform(): 使用计算得到的均值和标准差对数据进行标准化。

  • scaler.transform(X_test): 使用在训练集上拟合的标准化器对测试集进行转换。注意:测试集只能使用训练集上学习到的参数进行转换,避免信息泄露。

数据预处理的重要性:

  • 特征缩放: 许多机器学习算法 (例如 KNN, SVM, 神经网络) 对特征的尺度敏感。特征缩放可以将不同尺度的特征统一到相似的尺度范围内,避免某些特征对模型训练产生过大的影响,提高模型的稳定性和收敛速度。标准化 (StandardScaler) 将数据缩放到均值为 0,标准差为 1 的分布;归一化 (MinMaxScaler) 将数据缩放到 0 到 1 的范围内。

3.2.2 模型选择和训练

我们选择逻辑回归 (Logistic Regression) 和支持向量机 (SVM) 两种常用的分类算法进行演示。

3.2.2.1 逻辑回归 (Logistic Regression)

from sklearn.linear_model import LogisticRegression # 1. 创建逻辑回归模型 logreg_model = LogisticRegression(random_state=42, solver='liblinear', multi_class='ovr') # random_state=42: 设置随机种子 # solver='liblinear': 选择求解器,适用于小数据集,对于大数据集可以考虑 'sag' 或 'saga' # multi_class='ovr': 使用 one-vs-rest (OvR) 策略处理多分类问题 # 2. 训练模型 logreg_model.fit(X_train_scaled, y_train) # 使用标准化后的训练集数据和训练集标签进行训练 print("逻辑回归模型训练完成!")

代码详解:

  • LogisticRegression(): 创建逻辑回归模型对象。

    • random_state: 设置随机种子。

    • solver: 选择优化算法求解器。'liblinear' 适用于小数据集,'sag''saga' 适用于大数据集。

    • multi_class: 处理多分类问题的策略。'ovr' (one-vs-rest) 将多分类问题分解为多个二分类问题;'multinomial' 直接进行多分类。

  • logreg_model.fit(X_train_scaled, y_train): 使用训练数据训练逻辑回归模型。

3.2.2.2 支持向量机 (SVM)

from sklearn.svm import SVC # 1. 创建 SVM 模型 svm_model = SVC(random_state=42, kernel='rbf', C=1.0, gamma='scale') # random_state=42: 设置随机种子 # kernel='rbf': 选择核函数,'rbf' (径向基函数) 是常用的非线性核函数,也可用 'linear', 'poly', 'sigmoid' 等 # C=1.0: 正则化参数,控制模型复杂度,C 值越大,模型越复杂,可能过拟合 # gamma='scale': 核函数参数,影响 RBF 核函数的宽度,'scale' 会根据特征维度自动调整 # 2. 训练模型 svm_model.fit(X_train_scaled, y_train) # 使用标准化后的训练集数据和训练集标签进行训练 print("SVM 模型训练完成!")

代码详解:

  • SVC(): 创建 SVM 分类模型对象 (Support Vector Classifier)。

    • random_state: 设置随机种子。

    • kernel: 选择核函数。常用的核函数包括:

      • 'linear': 线性核函数,适用于线性可分数据。

      • 'rbf': 径向基函数 (RBF) 核函数,适用于非线性可分数据,是默认核函数。

      • 'poly': 多项式核函数。

      • 'sigmoid': Sigmoid 核函数。

    • C: 正则化参数。C 值越大,模型越复杂,容错能力越低,可能过拟合;C 值越小,模型越简单,容错能力越高,可能欠拟合。

    • gamma: 核函数参数,影响 RBF 核函数的宽度。'scale' (默认值) 会根据特征维度自动调整;'auto' 会根据数据自动调整。也可以手动设置具体数值。

  • svm_model.fit(X_train_scaled, y_train): 使用训练数据训练 SVM 模型。

模型超参数:

  • 模型超参数是在模型训练之前设置的参数,而不是通过训练数据学习得到的。

  • 不同的模型有不同的超参数,例如逻辑回归的 Csolver,SVM 的 kernelCgamma,决策树的 max_depthmin_samples_split 等。

  • 超参数的选择会显著影响模型的性能。通常需要通过交叉验证和网格搜索 (GridSearchCV) 或随机搜索 (RandomizedSearchCV) 等方法进行超参数调优,找到最佳的超参数组合。

3.2.3 模型评估

我们使用测试集数据评估训练好的逻辑回归模型和 SVM 模型的性能,并使用多种评估指标。

from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, roc_auc_score, roc_curve import matplotlib.pyplot as plt import numpy as np # 1. 使用模型进行预测 y_pred_logreg = logreg_model.predict(X_test_scaled) # 逻辑回归模型预测 y_pred_svm = svm_model.predict(X_test_scaled) # SVM 模型预测 y_prob_logreg = logreg_model.predict_proba(X_test_scaled)[:, 1] # 逻辑回归模型预测概率 (用于 AUC-ROC) # predict_proba 返回每个样本属于每个类别的概率,[:, 1] 取出正例 (类别 1) 的概率,假设类别 1 为正例 # 2. 评估逻辑回归模型 print("逻辑回归模型评估:") print("准确率:", accuracy_score(y_test, y_pred_logreg)) print("\n分类报告:\n", classification_report(y_test, y_pred_logreg, target_names=target_names)) print("\n混淆矩阵:\n", confusion_matrix(y_test, y_pred_logreg)) # 3. 评估 SVM 模型 print("\nSVM 模型评估:") print("准确率:", accuracy_score(y_test, y_pred_svm)) print("\n分类报告:\n", classification_report(y_test, y_pred_svm, target_names=target_names)) print("\n混淆矩阵:\n", confusion_matrix(y_test, y_pred_svm)) # 4. 可视化混淆矩阵 (可选) def plot_confusion_matrix(cm, classes, title='Confusion matrix', cmap=plt.cm.Blues): """绘制混淆矩阵""" plt.imshow(cm, interpolation='nearest', cmap=cmap) plt.title(title) plt.colorbar() tick_marks = np.arange(len(classes)) plt.xticks(tick_marks, classes, rotation=45) plt.yticks(tick_marks, classes) thresh = cm.max() / 2. for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])): plt.text(j, i, format(cm[i, j], 'd'), horizontalalignment="center", color="white" if cm[i, j] > thresh else "black") plt.tight_layout() plt.ylabel('True label') plt.xlabel('Predicted label') import itertools plt.figure(figsize=(8, 6)) plot_confusion_matrix(confusion_matrix(y_test, y_pred_logreg), classes=target_names, title='Confusion matrix - Logistic Regression') plt.show() plt.figure(figsize=(8, 6)) plot_confusion_matrix(confusion_matrix(y_test, y_pred_svm), classes=target_names, title='Confusion matrix - SVM') plt.show()

代码详解:

  • accuracy_score(y_test, y_pred): 计算准确率。

  • classification_report(y_test, y_pred, target_names=target_names): 生成分类报告,包含精确率、召回率、F1 值和支持度。

  • confusion_matrix(y_test, y_pred): 生成混淆矩阵。

  • plot_confusion_matrix(): 自定义函数,用于可视化混淆矩阵 (使用了 matplotlib 库)。

  • logreg_model.predict(X_test_scaled): 使用逻辑回归模型在测试集上进行预测,返回预测的类别标签。

  • svm_model.predict(X_test_scaled): 使用 SVM 模型在测试集上进行预测,返回预测的类别标签。

  • logreg_model.predict_proba(X_test_scaled)[:, 1]: 对于逻辑回归模型,predict_proba 方法返回每个样本属于每个类别的概率。[:, 1] 假设类别 1 为正例,取出所有样本属于类别 1 的概率。注意:predict_proba 方法并非所有分类器都提供,例如 SVM 默认不提供概率预测。

评估指标详解:

  • 准确率:iris 数据集上,逻辑回归和 SVM 模型都取得了较高的准确率,说明模型整体分类效果较好。

  • 分类报告:

    • 精确率 (Precision): 例如,对于 setosa 类别,逻辑回归的精确率为 1.00,表示所有预测为 setosa 的样本中,100% 确实是 setosa

    • 召回率 (Recall): 例如,对于 setosa 类别,逻辑回归的召回率为 1.00,表示所有真实的 setosa 样本中,100% 被模型预测为 setosa

    • F1 值: 精确率和召回率的调和平均值,用于综合评价模型的性能。

    • 支持度 (Support): 每个类别在测试集中实际的样本数量。

  • 混淆矩阵:

    • 混淆矩阵的行表示真实类别,列表示预测类别。

    • 对角线上的数值表示分类正确的样本数量。

    • 非对角线上的数值表示分类错误的样本数量。

    • 通过混淆矩阵可以更详细地了解模型在各个类别上的分类情况,例如模型容易将哪个类别误判为哪个类别。

3.2.4 模型优化 (超参数调优)

我们使用 GridSearchCV (网格搜索交叉验证) 对 SVM 模型的超参数 Cgamma 进行调优。

from sklearn.model_selection import GridSearchCV # 1. 设置超参数网格 param_grid = {'C': [0.1, 1, 10, 100], 'gamma': ['scale', 'auto', 0.1, 1]} # C 的候选值: [0.1, 1, 10, 100] # gamma 的候选值: ['scale', 'auto', 0.1, 1] # 2. 创建 GridSearchCV 对象 grid_search = GridSearchCV(SVC(kernel='rbf', random_state=42), # 使用 SVM 模型 param_grid, # 超参数网格 cv=5, # 5 折交叉验证 scoring='accuracy') # 评估指标为准确率 # 3. 运行网格搜索 grid_search.fit(X_train_scaled, y_train) # 在训练集上进行网格搜索和交叉验证 # 4. 获取最佳模型和最佳超参数 best_svm_model = grid_search.best_estimator_ # 最佳模型 best_params = grid_search.best_params_ # 最佳超参数 best_score = grid_search.best_score_ # 最佳交叉验证分数 print("最佳 SVM 模型:", best_svm_model) print("最佳超参数:", best_params) print("最佳交叉验证准确率:", best_score) # 5. 使用最佳模型在测试集上评估 y_pred_best_svm = best_svm_model.predict(X_test_scaled) print("\n最佳 SVM 模型在测试集上的准确率:", accuracy_score(y_test, y_pred_best_svm)) print("\n最佳 SVM 模型分类报告:\n", classification_report(y_test, y_pred_best_svm, target_names=target_names)) print("\n最佳 SVM 模型混淆矩阵:\n", confusion_matrix(y_test, y_pred_best_svm))

代码详解:

  • GridSearchCV(): 创建 GridSearchCV 对象,用于网格搜索交叉验证。

    • SVC(kernel='rbf', random_state=42): 指定要进行超参数调优的模型,这里使用 RBF 核函数的 SVM 模型。

    • param_grid: 超参数网格,字典类型,键为超参数名称,值为超参数候选值列表。

    • cv=5: 设置 5 折交叉验证。

    • scoring='accuracy': 设置评估指标为准确率。

  • grid_search.fit(X_train_scaled, y_train): 在训练集上运行网格搜索和交叉验证。GridSearchCV 会遍历 param_grid 中所有超参数组合,对每种组合进行交叉验证,并记录交叉验证结果。

  • grid_search.best_estimator_: 获取在交叉验证中表现最佳的模型 (即使用最佳超参数组合训练的模型)。

  • grid_search.best_params_: 获取最佳超参数组合。

  • grid_search.best_score_: 获取最佳交叉验证分数 (根据 scoring 参数指定的评估指标)。

交叉验证 (Cross-Validation):

  • 交叉验证是一种评估模型泛化能力的方法,可以更可靠地评估模型在未见过的数据上的表现,避免模型在训练集上过拟合,而在测试集上表现不佳的情况。

  • K 折交叉验证 (K-Fold Cross-Validation) 将训练集划分为 K 个子集 (fold),每次选择其中 K-1 个子集作为训练集,剩下的 1 个子集作为验证集,进行 K 次训练和验证。最终的评估结果是 K 次验证结果的平均值。

  • GridSearchCV 中使用交叉验证来评估每种超参数组合的性能,选择交叉验证性能最佳的超参数组合。

网格搜索 (Grid Search):

  • 网格搜索是一种超参数调优方法,它通过遍历预定义的超参数网格中的所有超参数组合,并使用交叉验证评估每种组合的性能,最终选择性能最佳的超参数组合。

  • 网格搜索的缺点是当超参数数量较多或超参数候选值较多时,搜索空间会很大,计算量会显著增加。

其他超参数调优方法:

  • 随机搜索 (RandomizedSearchCV): 与网格搜索不同,随机搜索在超参数空间中随机采样一定数量的超参数组合进行评估。当超参数之间相互独立且对性能的影响程度差异较大时,随机搜索通常比网格搜索更高效。

  • 贝叶斯优化 (Bayesian Optimization): 一种更高级的超参数调优方法,使用贝叶斯模型来建模超参数与性能之间的关系,并根据模型预测选择下一组超参数进行评估,能够更有效地找到最佳超参数组合。

3.2.5 其他分类算法实践 (简要示例)

除了逻辑回归和 SVM,Scikit-learn 还提供了许多其他分类算法。下面我们简要演示如何使用决策树 (Decision Tree) 和随机森林 (Random Forest) 进行分类。

3.2.5.1 决策树 (Decision Tree)

from sklearn.tree import DecisionTreeClassifier # 1. 创建决策树模型 dt_model = DecisionTreeClassifier(random_state=42, max_depth=3) # 限制树的最大深度 # 2. 训练模型 dt_model.fit(X_train, y_train) # 决策树通常不需要特征缩放 # 3. 评估模型 y_pred_dt = dt_model.predict(X_test) print("决策树模型评估:") print("准确率:", accuracy_score(y_test, y_pred_dt)) print("\n分类报告:\n", classification_report(y_test, y_pred_dt, target_names=target_names)) print("\n混淆矩阵:\n", confusion_matrix(y_test, y_pred_dt)) # 4. 可视化决策树 (可选,需要安装 graphviz 和 pydotplus) # from sklearn.tree import export_graphviz # import graphviz # dot_data = export_graphviz(dt_model, out_file=None, # feature_names=feature_names, # class_names=target_names, # filled=True, rounded=True, # special_characters=True) # graph = graphviz.Source(dot_data) # graph.render("iris_decision_tree") # 保存为 PDF 文件

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U