欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > 机器学习分类算法模型性能的评估方法:数据集划分、交叉验证、准确率、性能指标、混淆矩阵、交叉熵损失

机器学习分类算法模型性能的评估方法:数据集划分、交叉验证、准确率、性能指标、混淆矩阵、交叉熵损失

2025/11/10 17:48:11 来源:https://blog.csdn.net/qq_55433305/article/details/148400766  浏览:    关键词:机器学习分类算法模型性能的评估方法:数据集划分、交叉验证、准确率、性能指标、混淆矩阵、交叉熵损失

本章都是以逻辑回归算法ogisticRegression为训练分类模型,以简单解释和代码展示评估方法和指标,以pima_data.csv 数据集(皮马印第安人糖尿病预测数据集),数据集和代码在以下链接https://github.com/KLWU07/Machine-learning-Project-practice。

一、交叉验证方法

  • K折交叉验证是一种评估模型性能的常用方法,适用于各种机器学习任务。它通过将数据集分成K个大小大致相等的子集(或称为“折”),然后进行K次训练和测试,每次使用一个子集作为测试集,其余K-1个子集作为训练集。这种方法可以充分利用有限的数据,减少因数据划分不同而导致的性能评估偏差。

1.K折交叉验证方法(10-fold Cross-Validation)

  • 交叉验证是一种评估模型性能的常用方法,通过将数据集分成多个子集,多次训练和测试模型,从而减少因数据划分不同而导致的性能评估偏差。
from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]# 设置交叉验证参数
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, shuffle=True, random_state=seed)# 创建一个Pipeline,包括标准化和逻辑回归
pipeline = Pipeline([('scaler', StandardScaler()),  # 数据标准化('classifier', LogisticRegression(max_iter=1000))  # 逻辑回归模型
])# 进行交叉验证
result = cross_val_score(pipeline, X, Y, cv=kfold)# 打印结果
print("算法评估结果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100))
算法评估结果:77.346% (4.689%)
  • 平均准确率它表示模型在所有测试集上的平均预测正确率。换句话说,模型在测试数据上正确预测了大约77.346%的样本。
  • 标准差。它表示模型在不同测试集上的准确率的波动程度。标准差越小,说明模型的性能越稳定,不同测试集上的准确率差异越小。

2.留一法交叉验证方法(Leave-One-Out Cross-Validation, LOOCV)

  • 留一法交叉验证是一种特殊的交叉验证方法,其中每次只留出一个样本作为测试集,其余所有样本作为训练集。这种方法在数据集较小时特别有用,因为它几乎利用了所有数据进行训练,从而减少了数据的浪费。
from pandas import read_csv
from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression# 导入数据
filename = 'pima_data.csv'  # 确保路径正确
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
# 设置留一法交叉验证
loocv = LeaveOneOut()
# 创建逻辑回归模型
model = LogisticRegression(max_iter=1000)  # 增加最大迭代次数
# 进行交叉验证
result = cross_val_score(model, X, Y, cv=loocv)
# 打印结果
print("算法评估结果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100))
算法评估结果:77.604% (41.689%)  # 平均准确率和标准差

3.随机划分的交叉验证方法(与1有区别)

  • ShuffleSplit是一种随机划分的交叉验证方法,它会随机划分训练集和测试集多次,从而提供模型性能的统计估计。这种方法特别适用于数据集较小时,因为它可以多次随机划分数据,减少因数据划分不同而导致的性能评估偏差。
  • n_splits=5,那么数据集将被随机划分5次,每次划分都会生成一个新的训练集和测试集。
  • test_size=0.2,那么每次划分时,大约20%的数据将被用作测试集,其余80%的数据将被用作训练集。
    如果这里我把n_splits=10,test_size=0.1,结果会不会和1一样,当然不一样,因为10折随机划10个大小大致相等的子集对于每个fold,将该fold用作测试集,将剩余的9个fold合并用作训练集,在训练集上训练模型,在测试集上评估模型的性能。依次每个fold都会成为测试集。
from pandas import read_csv
from sklearn.model_selection import ShuffleSplit
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
n_splits = 10
test_size = 0.1
seed = 7
kfold = ShuffleSplit(n_splits=n_splits, test_size=test_size, random_state=seed)
model = LogisticRegression(max_iter=1000)
result = cross_val_score(model, X, Y, cv=kfold)
print("算法评估结果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100))
算法评估结果:78.182% (5.221%)

4.简单指定划分数据集比例,无交叉验证

from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
test_size = 0.3
seed = 7
X_train, X_test, Y_traing, Y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
model = LogisticRegression(max_iter=1000)
model.fit(X_train, Y_traing)
result = model.score(X_test, Y_test)
print("算法评估结果:%.3f%%" % (result * 100))
算法评估结果:77.922%

二、统计指标评估的方法

1.准确率(Accuracy)

  • 概念:准确率是最直观的指标,它表示模型正确预测的样本数占总样本数的比例。计算公式为
    准确率 = 总样本数 正确预测的样本数 准确率=\frac{总样本数}{正确预测的样本数} 准确率=正确预测的样本数总样本数

  • 适用场景:当数据集类别分布比较均衡时,准确率是一个很好的指标。例如在一个二分类问题中,正样本和负样本数量大致相等,准确率可以很好地反映模型的性能。

  • 这与一里1,10折交叉验证方法相同,这里没有使用数据标准化

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,shuffle=True, random_state=seed)
model = LogisticRegression(max_iter=1000)
result = cross_val_score(model, X, Y, cv=kfold)
print("算法评估结果准确度:%.3f%% (%.3f%%)" % (result.mean(), result.std()))
算法评估结果准确度:0.772% (0.050%)

2.ROC - AUC(Receiver Operating Characteristic - Area Under Curve)计算ROC曲线下面积(AUC)

  • 概念:ROC曲线是以真正例率(召回率)为纵坐标,假正例率(1 - 精确率)为横坐标绘制的曲线。AUC是ROC曲线下的面积,AUC值越大,模型性能越好。
  • 适用场景:适用于二分类问题,尤其是在类别不平衡的情况下。例如在信用评估模型中,AUC可以很好地衡量模型区分好客户和坏客户的能力。
from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,shuffle=True, random_state=seed)
model = LogisticRegression(max_iter=1000)
scoring = 'roc_auc'
result = cross_val_score(model, X, Y, cv=kfold, scoring=scoring)
print('AUC %.3f (%.3f)' % (result.mean(), result.std()))
AUC 0.829 (0.047)
  • AUC值为0.829表明模型具有较好的区分能力,能够较好地预测患者是否患有糖尿病。
  • 标准差为0.047表明模型在不同数据子集上的表现较为稳定,没有出现较大的波动。

3.分类报告(classification report)

  • 分类报告(Classification Report)是一种用于评估分类模型性能的工具,它综合了多个关键指标,以表格形式展示模型在各个类别上的表现。分类报告通常包含以下主要部分:精确率(Precision)、召回率(Recall)、F1 - score 和 支持度(Support)。此外,它还会提供 宏平均(Macro - avg) 和 加权平均(Weighted - avg) 等综合指标。

(1)精确率(Precision)

  • 定义:精确率衡量的是模型预测为正类的样本中,实际为正类的比例。精确率越高,说明模型预测为正类的样本越可靠。计算公式为:
    精确率 = 真正例( T P ) 真正例( T P ) + 假正例( F P ) ​ 精确率=\frac{ 真正例(TP) }{ 真正例(TP)+假正例(FP)} ​ 精确率=真正例(TP+假正例(FP真正例(TP)
    (2)召回率(Recall)
  • 定义:召回率衡量的是所有实际为正类的样本中,模型正确预测为正类的比例。召回率越高,说明模型能够更好地识别出实际为正类的样本。计算公式为:
    召回率 = 真正例( T P ) 真正例( T P ) + 假负例( F N ) ​ 召回率= \frac{ 真正例(TP) }{ 真正例(TP)+假负例(FN)} ​ 召回率=真正例(TP+假负例(FN真正例(TP)
    (3)F1 - score
  • 定义:F1 - score 是精确率和召回率的调和平均数,用于综合评估模型的性能。F1 - score 越高,说明模型在精确率和召回率之间取得了较好的平衡。计算公式为:
    F 1 − s c o r e = 2 × 精确率 × 召回率 精确率 + 召回率 ​ F1 - score= 2× \frac{ 精确率×召回率 }{ 精确率+召回率} ​ F1score=2×精确率+召回率精确率×召回率
    (4)支持度(Support)
  • 定义:支持度表示每个类别在测试集中实际的样本数量。支持度可以帮助我们了解模型在不同类别上的样本量分布情况,从而更好地评估模型的性能。
    (5)宏平均(Macro - avg)
  • 定义:宏平均是将每个类别的指标(精确率、召回率、F1 - score)分别计算平均值,不考虑每个类别的样本数量。宏平均对所有类别给予相同的权重,适用于类别数量较少且类别之间样本数量差异不大的情况。
    (6)加权平均(Weighted - avg)
  • 定义:加权平均是根据每个类别的样本数量对指标(精确率、召回率、F1 - score)进行加权平均。加权平均考虑了每个类别的样本数量,适用于类别数量较多且类别之间样本数量差异较大的情况。
from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
test_size = 0.33
seed = 4
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
model = LogisticRegression(max_iter=1000)
model.fit(X_train, Y_train)
predicted = model.predict(X_test)
report = classification_report(Y_test, predicted)
print(report)

结果

类别精确率(Precision)召回率(Recall)F1 - score支持度(Support)
正类(1)0.840.870.86171
负类(0)0.710.660.6983
accuracy0.80254
宏平均(Macro - avg)0.780.770.77254
加权平均(Weighted - avg)0.800.800.80254

4.混淆矩阵(Confusion Matrix)

  • 混淆矩阵(Confusion Matrix)是评估分类模型性能的一种重要工具。它是一个表格,用于描述分类模型在测试数据上的预测结果与实际标签之间的关系。混淆矩阵能够直观地展示模型的预测准确性,帮助我们理解模型在各个类别上的表现。通过混淆矩阵,我们可以计算出多种评估指标,这些指标从不同角度反映了模型的性能,准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1 - score。

例如二类

预测为负类(Negative)预测为正类(Positive)
实际为负类真负例(TN)假正例(FP)
实际为正类*假负例(FN)真正例(TP)

真正例(True Positive, TP):模型正确预测为正类的样本数。
假正例(False Positive, FP):模型错误预测为正类的样本数(实际为负类)。
假负例(False Negative, FN):模型错误预测为负类的样本数(实际为正类)。
真负例(True Negative, TN):模型正确预测为负类的样本数。

from pandas import read_csv
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
test_size = 0.33
seed = 4
X_train, X_test, Y_traing, Y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
model = LogisticRegression(max_iter=1000)
model.fit(X_train, Y_traing)
predicted = model.predict(X_test)
matrix = confusion_matrix(Y_test, predicted)
classes = ['0', '1']
dataframe = pd.DataFrame(data=matrix,index=classes,columns=classes)
print(dataframe)
     0   1
0  149  22
1   28  55

三、交叉熵损失(Cross - Entropy Loss)

  • 交叉熵损失(Cross - Entropy Loss)是一种常用的损失函数,尤其在分类任务中应用广泛。它衡量的是模型预测的概率分布与真实标签的概率分布之间的差异。交叉熵损失越小,说明模型的预测结果越接近真实标签。

1.对数损失(Log Loss)/逻辑损失(Logistic Loss)

  • 对数损失越小越好:对数损失越小,表示模型的预测越接近真实标签。
  • 对数损失对概率预测的惩罚是指数级的:如果模型对错误的预测非常有信心(即预测概率接近0或1),对数损失会非常大。这使得对数损失对模型的不确定性有很强的惩罚。
  • 对数损失适用于二分类问题:对于多分类问题,对数损失可以扩展为多分类对数损失(Multiclass Log Loss)。
from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,  shuffle=True,random_state=seed)
model = LogisticRegression(max_iter=1000)
scoring = 'neg_log_loss'
result = cross_val_score(model, X, Y, cv=kfold, scoring=scoring)
print('Logloss %.3f (%.3f)' % (result.mean(), result.std()))
Logloss -0.485 (0.057)

四、完整的示例代码

import pandas as pd
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, roc_auc_score
from sklearn.preprocessing import LabelBinarizer# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = pd.read_csv(filename, names=names)# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]# 划分训练集和测试集
test_size = 0.33
seed = 4
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)# 训练逻辑回归模型
model = LogisticRegression(max_iter=1000)
model.fit(X_train, Y_train)# 预测测试集结果
predicted = model.predict(X_test)# 计算准确率
accuracy = accuracy_score(Y_test, predicted)
print(f'准确率(Accuracy): {accuracy:.4f}')# 生成混淆矩阵
matrix = confusion_matrix(Y_test, predicted)
print('混淆矩阵(Confusion Matrix):')
print(matrix)# 生成分类报告
report = classification_report(Y_test, predicted, target_names=['Negative', 'Positive'])
print('分类报告(Classification Report):')
print(report)# 计算ROC - AUC
lb = LabelBinarizer()
Y_test_binarized = lb.fit_transform(Y_test)
predicted_prob = model.predict_proba(X_test)[:, 1]
roc_auc = roc_auc_score(Y_test_binarized, predicted_prob)
print(f'ROC - AUC: {roc_auc:.4f}')# 交叉验证
cv_scores = cross_val_score(model, X, Y, cv=5, scoring='accuracy')
print(f'交叉验证准确率(Cross - Validation Accuracy): {cv_scores.mean():.4f} ± {cv_scores.std():.4f}')

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词