分类模型混淆矩阵:从枯燥到精美的可视化升级

背景

图片

混淆矩阵是分类模型评估中必不可少的工具,它能够直观展示模型在不同类别上的预测表现。然而,传统的混淆矩阵往往缺乏美感,信息表达不够直观,不利于数据分析结果的分享和解读。

本篇文章将以分类模型的混淆矩阵为例,介绍如何通过数据可视化技巧对混淆矩阵进行美化。在保持信息完整性的基础上,我们将利用颜色映射、文字标注等方式,让混淆矩阵更加清晰直观,从而提升其在报告和展示中的表达效果。

代码实现

二分类模型实现

模型构建

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltplt.rcParams['font.family'] = 'Times New Roman'plt.rcParams['axes.unicode_minus'] = Falseimport warnings# 忽略所有警告warnings.filterwarnings("ignore")from sklearn.model_selection import train_test_splitdf = pd.read_excel('2025-1-9公众号Python机器学习AI.xlsx')# 划分特征和目标变量X = df.drop(['y'], axis=1)y = df['y']# 划分训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,                                                     random_state=42, stratify=df['y'])
from xgboost import XGBClassifierfrom sklearn.model_selection import GridSearchCV, StratifiedKFoldfrom sklearn.metrics import accuracy_score
# 定义 XGBoost 二分类模型model_xgb = XGBClassifier(use_label_encoder=False, eval_metric='logloss', random_state=8)
# 定义参数网格param_grid = {    'n_estimators': [50, 100, 200],    'max_depth': [3, 5, 7],    'learning_rate': [0.01, 0.1, 0.2],    'subsample': [0.8, 1.0],    'colsample_bytree': [0.8, 1.0]}
# 定义 K 折交叉验证 (Stratified K-Fold)kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=8)
# 使用网格搜索寻找最佳参数grid_search = GridSearchCV(estimator=model_xgb, param_grid=param_grid, scoring='accuracy',                           cv=kfold, verbose=1, n_jobs=-1)
# 拟合模型grid_search.fit(X_train, y_train)# 使用最优参数训练模型xgboost = grid_search.best_estimator_

使用XGBoost二分类模型,通过网格搜索和K折交叉验证优化超参数,以找到最佳模型并对数据进行训练和测试划分,从而提升二分类任务的预测性能

基础二分类混淆矩阵

from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay# 使用测试集进行预测y_pred = xgboost.predict(X_test)# 计算混淆矩阵cm = confusion_matrix(y_test, y_pred)# 绘制混淆矩阵disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=xgboost.classes_)fig, ax = plt.subplots(figsize=(6, 6))  # 调整图大小disp.plot(cmap='Blues', values_format='d', ax=ax)# 设置标题和字体加粗plt.title("Confusion Matrix for XGBoost Model", fontweight='bold', fontsize=14)# 加粗坐标轴标签ax.set_xlabel('Predicted Label', fontweight='bold', fontsize=12)ax.set_ylabel('True Label', fontweight='bold', fontsize=12)# 调整刻度字体ax.tick_params(axis='both', labelsize=10, width=2)# 调整矩阵中的数值字体大小for text in disp.text_.ravel():    text.set_fontsize(14)  # 设置字体大小    text.set_fontweight('bold')  # 设置字体加粗plt.savefig("1.png", format='png', bbox_inches='tight')plt.show()

图片

优化二分类混淆矩阵

图片

加入标准化混淆矩阵、总计行列和颜色区分,并对数据进行精细标注(如百分比和数值),优化混淆矩阵的可视化效果,使其更加直观和易于解读

分类模型实现

模型构建

import numpy as npimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示plt.rcParams['axes.unicode_minus'] = Falseimport warnings# 忽略所有警告warnings.filterwarnings("ignore")
df = pd.read_excel('多类别数据.xlsx')from sklearn.preprocessing import LabelEncoderfrom sklearn.svm import SVCfrom sklearn.model_selection import train_test_splitfrom hyperopt import fmin, tpe, hpfrom sklearn.metrics import accuracy_score
# 对 Type 列进行编码label_encoder = LabelEncoder()df['Type_encoded'] = label_encoder.fit_transform(df['Type'])
# 分割数据集X = df.drop(['Type', 'Type_encoded'], axis=1)y = df['Type_encoded']
X_train, X_test, y_train, y_test = train_test_split(    X, y, test_size=0.3, stratify=df['Type_encoded'])
# 定义超参数空间parameter_space_svc = {    'C': hp.loguniform('C', np.log(100), np.log(1000)),  # 惩罚项    'kernel': hp.choice('kernel', ['rbf', 'poly']),       # 核函数类型(选择 rbf 或 poly)    'gamma': hp.loguniform('gamma', np.log(100), np.log(1000)),  # 核函数的系数}
# 初始化计数器count = 0
# 定义优化目标函数def func(args):    global count    count += 1    print(f"\nIteration {count}: Hyperparameters - {args}")
    # 创建 SVM 分类器,传递超参数    clf = SVC(**args)
    # 训练模型    clf.fit(X_train, y_train)
    # 预测测试集    prediction = clf.predict(X_test)
    # 计算准确率    score = accuracy_score(y_test, prediction)    print(f'Test accuracy: {score}')
    # 由于 fmin 函数默认是最小化目标函数,所以返回负准确率作为目标    return -score
# 使用 TPE 算法进行超参数优化,最大评估次数为 100best = fmin(func, parameter_space_svc, algo=tpe.suggest, max_evals=100)
# 将最佳的核函数类型从索引值转换为相应的字符串kernel_list = ['rbf', 'poly']best['kernel'] = kernel_list[best['kernel']]
# 将最佳超参数保存到 best_params_ 中best_params_ = {    'C': best['C'],    'kernel': best['kernel'],    'gamma': best['gamma']}
# 输出最佳超参数print('\nBest hyperparameters:', best_params_)
# 创建 SVM 分类器,并使用最佳超参数进行配置clf = SVC(    C=best_params_['C'],                # 惩罚项参数    kernel=best_params_['kernel'],      # 核函数类型    gamma=best_params_['gamma'],        # 核函数系数    decision_function_shape='ovr',      # 多分类问题时使用 "ovr"(一对多)策略    cache_size=5000,                    # 缓存大小,单位为 MB    probability=True)
# 使用训练数据进行模型训练clf.fit(X_train, y_train)

通过超参数优化训练一个基于SVM的多分类模型,为后续生成和分析多分类混淆矩阵做好准备

基础多分类混淆矩阵

from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
# 使用测试集进行预测y_pred = clf.predict(X_test)
# 计算混淆矩阵cm = confusion_matrix(y_test, y_pred)
# 绘制混淆矩阵disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=label_encoder.classes_)  # 使用编码器的类标签fig, ax = plt.subplots(figsize=(6, 6))  # 调整图大小disp.plot(cmap='Blues', values_format='d', ax=ax)
# 设置标题和字体加粗plt.title("Confusion Matrix for SVM Model", fontweight='bold', fontsize=14)
# 加粗坐标轴标签ax.set_xlabel('Predicted Label', fontweight='bold', fontsize=12)ax.set_ylabel('True Label', fontweight='bold', fontsize=12)
# 调整刻度字体ax.tick_params(axis='both', labelsize=10, width=2)
# 调整矩阵中的数值字体大小for text in disp.text_.ravel():    text.set_fontsize(14)  # 设置字体大小    text.set_fontweight('bold')  # 设置字体加粗
# 保存图像plt.savefig("3.png", format='png', bbox_inches='tight')plt.show()

图片

优化多分类混淆矩阵

图片

同样对于多分类模型,通过添加标准化、总计行列、颜色区分和精细标注,优化混淆矩阵的展示效果,使其更直观、全面且易于解读。

来源:Python机器学习AI

THE END