通过TSS综合灵敏度与特异度优化分类模型阈值,提升少数类样本识别率

机器学习算法大数据

picture.image

背景

在标准的二分类模型中,通常使用0.5作为默认的阈值,即:

  • 如果模型预测样本属于类别1的概率大于0.5,则预测该样本为类别1;
  • 如果预测概率小于0.5,则预测该样本为类别0

然而,选择0.5作为阈值并不总是最佳的,因为不同的数据集和问题可能会对分类性能产生不同的需求。在某些情况下,默认的0.5阈值可能导致不平衡的结果,尤其是在类别不平衡或不同分类错误代价的情况下

引入TSS的作用:

TSS提供了一种方法来调整这个阈值,使得模型的预测效果对正类(类别 1)和负类(类别 0) 都达到最佳平衡,而不是固守默认的0.5阈值。具体来说,TSS能帮助选择一个最佳阈值,使得模型在灵敏度(对正类的识别能力)和特异度(对负类的识别能力)之间找到最优平衡点,将灵敏度和特异度结合在一起,综合反映模型对正类和负类的分类能力

如何通过TSS选择阈值:

灵敏度(Sensitivity):也称为召回率,是模型正确识别正类(类别 1)的能力,公式是

特异度(Specificity):是模型正确识别负类(类别 0)的能力,公式是

TSS的计算公式是:

TSS是灵敏度和特异度的综合指标,TSS的值范围通常在 [-1, 1] 之间。TSS=1表示模型完美地分类了所有样本,TSS=0表示模型的表现与随机分类相当,TSS<0表示模型的性能比随机分类还要差

通过TSS优化阈值:

通过计算不同阈值下的TSS值,选择TSS最大的阈值作为最佳分类阈值,这意味着:

  • 如果只使用默认的0.5阈值,它可能不会得到最佳的分类效果
  • 通过调整阈值,可以找到使得TSS最大化的阈值,这时模型对正负类的识别能力都达到了最佳平衡

案例

假设模型预测某样本为类别1的概率是0.7,使用默认的阈值0.5,那么会将其预测为类别1,但是,如果调整阈值为0.8,这个样本的预测概率就低于这个阈值,可能被预测为类别 0。虽然这种调整可能导致灵敏度降低,但可能会提高特异度,通过计算不同阈值下的TSS,可以选择使TSS 最大的阈值,这样可以获得最优的分类效果,平衡两类的分类表现

通过 TSS 的引入,可以避免固定使用0.5阈值,而是通过优化阈值使得 灵敏度特异度平衡 达到最佳,从而提升模型的整体性能,特别是在面对 类别不平衡 或对 两类分类有不同关注

代码实现

模型构建


          
import pandas as pd
          
import numpy as np
          
import matplotlib.pyplot as plt
          
plt.rcParams['font.family'] = 'Times New Roman'
          
plt.rcParams['axes.unicode_minus'] = False
          
import warnings
          
# 忽略所有警告
          
warnings.filterwarnings("ignore")
          
from sklearn.model_selection import train_test_split
          
df = pd.read_excel('2025-1-23公众号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 XGBClassifier
          
from sklearn.model_selection import GridSearchCV, StratifiedKFold
          
from 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模型和网格搜索(GridSearchCV) 来进行超参数调优,并通过 Stratified K-Fold 交叉验证 找到最佳的模型参数,为后续的 TSS(True Skill Statistic) 演示提供一个经过优化的分类模型基础

默认0.5阈值下的模型性能


          
from sklearn.metrics import classification_report
          
# 预测测试集
          
y_pred = xgboost.predict(X_test)
          
# 输出模型报告,查看评价指标
          
print(classification_report(y_test, y_pred))
      

picture.image

picture.image

从这个结果可以看出,在默认阈值0.5下,XGBoost 模型对恶性(malignant)和良性(benign)样本的预测存在一定的类别不均衡。虽然恶性样本的预测准确率较高(82.7%的恶性样本被正确分类),但良性样本的召回率较低(只有64.0%的良性样本被正确预测为良性),这表明模型倾向于将样本预测为恶性类别,从而导致对良性类别的预测效果较差,我们更倾向于对于少数类样本的识别,所以得确定一个新的阈值让模型对于少数类别的识别有提升的同时对于多数类别的预测精确度也不会下降太多,所以接下来引入TTS确定最佳阈值让二者达到平衡

引入TSS确定最佳阈值

picture.image

TSS随阈值变化的曲线,通过选择最佳阈值 0.14 最大化了 TSS(0.5946),从而平衡了模型对正负类的分类性能,提高了对少数类(良性)样本的识别能力,同时尽量不降低多数类(恶性)的预测精度,完整 代码与数据集获取:如需获取本文的源代码和数据集,请添加作者微信联系

TTS最佳阈值下的模型性能


          
# 使用默认阈值(0.5)进行预测
          
y_pred_default = (probabilities[:, 1] > 0.5).astype(int)
          
# 使用最优阈值(optimal_threshold)进行预测
          
y_pred_optimal = (probabilities[:, 1] > optimal_threshold).astype(int)
          
# 创建 DataFrame 存储真实标签、默认预测值和最优阈值下的预测值
          
result_df = pd.DataFrame({
          
    'True_Label': true_labels,
          
    'y_pred_default': y_pred_default,
          
    'y_pred_optimal': y_pred_optimal
          
})
          
print(classification_report(y_test,  np.array(result_df['y_pred_optimal'])))
      

picture.image

picture.image

TSS最佳阈值下(0.14)的模型性能:在阈值0.14下,模型对恶性(malignant)样本的预测准确率为(63.5%),但是良性(benign)样本的预测效果有显著提升,96.0%的良性样本被正确预测为良性。这个阈值提高了对少数类(良性样本)的召回率,从而优化了模型的整体性能

与默认阈值0.5的性能对比:在默认0.5阈值下,模型倾向于预测为多数类(恶性样本),导致良性样本的召回率较低(64.0%)。通过选择0.14的阈值,模型能够大大提高良性样本的识别效果,尽管多数类(恶性)的预测精度有所下降,但总体分类效果有所改善,尤其是在少数类样本的识别上

由于这个数据集是模拟数据集,且存在 样本不均衡样本数量较少 的情况,模型在默认 0.5阈值 下倾向于预测多数类(通常是恶性样本),从而导致少数类(良性样本)的预测效果较差。在这种情况下, 一个样本的预测正误 对于灵敏度、特异度的影响较大。

然而,通过 TSS调整阈值 ,模型能够在 0.14阈值 下对 少数类(良性)样本 的预测效果有了显著提升,尽管 多数类(恶性)样本 的预测精度有所下降, 总体准确率(accuracy)0.77 降低到 0.74 ,但这是可以接受的,因为模型在 少数类样本的识别上得到了更高的精度 ,这符合我们对 少数类样本识别 的需求。

总结来说,通过调整阈值,虽然 总体准确率有所下降 ,但 对少数类样本的预测精度得到了有效提升 ,这在 不平衡数据集 中是一个有意义的优化

往期推荐

SHAP值+模型预测概率解读机器学习模型的决策过程

聚类与解释的结合:利用K-Means聚类辅助SHAP模型解释并可视化

期刊配图:RFE结合随机森林与K折交叉验证的特征筛选可视化

期刊配图:变量重要性排序与顺序正向选择的特征筛选可视化

期刊配图:SHAP可视化改进依赖图+拟合线+边缘密度+分组对比

期刊配图:SHAP蜂巢图与柱状图多维组合解读特征对模型的影响

基于mRMR筛选和递归特征选择的多模型性能评估与AUC可视化对比

期刊配图:SHAP可视化进阶蜂巢图与特征重要性环形图的联合展示方法

期刊配图:基于t-sne降维与模型预测概率的分类效果可视化

期刊配图:多种机器学习算法在递归特征筛选中的性能变化图示

picture.image

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论