机器学习03-sklearn模型评估指标与knn算法

发布于:2025-08-16 ⋅ 阅读:(10) ⋅ 点赞:(0)

前言:

回顾使用sklearn库进行及其学习的步骤:先获取数据集,再进行数据处理,如果遇到不是机器语言的数据,需要通过特征工程处理,包括特征降维等,最后使用估计器进行机器学习(也可以看作是训练模型的过程即fit操作)。对sklearn模型的评估指标就是用来验证模型性能的一些内容,比如准确率、召回率、混淆矩阵等,这也是本节的主要内容。开发者就可以根据这些指标更加直观的了解模型的性能情况。本节也会学习knn算法,即k近邻算法。

一、sklearn模型评估指标

1、估计器

  • 估计器的核心功能是:拟合数据、转换数据(与训练模型的fit_transform函数类似)

  • 估计器是任何能够从数据中学习的对象。

  • 关键特性:

特性 说明
定义 估计器是任何能够从数据中学习的对象,是 scikit-learn 中机器学习模型的核心抽象。
核心方法:fit - 所有估计器都必须实现 fit 方法。<br>- 输入:一个或多个数据集(如 X 和可选的 y)。<br>- 功能:从数据中学习模式(监督学习或无监督学习)。<br>- 返回:估计器实例本身。
其他常见方法 根据估计器类型不同,可能实现以下方法之一或多个:<br>- 分类器(Classifier):<br>  predict():预测类别标签<br>  predict_proba():预测类别概率<br>- 回归器(Regressor):<br>  predict():预测连续值输出<br>- 聚类器(Clusterer):<br>  predict():为新样本分配簇标签<br>  transform():降维或特征提取<br>- 转换器(Transformer):<br>  transform():对数据进行变换<br>  inverse_transform():将变换后的数据还原
状态存储(属性命名规范) - fit 调用后,估计器会保存其学习到的状态(如参数、模型等)。<br>- 这些内部状态以以下划线 _ 结尾的属性来存储,例如:<br>  coef_(系数)<br>  intercept_(截距)<br>  classes_(类别标签)

2、训练和生成模型

参数/内容 描述说明
方法名称 fit
作用 用于训练模型,即从数据中学习模式。根据输入的特征和目标变量(监督学习)或仅特征(无监督学习),估计模型参数。
调用时机 在创建模型实例后调用,通常在数据预处理之后、预测或评估之前。
输入参数 - x_train:训练数据的特征集(特征矩阵)。<br> 形状为 (n_samples, n_features),表示 n_samples 个样本,每个样本有 n_features 个特征。<br>- y_train:训练数据的目标变量(标签)。<br> 形状为 (n_samples,)(n_samples, n_targets),可选(取决于模型是否为监督学习)。
返回值 返回模型本身(即 self),允许链式调用,例如:model.fit().score()
对模型的影响 调用 fit 后,模型会保存学习到的参数,这些参数通常以以下划线 _ 结尾的属性形式存储,如 coef_intercept_classes_ 等。
注意事项 - x_trainy_train 需要是 NumPy 数组、Pandas DataFrame 或其他兼容数组类型。<br>- 特征通常需要进行标准化或归一化处理,尤其是对距离敏感的模型(如 KNN)。

3、模型评估指标

  • 模型得分*

    • score 方法:每一个估计器都有这一个方法,可以返回模型的性能指标

      • 分类模型:准确率

      • 回归模型:决定系数

      • score 方法的参数:x_test、y_test ---- 默认内部调用了 predict 方法,然后用预测的结果和 y_test 真是标签作比较

    • accuracy_score 方法:他也是返回一个准确率,需要单独导入

      • 参数:

        • y_true:测试集的真实标签

        • y_pred:测试集的预测标签

4、混淆矩阵*

  • 混淆矩阵是一个表格,展示了分类模型预测结果与真史结果之间的比较。它们可以帮助我们直观地看到模型在各个类别上的分类情况。

    • 比如:

    真实类别 预测概率
    0.6 猫
    0.7 猫
    0.2 猫
    • True、False、Positive、Negative

    • TP:实际是正例,预测结果也是正例,即真正例

    • FP:实际为负例,预测结果为正例,即假正例

    • FN:实际为正例,预测结果为负例,即假负例

    • TN:实际为负例,预测结果为负例,即真负例

  • 基于混淆矩阵的相关指标计算公式:

  • sklearn中计算出混淆矩阵的函数

    • 函数介绍

    项目 内容
    函数名 confusion_matrix
    所属模块 sklearn.metrics
    功能说明 计算分类模型的混淆矩阵,用于评估分类性能。矩阵中的每个元素表示预测类别与实际类别的样本数量。
    调用格式 confusion_matrix(y_true, y_pred, *, labels=None, sample_weight=None, normalize=None)
    • 参数说明

    参数名 类型 默认值 描述
    y_true array-like of shape (n_samples,) 真实标签(ground truth)
    y_pred array-like of shape (n_samples,) 模型预测的标签(predicted labels)
    labels array-like, optional None 标签列表,用于定义矩阵中类别的顺序;若为 None,则自动按出现顺序排列
    sample_weight array-like of shape (n_samples,), optional None 样本权重,可用于加权计算混淆矩阵
    normalize {'true', 'pred', 'all'}, optional None 是否对矩阵进行归一化:<br> - 'true': 每行归一化<br> - 'pred': 每列归一化<br> - 'all': 整体归一化
    • 返回值:

    返回值 类型 描述
    混淆矩阵 ndarray of shape (n_classes, n_classes) 返回一个二维数组,其中第 i 行 j 列的值表示真实为类别 i,预测为类别 j 的样本数
  • 案例代码:

#引入鸢尾花类
from sklearn.datasets import load_iris
#引入数据集划分函数
from sklearn.model_selection import train_test_split
#引入KNN分类器
from sklearn.neighbors import KNeighborsClassifier
#引入混淆矩阵
from sklearn.metrics import confusion_matrix
​
#获取数据集
iris=load_iris()
#获取数据集、标签
data,target=iris.data,iris.target
#划分训练集、测试集
X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.2,random_state=42)
#创建knn估计器---k=5
knn=KNeighborsClassifier(n_neighbors=5)
#训练模型
knn.fit(X_train,y_train)
#模型预测
y_predict=knn.predict(X_test)
#输出混淆矩阵
cm=confusion_matrix(y_test,y_predict)
print(cm)
  • 结果输出:

    [[10  0  0]
     [ 0  9  0]
     [ 0  0 11]]
  • 准确率:预测正确【TP+TN】的除以总共的数量【TP+TN+FP+FN】

  • 精确度:TP/(TP+FP) ---- 描述了预测正确的结果占有所有预测为正例的比例【查准率

  • 召回率:TP/(TP+FN) ---- 描述了正类样本是否被找到的一个比例【查全率

5、分类模型性能指标

  • 分类报告

    • classification_reportscikit-learn 库中 sklearn.metrics 模块提供的一种评估分类模型性能的工具。它能够生成一个详细的分类报告,其中包括多个重要的评估指标,如精确率(Precision)、召回率(Recall)、F1 分数(F1-Score)以及支持度(Support)等。这些指标提供了比单一准确率更全面的模型评估信息。

6、ROC和AUC

6.1ROC

  • ROC 曲线(Receiver Operating Characteristic Curve)是一种用于评估二分类模型(只有两个类别)性能的图形工具,尤其适用于不同阈值下模型表现的可视化分析

  • ROC 曲线是以假正率(FPR)为横坐标、真正率(TPR)为纵坐标的图形,它展示了分类器在不同阈值(threshold)下的性能变化情况

  • ROC:用于绘制ROC曲线。

    • 同一批样本,进行二分类时,对正负的判断是需要设置阀值的,当采用不同的阀值,样本被预测出的正负是不相同的,所以不同的阈值会预测可以会预测出不同的正负,同一批样本不同的正负预测结果就是得到不同的 FPR 和 TPR,所以不同的 (TPR,FPR) 就是很多点,这些点相邻的连接在一起 ROC 曲线了。

6.2AUC

  • ROC 曲线下的面积(Area Under the Curve),表示模型区分正类和负类的能力。

6.3AUC与ROC案例

  • 案例代码:

import numpy as np
# 导入roc和auc
from sklearn.metrics import roc_curve,auc
# 导入数据集
from sklearn.datasets import load_breast_cancer
# 导入数据集分割
from sklearn.model_selection import train_test_split
# 导入估计器
from sklearn.linear_model import LogisticRegression
​
#导入癌症数据集
cancer=load_breast_cancer()
data,target=cancer.data,cancer.target
​
#数据分割(划分训练集和测试集)
X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.2,random_state=42)
#创建估计器
estimate=LogisticRegression()
#拟合数据(类似于训练模型:fit_transform)
estimate.fit(X_train,y_train)
# 预测概率
"""
   predict:返回预测结果的标签
   predict_proba:返回预测结果的各个标签的概率值
"""
np.set_printoptions(suppress=True)#不输出科学计数法
y_predict=estimate.predict_proba(X_test)[:,1]#预测概率,获取预测概率的二分类概率
print(y_predict)
​
#计算roc
"""
   thresholds:阈值的结果就是从y_predict中筛选出来的,它筛选了能够引起结果变化的值作为阈值,
   但是第一个值不是从阈值中来的,而是max(y_predict)+1(可以从源码解释中找到)
"""
#计算fpr和tpr
fpr,tpr,thresholds=roc_curve(y_test,y_predict)#计算roc
print(thresholds)
​
#计算auc
auc_value=auc(fpr,tpr)
print(auc_value)
  • 结果输出:

[0.88156752 0.00000002 0.00532033 0.99439185 0.99782258 0.
 0.         0.01020612 0.99498697 0.97605777 0.94067645 0.00064452
 0.97990142 0.44393415 0.99100365 0.00182893 0.99430905 0.99959416
 0.99560944 0.00000037 0.84059109 0.96411482 0.         0.99310236
 0.98905268 0.99885321 0.9944082  0.9940906  0.98781048 0.00000006
 0.99509283 0.99618719 0.98884347 0.97729115 0.99749377 0.99633887
 0.00300325 0.99150777 0.00000516 0.89381172 0.99780315 0.00452311
 0.99833578 0.98654384 0.99853306 0.95132797 0.99817839 0.99347531
 0.90412536 0.99384942 0.00013775 0.00000001 0.93160939 0.99774558
 0.99865839 0.97240546 0.99692222 0.         0.81219653 0.99923898
 0.9724787  0.00000093 0.         0.97011642 0.98166975 0.9250362
 0.00014308 0.00000002 0.98925989 0.98773237 0.02421461 0.00005355
 0.98396536 0.08423926 0.9906121  0.99603021 0.90612353 0.6429675
 0.9948584  0.98506679 0.00120028 0.98987356 0.53345917 0.
 0.00083722 0.10348448 0.00359532 0.00000331 0.99256513 0.97562931
 0.94486409 0.91186567 0.90405388 0.99241004 0.99738368 0.99648298
 0.00000006 0.00000138 0.99928859 0.00018265 0.00009718 0.99969279
 0.00000007 0.00364185 0.93808451 0.79891799 0.98797606 0.
 0.94836704 0.73583098 0.00085141 0.99234471 0.20343522 0.        ]
[1.99969279 0.99969279 0.88156752 0.81219653 0.73583098 0.44393415
 0.20343522 0.        ]
0.9970520799213888
  • 总结:

"""
    ROC:在阈值取值不同的情况下,计算出来TPR和PR的值,然后以FPR为横坐标,TPR为纵坐标绘制出来的图像
​
    AUC:ROC曲线与x轴围起来的面积
​
    API:from sklearn.metrics import roc_curve,auc
"""

二、KNN算法

  • KNN:K 近邻算法

  • 原理:根据距离来判定输入的样本属于哪一个类别,我们首选确定需要计算输入样本其他已知样本的距离,选择距离最近的 k 个样本,然后统计 k 个样本中类别的信息

    • 第一种情况,k 个样本都是不一样的类别,那么新样本就类似于随机选择一个类别

    • 第二种情况,k 个样本中有一个类别的统计数量大于其他样本,那么新的样本就属于这个类别

    • 少数服从多数

  • 步骤:

    • 准备数据,对数据进行预处理

    • 计算测试新样本点到其他每个已知样本点的距离

    • 对每个距离进行排序,然后选择出距离最小的 K 个点

    • 对 K 个点所属的类别进行比较,按照少数服从多数的原则,将测试样本点归入到 K 个点中占比最高的一类中。

  • API:from sklearn.neighbors import KNeighborsClassifier

  • 超参数:n_neighbors=5---设置k值,即以多少个最近距离的已知样本作为参照物

  • 两个距离公式(欧几里得距离-直线距离、曼哈顿距离-城市街道距离)

    • 假设 a(x,y) b(x1,y1)

      • 欧氏距离:​

      • 曼哈顿距离:城市街区距离,​

  • 案例代码:

import numpy as np
#模型评估指标:准确率、混淆矩阵、分类报告
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
#knn核心API:计算新样本与所有已知样本的距离
from sklearn.neighbors import KNeighborsClassifier
#导入红酒数据集
from sklearn.datasets import load_wine
#导入划分数据集的包
from sklearn.model_selection import train_test_split
​
#加载红酒数据集
wine=load_wine()
#数据集、标签
data,target=wine.data,wine.target
print(target)
​
#划分训练集和测试集
X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.2,random_state=42)
​
#创建估计器----KNN----K=5
knn=KNeighborsClassifier(n_neighbors=5)
​
#投喂数据、拟合数据、训练模型
knn.fit(X_train,y_train)
​
#模型得分(accuracy_score方法)
y_predict=knn.predict(X_test)
acc=accuracy_score(y_test,y_predict)
print("准确率acc:",acc)
#模型得分(score方法)
score=knn.score(X_test,y_test)
print("准确率acc:",score)
​
#复习:混淆矩阵
cm=confusion_matrix(y_test,y_predict)
print("混淆矩阵:",cm)
​
#分类报告
cr=classification_report(y_test,y_predict)
print("分类报告:",cr)
​
#随机设置一个数据用来预测(二维数据:一条数据-13个特征,numpy数组类型)
my_data = np.array([[15, 1.5, 3.0, 18, 115, 2, 3, 0.20, 3, 6, 1.5, 4, 1001]])
​
#预测
result=knn.predict(my_data)
print("预测结果:",result)
print("预测结果:",wine.target_names[result])
print(knn.predict_proba(my_data))#预测概率,作用是:预测结果为0的概率是多少,预测结果为1的概率是多少
  • 结果输出:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
准确率acc: 0.7222222222222222
准确率acc: 0.7222222222222222
混淆矩阵: [[12  0  2]
 [ 0 11  3]
 [ 2  3  3]]
分类报告:               precision    recall  f1-score   support
​
           0       0.86      0.86      0.86        14
           1       0.79      0.79      0.79        14
           2       0.38      0.38      0.38         8
​
    accuracy                           0.72        36
   macro avg       0.67      0.67      0.67        36
weighted avg       0.72      0.72      0.72        36
​
预测结果: [0]
预测结果: ['class_0']
[[1. 0. 0.]]


网站公告

今日签到

点亮在社区的每一天
去签到