15、模型评估:准确率、混淆矩阵及相关指标解析

模型评估核心指标解析

模型评估:准确率、混淆矩阵及相关指标解析

1. 准确率(Accuracy)

在数据分析中,准确率是一个常用的评估指标。例如,我们的数据集可能具有高达 96% 的零准确率(null accuracy)。这意味着,如果构建一个简单的模型,对所有结果都预测为多数类,该模型也能达到 96% 的准确率。后续我们会探讨在改变训练集和测试集划分时,零准确率会如何变化。

1.1 准确率的优点
  • 易于使用 :准确率的计算和理解都很简单,它只是一个简单的分数公式。
  • 相比其他技术更受欢迎 :由于它是最容易计算的指标,所以最为流行。它也是评估模型的第一步,大多数数据科学入门书籍都会将准确率作为评估指标进行讲解。
  • 适合比较不同模型 :当使用不同模型解决问题时,可以信赖准确率最高的模型。
1.2 准确率的局限性
  • 无法反映响应变量的分布 :准确率无法提供关于响应/因变量分布的信息。例如,若模型准确率为 80%,我们无法得知响应变量的分布情况以及数据集的零准确率。如果数据集的零准确率高于 70%,那么一个准确率为 80% 的模型可能没什么用处。
  • 无法体现第一类和第二类错误 :准确率也无法提供关于模型第一类和第二类错误的信息。第一类错误是指实际为负类却被预测为正类,第二类错误是指实际为正类却被预测为负类。
2. 不平衡数据集(Imbalanced Datasets)

不平衡数据集是分类问题中的一种特殊情况,其中各类之间的分布差异很大。在这类数据集中,某一类占绝对优势,即不平衡数据集的零准确率非常高。

例如,在信用卡欺诈检测的数据集中,绝大多数交易是正常交易,只有极少数是欺诈交易。如果用 1 表示欺诈交易,0 表示正常交易,那么数据集中会有很多 0,几乎没有 1,数据集的零准确率可能超过 99%。这表明多数类(这里是 0)远远多于少数类(这里是 1),这样的数据集就是不平衡数据集。

3. 处理不平衡数据集的方法

在机器学习中,有两种方法可以克服不平衡数据集的缺点:
- 采样技术 :可以使用特殊的采样技术来减轻数据集的不平衡,通过选择训练和测试数据,使所有类都有足够的代表性。例如,对少数类进行过采样(从少数类中获取更多样本),或者对多数类进行欠采样(从多数类中获取较少样本)。然而,如果数据高度不平衡,零准确率高于 90%,那么任何采样技术都无法正确反映实际数据,可能会导致过拟合。因此,最好的方法是修改评估技术。
- 修改模型评估技术 :处理高度不平衡的数据集时,修改模型评估技术是更好的选择,这是获得良好结果最可靠的方法。除了准确率,还有许多其他评估指标可以用于评估模型。要学习这些技术,需要理解混淆矩阵的概念。

4. 混淆矩阵(Confusion Matrix)

混淆矩阵用于描述分类模型的性能,是总结分类器性能的一种方式。以下是一个基本的混淆矩阵示例代码:

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred_class)
print(cm)

混淆矩阵中各缩写的含义如下:
| 缩写 | 含义 |
| ---- | ---- |
| TN(True negative) | 实际为负类且被正确预测为负类的结果数量 |
| FP(False positive) | 实际为负类但被错误预测为正类的结果数量,也称为第一类错误 |
| FN(False negative) | 实际为正类但被错误预测为负类的结果数量,也称为第二类错误 |
| TP(True positive) | 实际为正类且被正确预测为正类的结果数量 |

所有机器学习和深度学习算法的目标都是最大化 TN 和 TP,最小化 FN 和 FP。以下是计算 TN、FP、FN 和 TP 的示例代码:

##True Negative
TN = cm[0, 0]
##False Negative
FN = cm[1, 0]
##False Positives
FP = cm[0, 1]
##True Positives
TP = cm[1, 1]
5. 从混淆矩阵计算的指标

从混淆矩阵可以导出多个指标,包括灵敏度、特异度、精确率、假阳性率、ROC 曲线和 AUC:
- 灵敏度(Sensitivity) :也称为召回率或真阳性率,是正预测数量除以实际正类的总数。在患者再入院的例子中,就是被分类为 1 的患者总数除以实际为 1 的患者总数。公式为:$Sensitivity = \frac{TP}{TP + FN}$。在患者再入院等情况下,需要模型具有高灵敏度,因为将 1 预测为 0 会导致严重后果。
- 特异度(Specificity) :是负预测数量除以实际负类的总数,也称为真阴性率。公式为:$Specificity = \frac{TN}{TN + FP}$。在垃圾邮件检测等情况下,需要算法具有更高的特异度,因为将非垃圾邮件分类为垃圾邮件会导致重要邮件丢失。
- 精确率(Precision) :是真阳性预测数量除以正预测的总数。公式为:$Precision = \frac{TP}{TP + FP}$。
- 假阳性率(False Positive Rate,FPR) :是假阳性事件数量与实际负类事件总数的比率,也等于 1 - 特异度。公式为:$False\ positive\ rate = \frac{FP}{FP + TN}$。
- 受试者工作特征曲线(Receiver Operating Characteristic,ROC) :是真阳性率(灵敏度)和假阳性率(1 - 特异度)之间的关系图。通过观察 ROC 曲线左上角的空白区域大小来判断曲线的优劣,空白区域越小越好。
- 曲线下面积(Area Under Curve,AUC) :是 ROC 曲线下的面积,也称为 AUROC。AUC 是一个数值,代表 ROC 曲线下的面积,面积越大越好。

以下是这些指标的计算流程 mermaid 图:

graph LR
    A[混淆矩阵] --> B[计算 TN, FP, FN, TP]
    B --> C[计算灵敏度]
    B --> D[计算特异度]
    B --> E[计算精确率]
    B --> F[计算假阳性率]
    C --> G[绘制 ROC 曲线]
    G --> H[计算 AUC]
6. 练习:使用医疗数据计算准确率和零准确率

本练习的目标是预测哪些患者在出院后 30 天内会再次入院。数据集可从 GitHub 仓库 下载。

6.1 数据预处理和探索性数据分析
  1. 导入所需库,加载并探索数据集
import numpy as np
import pandas as pd
patient_data = pd.read_csv("Health_Data.csv")
patient_data.head()
  1. 描述数据集中的数值和分类值
# 数值数据摘要
patient_data.describe()
# 分类数据摘要
patient_data.describe(include=['object'])
  1. 分离自变量和因变量
mydata = pd.read_csv("Health_Data.csv")
X = mydata.iloc[:, 1:9]
y = mydata.iloc[:, 9]
  1. 创建分类变量的虚拟变量
A_type = pd.get_dummies(X.iloc[:, 1], drop_first=True, prefix='Atype')
New_gender = pd.get_dummies(X.iloc[:, 4], drop_first=True, prefix='Gender')
Pre_exdis = pd.get_dummies(X.iloc[:, 2], drop_first=True, prefix='PreExistDis')
X.drop(['Admission_type', 'PreExistingDisease', 'Gender'], axis=1, inplace=True)
X = pd.concat([X, A_type, New_gender, Pre_exdis], axis=1)
  1. 划分训练集和测试集
from sklearn.model_selection import train_test_split
xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.30, random_state=110)
  1. 数据标准化
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
xtrain = sc.fit_transform(xtrain)
xtrain = pd.DataFrame(xtrain, columns=xtest.columns)
xtest = sc.transform(xtest)
xtest = pd.DataFrame(xtest, columns=xtrain.columns)
  1. 将数据转换为 NumPy 数组
x_train = xtrain.values
x_test = xtest.values
y_train = ytrain.values
y_test = ytest.values
6.2 构建神经网络并计算准确率
  1. 导入创建神经网络所需的库
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
  1. 初始化顺序模型
model = Sequential()
  1. 添加第一层全连接层和 Dropout 层
model.add(Dense(units=6, activation='relu', kernel_initializer='uniform', input_dim=11))
model.add(Dropout(rate=0.3))
  1. 添加第二层全连接层和 Dropout 层
model.add(Dense(units=6, activation='relu', kernel_initializer='uniform'))
model.add(Dropout(rate=0.3))
  1. 添加输出层
model.add(Dense(units=1, activation='sigmoid', kernel_initializer='uniform'))
  1. 编译模型
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
  1. 拟合模型
model.fit(x_train, y_train, epochs=100, batch_size=20)
  1. 进行预测
y_pred_class = model.predict(x_test)
y_pred_prob = model.predict_proba(x_test)
  1. 设置分类阈值
y_pred_class = y_pred_class > 0.5
  1. 计算准确率
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_pred_class)
6.3 计算零准确率
  1. 计算不同类别的数量
ytest.value_counts()
  1. 计算零准确率
ytest.value_counts().head(1) / len(ytest)

通过以上步骤,我们完成了使用医疗数据计算准确率和零准确率的练习。在实际应用中,需要综合考虑各种评估指标,以确保模型的性能符合需求。特别是在处理不平衡数据集时,不能仅仅依赖准确率,还需要关注混淆矩阵及其衍生的指标。

模型评估:准确率、混淆矩阵及相关指标解析

7. 指标分析与实际应用考虑

在实际应用中,不同的指标有着不同的侧重点和适用场景。我们需要根据具体的业务问题来选择合适的评估指标。

7.1 灵敏度和特异度的权衡

灵敏度和特异度往往是相互制约的。在某些情况下,我们可能需要提高灵敏度,例如在医疗诊断中,漏诊(将患病患者预测为未患病)可能会导致严重的后果,所以需要模型尽可能准确地识别出所有患病患者,此时应更注重灵敏度。而在另一些情况下,如垃圾邮件检测,误判(将正常邮件标记为垃圾邮件)可能会导致重要信息的丢失,这时就需要提高特异度。

以下是一个简单的表格来对比不同场景下对灵敏度和特异度的侧重:
| 场景 | 侧重指标 | 原因 |
| ---- | ---- | ---- |
| 医疗诊断 | 灵敏度 | 避免漏诊患者 |
| 垃圾邮件检测 | 特异度 | 防止正常邮件被误判为垃圾邮件 |

7.2 ROC 曲线和 AUC 的应用

ROC 曲线和 AUC 提供了一种直观的方式来评估模型的性能。ROC 曲线展示了灵敏度和特异度之间的关系,而 AUC 则是一个综合的指标,反映了模型在不同阈值下的整体性能。

在比较多个模型时,我们可以通过比较它们的 ROC 曲线和 AUC 值来选择最优模型。一般来说,AUC 值越大,模型的性能越好。例如,在图 6.8 中,红色曲线的 AUC 大于蓝色曲线,说明红色曲线对应的模型性能更优。

8. 模型优化与改进

在实际应用中,我们往往需要对模型进行优化和改进,以提高其性能。以下是一些常见的方法:

8.1 调整模型参数

在构建神经网络时,我们可以调整各种参数,如神经元数量、激活函数、学习率等。例如,在前面的练习中,我们可以尝试不同的神经元数量和 Dropout 率,以找到最优的模型配置。

# 调整神经元数量和 Dropout 率
model = Sequential()
model.add(Dense(units=8, activation='relu', kernel_initializer='uniform', input_dim=11))
model.add(Dropout(rate=0.2))
model.add(Dense(units=8, activation='relu', kernel_initializer='uniform'))
model.add(Dropout(rate=0.2))
model.add(Dense(units=1, activation='sigmoid', kernel_initializer='uniform'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=120, batch_size=25)
8.2 特征工程

特征工程是提高模型性能的重要手段。我们可以通过选择更有价值的特征、创建新的特征或对现有特征进行变换来改善模型的表现。在前面的医疗数据练习中,我们对分类变量进行了虚拟编码,这就是一种简单的特征工程方法。

以下是一个 mermaid 图展示模型优化的一般流程:

graph LR
    A[原始模型] --> B[调整模型参数]
    A --> C[特征工程]
    B --> D[评估模型性能]
    C --> D
    D --> E{性能是否满足要求}
    E -- 是 --> F[最终模型]
    E -- 否 --> B
9. 总结与展望

通过对准确率、混淆矩阵及相关指标的学习,我们了解到在模型评估中不能仅仅依赖单一的指标,特别是在处理不平衡数据集时,需要综合考虑各种指标。混淆矩阵及其衍生的指标为我们提供了更全面的模型性能评估方法。

在未来的工作中,我们可以进一步探索更复杂的模型评估技术和优化方法。例如,尝试使用集成学习方法来提高模型的性能,或者结合领域知识进行更深入的特征工程。同时,随着数据量的不断增加和计算能力的提升,我们可以使用更复杂的模型结构,如深度学习中的卷积神经网络(CNN)和循环神经网络(RNN),来解决更具挑战性的问题。

总之,模型评估是一个不断迭代和优化的过程,我们需要根据具体的业务需求和数据特点选择合适的评估指标和优化方法,以构建出性能优良的模型。

希望通过本文的介绍,你对模型评估有了更深入的理解,并能够在实际应用中灵活运用这些知识。在实际项目中,不断尝试和实践,结合具体问题进行分析和优化,才能真正掌握模型评估的精髓。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值