第100+22步 ChatGPT学习:概率校准 Platt Scaling

news2024/11/14 13:30:59

基于Python 3.9版本演示

一、写在前面

最近看了一篇在Lancet子刊《eClinicalMedicine》上发表的机器学习分类的文章:《Development of a novel dementia risk prediction model in the general population: A large, longitudinal, population-based machine-learning study》。

学到一种叫做“概率校准”的骚操作,顺手利用GPT系统学习学习。

文章中用的技术是:保序回归(Isotonic regression)。

为了体现举一反三,顺便问了GPT还有哪些方法也可以实现概率校准。它给我列举了很多,那么就一个一个学习吧。

首先,是一个叫做 Platt Scaling 的方法。

二、Platt Scaling

Platt Scaling 是一种后处理方法,用于将机器学习分类器(尤其是二分类器)的输出分数(scores)转换为概率。它通过使用一个简单的逻辑回归模型将分类器的输出分数映射到 [0, 1] 的区间,从而提供概率估计。这个方法最初由 John Platt 在1999年提出,主要用于支持向量机(SVM)的概率估计。

(1)Platt Scaling 的基本步骤

1)训练分类器:首先,训练一个分类器(例如支持向量机、神经网络或决策树),并获得其输出分数(未归一化的分数或logits)。

2)拟合逻辑回归模型:将分类器的输出分数作为逻辑回归模型的输入。使用训练数据中的真实标签作为逻辑回归模型的输出。训练逻辑回归模型,找到最佳的参数(通常是通过最小化对数损失函数来实现)。

3)生成概率估计:使用训练好的逻辑回归模型,将新的分类器输出分数转换为概率估计。

(2)Platt Scaling 在分类中的作用

1)概率校准:Platt Scaling 可以将分类器的输出分数校准为概率,使得输出更具解释性。例如,一个输出概率为0.7的样本可以解释为该样本属于正类的概率为70%。

2)提升模型性能:通过将分数转换为概率,可以更好地进行决策边界的选择,从而提高分类器的性能。

3)适用于多种分类器:尽管Platt Scaling最初是为SVM设计的,但它可以广泛应用于各种分类器,如神经网络、决策树等。

4)融合不同模型的概率输出:在集成学习中,可以使用Platt Scaling将不同模型的输出分数转换为概率,然后结合这些概率进行加权平均,从而提升集成模型的性能。

三、Platt Scaling代码实现

下面,我编一个1比3的不太平衡的数据进行测试,对照组使用不进行校准的LR模型,实验组就是加入校准的LR模型,看看性能能够提高多少?

(1)不进行校准的SVM模型(默认参数)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix, roc_auc_score, roc_curve

# 加载数据
dataset = pd.read_csv('8PSMjianmo.csv')
X = dataset.iloc[:, 1:20].values
Y = dataset.iloc[:, 0].values

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.30, random_state=666)

# 标准化数据
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# 使用SVM分类器
classifier = SVC(kernel='linear', probability=True)
classifier.fit(X_train, y_train)

# 预测结果
y_pred = classifier.predict(X_test)
y_testprba = classifier.decision_function(X_test)

y_trainpred = classifier.predict(X_train)
y_trainprba = classifier.decision_function(X_train)

# 混淆矩阵
cm_test = confusion_matrix(y_test, y_pred)
cm_train = confusion_matrix(y_train, y_trainpred)
print(cm_train)
print(cm_test)

# 绘制测试集混淆矩阵
classes = list(set(y_test))
classes.sort()
plt.imshow(cm_test, cmap=plt.cm.Blues)
indices = range(len(cm_test))
plt.xticks(indices, classes)
plt.yticks(indices, classes)
plt.colorbar()
plt.xlabel('Predicted')
plt.ylabel('Actual')
for first_index in range(len(cm_test)):
    for second_index in range(len(cm_test[first_index])):
        plt.text(first_index, second_index, cm_test[first_index][second_index])

plt.show()

# 绘制训练集混淆矩阵
classes = list(set(y_train))
classes.sort()
plt.imshow(cm_train, cmap=plt.cm.Blues)
indices = range(len(cm_train))
plt.xticks(indices, classes)
plt.yticks(indices, classes)
plt.colorbar()
plt.xlabel('Predicted')
plt.ylabel('Actual')
for first_index in range(len(cm_train)):
    for second_index in range(len(cm_train[first_index])):
        plt.text(first_index, second_index, cm_train[first_index][second_index])

plt.show()

# 计算并打印性能参数
def calculate_metrics(cm, y_true, y_pred_prob):
    a = cm[0, 0]
    b = cm[0, 1]
    c = cm[1, 0]
    d = cm[1, 1]
    acc = (a + d) / (a + b + c + d)
    error_rate = 1 - acc
    sen = d / (d + c)
    sep = a / (a + b)
    precision = d / (b + d)
    F1 = (2 * precision * sen) / (precision + sen)
    MCC = (d * a - b * c) / (np.sqrt((d + b) * (d + c) * (a + b) * (a + c)))
    auc_score = roc_auc_score(y_true, y_pred_prob)
    
    metrics = {
        "Accuracy": acc,
        "Error Rate": error_rate,
        "Sensitivity": sen,
        "Specificity": sep,
        "Precision": precision,
        "F1 Score": F1,
        "MCC": MCC,
        "AUC": auc_score
    }
    return metrics

metrics_test = calculate_metrics(cm_test, y_test, y_testprba)
metrics_train = calculate_metrics(cm_train, y_train, y_trainprba)

print("Performance Metrics (Test):")
for key, value in metrics_test.items():
    print(f"{key}: {value:.4f}")

print("\nPerformance Metrics (Train):")
for key, value in metrics_train.items():
print(f"{key}: {value:.4f}")

结果输出:

记住这些个数字。

这个参数的SVM还没有LR好。

(2)进行校准的SVM模型(默认参数)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix, roc_auc_score
from sklearn.calibration import CalibratedClassifierCV

# 加载数据
dataset = pd.read_csv('8PSMjianmo.csv')
X = dataset.iloc[:, 1:20].values
Y = dataset.iloc[:, 0].values

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.30, random_state=666)

# 标准化数据
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# 使用SVM分类器并进行Platt Scaling
svm = SVC(kernel='linear', probability=True)
calibrated_svm = CalibratedClassifierCV(svm, method='sigmoid')
calibrated_svm.fit(X_train, y_train)

# 预测结果
y_pred = calibrated_svm.predict(X_test)
y_testprba = calibrated_svm.predict_proba(X_test)[:, 1]

y_trainpred = calibrated_svm.predict(X_train)
y_trainprba = calibrated_svm.predict_proba(X_train)[:, 1]

# 混淆矩阵
cm_test = confusion_matrix(y_test, y_pred)
cm_train = confusion_matrix(y_train, y_trainpred)
print(cm_train)
print(cm_test)

# 绘制测试集混淆矩阵
classes = list(set(y_test))
classes.sort()
plt.imshow(cm_test, cmap=plt.cm.Blues)
indices = range(len(cm_test))
plt.xticks(indices, classes)
plt.yticks(indices, classes)
plt.colorbar()
plt.xlabel('Predicted')
plt.ylabel('Actual')
for first_index in range(len(cm_test)):
    for second_index in range(len(cm_test[first_index])):
        plt.text(first_index, second_index, cm_test[first_index][second_index])

plt.show()

# 绘制训练集混淆矩阵
classes = list(set(y_train))
classes.sort()
plt.imshow(cm_train, cmap=plt.cm.Blues)
indices = range(len(cm_train))
plt.xticks(indices, classes)
plt.yticks(indices, classes)
plt.colorbar()
plt.xlabel('Predicted')
plt.ylabel('Actual')
for first_index in range(len(cm_train)):
    for second_index in range(len(cm_train[first_index])):
        plt.text(first_index, second_index, cm_train[first_index][second_index])

plt.show()

# 计算并打印性能参数
def calculate_metrics(cm, y_true, y_pred_prob):
    a = cm[0, 0]
    b = cm[0, 1]
    c = cm[1, 0]
    d = cm[1, 1]
    acc = (a + d) / (a + b + c + d)
    error_rate = 1 - acc
    sen = d / (d + c)
    sep = a / (a + b)
    precision = d / (b + d)
    F1 = (2 * precision * sen) / (precision + sen)
    MCC = (d * a - b * c) / (np.sqrt((d + b) * (d + c) * (a + b) * (a + c)))
    auc_score = roc_auc_score(y_true, y_pred_prob)
    
    metrics = {
        "Accuracy": acc,
        "Error Rate": error_rate,
        "Sensitivity": sen,
        "Specificity": sep,
        "Precision": precision,
        "F1 Score": F1,
        "MCC": MCC,
        "AUC": auc_score
    }
    return metrics

metrics_test = calculate_metrics(cm_test, y_test, y_testprba)
metrics_train = calculate_metrics(cm_train, y_train, y_trainprba)

print("Performance Metrics (Test):")
for key, value in metrics_test.items():
    print(f"{key}: {value:.4f}")

print("\nPerformance Metrics (Train):")
for key, value in metrics_train.items():
print(f"{key}: {value:.4f}")

看看结果:

总体来看,起作用了。训练集和验证集的AUC均有点提升,但不多。

四、换个策略

参考那篇文章的策略:采用五折交叉验证来建立和评估模型,其中四折用于训练,一折用于评估,在训练集中,其中三折用于建立SVM模型,另一折采用Platt Scaling概率校正,在训练集内部采用交叉验证对超参数进行调参。

代码:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split, KFold, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.calibration import CalibratedClassifierCV
from sklearn.metrics import confusion_matrix, roc_auc_score, make_scorer

# 加载数据
dataset = pd.read_csv('8PSMjianmo.csv')
X = dataset.iloc[:, 1:20].values
Y = dataset.iloc[:, 0].values

# 标准化数据
sc = StandardScaler()
X = sc.fit_transform(X)

# 五折交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=666)

# 超参数调优参数网格
param_grid = {
    'C': [0.1, 1, 10, 100],
    'kernel': ['linear', 'rbf']
}

# 计算并打印性能参数
def calculate_metrics(cm, y_true, y_pred_prob):
    a = cm[0, 0]
    b = cm[0, 1]
    c = cm[1, 0]
    d = cm[1, 1]
    acc = (a + d) / (a + b + c + d)
    error_rate = 1 - acc
    sen = d / (d + c)
    sep = a / (a + b)
    precision = d / (b + d)
    F1 = (2 * precision * sen) / (precision + sen)
    MCC = (d * a - b * c) / (np.sqrt((d + b) * (d + c) * (a + b) * (a + c)))
    auc_score = roc_auc_score(y_true, y_pred_prob)
    
    metrics = {
        "Accuracy": acc,
        "Error Rate": error_rate,
        "Sensitivity": sen,
        "Specificity": sep,
        "Precision": precision,
        "F1 Score": F1,
        "MCC": MCC,
        "AUC": auc_score
    }
    return metrics

# 初始化结果列表
results_train = []
results_test = []

# 初始化变量以跟踪最优模型
best_auc = 0
best_model = None
best_X_train = None
best_X_test = None
best_y_train = None
best_y_test = None

# 交叉验证过程
for train_index, test_index in kf.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = Y[train_index], Y[test_index]

    # 内部交叉验证进行超参数调优和模型训练
    inner_kf = KFold(n_splits=4, shuffle=True, random_state=666)
    grid_search = GridSearchCV(SVC(probability=True), param_grid, cv=inner_kf, scoring='roc_auc')
    grid_search.fit(X_train, y_train)
    model = grid_search.best_estimator_

    # Platt Scaling 概率校准
    calibrated_svm = CalibratedClassifierCV(model, method='sigmoid', cv='prefit')
    calibrated_svm.fit(X_train, y_train)

    # 评估模型
    y_trainpred = calibrated_svm.predict(X_train)
    y_trainprba = calibrated_svm.predict_proba(X_train)[:, 1]
    cm_train = confusion_matrix(y_train, y_trainpred)
    metrics_train = calculate_metrics(cm_train, y_train, y_trainprba)
    results_train.append(metrics_train)
    
    y_pred = calibrated_svm.predict(X_test)
    y_testprba = calibrated_svm.predict_proba(X_test)[:, 1]
    cm_test = confusion_matrix(y_test, y_pred)
    metrics_test = calculate_metrics(cm_test, y_test, y_testprba)
    results_test.append(metrics_test)
    
    # 更新最优模型
    if metrics_test['AUC'] > best_auc:
        best_auc = metrics_test['AUC']
        best_model = calibrated_svm
        best_X_train = X_train
        best_X_test = X_test
        best_y_train = y_train
        best_y_test = y_test
        best_params = grid_search.best_params_

    print("Performance Metrics (Train):")
    for key, value in metrics_train.items():
        print(f"{key}: {value:.4f}")
    
    print("\nPerformance Metrics (Test):")
    for key, value in metrics_test.items():
        print(f"{key}: {value:.4f}")
    print("\n" + "="*40 + "\n")

# 使用最优模型评估性能
y_trainpred = best_model.predict(best_X_train)
y_trainprba = best_model.predict_proba(best_X_train)[:, 1]
cm_train = confusion_matrix(best_y_train, y_trainpred)
metrics_train = calculate_metrics(cm_train, best_y_train, y_trainprba)

y_pred = best_model.predict(best_X_test)
y_testprba = best_model.predict_proba(best_X_test)[:, 1]
cm_test = confusion_matrix(best_y_test, y_pred)
metrics_test = calculate_metrics(cm_test, best_y_test, y_testprba)

print("Performance Metrics of the Best Model (Train):")
for key, value in metrics_train.items():
    print(f"{key}: {value:.4f}")

print("\nPerformance Metrics of the Best Model (Test):")
for key, value in metrics_test.items():
    print(f"{key}: {value:.4f}")

# 打印最优模型的参数
print("\nBest Model Parameters:")
for key, value in best_params.items():
    print(f"{key}: {value}")

提升挺大的,不过可能是因为进行了超参数的搜索吧。

最优的SVM参数是:

Best Model Parameters:

C: 0.1

kernel: rbf

大家有空可以去使用这个参数试一试,不进行校准的SVM的性能如何?

不过也无所谓啦,结果不错就行。

五、最后

各位可以去试一试在其他数据或者在其他机器学习分类模型中使用的效果。

数据不分享啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2056001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MapBox Android版开发 1 配置

MapBox Android版开发 1 配置 前言MapBox V9 配置创建工程配置地图配置私钥配置公钥配置仓库配置依赖配置权限地图初始化 显示地图布局文件地图Activity 运行效果 MapBox V11 配置创建工程配置地图配置私钥配置公钥配置仓库配置依赖配置权限 显示地图布局文件 运行效果 前言 本…

ee trade:黄金投资与股票投资的区别

黄金和股票, 是金融市场中两种常见的投资工具, 它们拥有截然不同的特点和风险, 了解它们的差异, 可以帮助投资者制定更合理的投资策略。 一、 投资性质: 避险与成长, 两种投资方向 黄金: 被视…

金价徘徊高位,市场聚焦美联储降息预期

现货黄金高位震荡 周二亚市早盘,现货黄金在2500美元/盎司关口附近徘徊,交投于2503.23美元/盎司附近。金价周一在创纪录的高位后出现回调,投资者从涨势中获利了结,并根据美联储的线索调整仓位,现货黄金最终收报2504.1…

Vue - 详细介绍 vue-monoplasty-slide-verify vue3-puzzle-vcode 滑动验证组件

Vue - 详细介绍 vue-monoplasty-slide-verify & vue3-puzzle-vcode 滑动验证组件 在日常的账号登录所需要的大部分是滑动验证来检验人为操作,免于字母验证码的繁琐输入,下面介绍在Vue2和Vue3中适用的滑动验证组件。 1、vue-monoplasty-slide-verif…

【GitLab】使用 Docker 安装 3:gitlab-ce:17.3.0-ce.0 配置

参考阿里云的教程docker的重启 sudo systemctl daemon-reload sudo systemctl restart docker配置 –publish 8443:443 --publish 8084:80 --publish 22:22 sudo docker ps -a 當容器狀態為healthy時,說明GitLab容器已經正常啟動。 root@k8s-master-pfsrv:~

远离内卷,新的跨境电商蓝海,智能小家电沃尔玛1P新赛道——WAYLI威利跨境助力商家

随着全球经济格局的变迁,跨境电商已经成为新的蓝海领域,其中智能小家电市场更是呈现出蓬勃的发展态势。在这样的背景下,沃尔玛1P会员凭借其独特的优势,正开辟出一条全新的跨境电商赛道。 一、智能小家电市场崛起,源于消…

通义灵码代码搜索功能的前沿性研究论文被软件工程国际顶会 FSE 录用

在今年 FSE 2024 软件工程大会上,阿里云通义灵码团队和重庆大学合作的论文《An Empirical Study of Code Search in Intelligent Coding Assistant: Perceptions, Expectations, and Directions》被 FSE Industry 2024 (CCF A) 录用。 本篇论文主要探讨了在智能编码…

告别硬件!试试ToDesk云电脑,让你的云端体验更有趣

在这个不断进步的数字时代,科技的每一次突破都在重新塑造我们的生活和工作模式。随着云计算技术的不断成熟,传统的硬件限制正在逐渐消失,一个全新的云端时代正悄然兴起。ToDesk云电脑作为这场变革的领航者,正引领我们进入一个更加…

海绵城市雨水监测系统简介

海绵城市雨水监测系统主要有:数据采集、无线数据传输、后台云服务、终端平台显示等部分组成。系统通过前端数据采集水质(ss\cod\浊度、PH等)、雨水雨量、流量、水位、土壤湿度、气象等数据。通过无线数据传输通讯(4G、5G、以太网、…

高性能web服务器详解

一、Web服务的基础介绍 正常情况下单次web服务访问的流程简图: 1.1 Web服务介绍 这里介绍的是 Apache 和 NGINX 1.1.1 Apache 经典的Web服务端 Apache 起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发 目前经历了两大版本分别是 1.X 和 2.X…

Ubuntu 16.04 通过deb包安装内核头文件

文章目录 前言通过deb包安装内核头文件 前言 Ubuntu16.04部分内核版本无法通过 apt-get install linux-headers-$(uname -r) 来进行安装: # cat /etc/lsb-release DISTRIB_IDUbuntu DISTRIB_RELEASE16.04 DISTRIB_CODENAMExenial DISTRIB_DESCRIPTION"Ubuntu…

linux 部署YUM仓库及NFS共享服务

目录 简介 一、YUM仓库服务 1.1 YUM概述 1.2 linux系统各家厂家用的安装源 1.3 yum命令 1.4 yum下载方式 1.5 部署YUM软件仓库 二、NFS共享存储服务 2.1 NFS共享存储服务概念 2.2 NFS配置环境 2.3 使用NFS发布共享资源 2.4 在客户端访问NFS共享 简介 yum&#xff…

测试面试题集锦(五)| 自动化测试与性能测试篇(附答案)

简介 本系列文章总结归纳了一些软件测试工程师常见的面试题,主要来源于个人面试遇到的、网络搜集(完善)、工作日常讨论等,分为以下十个部分,供大家参考。如有错误的地方,欢迎指正。有更多的面试题或面试中遇…

Apeaksoft Video Converter Ultimate for Mac:强大的视频转换与编辑工具

Apeaksoft Video Converter Ultimate for Mac是一款专为Mac用户设计的视频转换与编辑软件,凭借其强大的功能和用户友好的界面,在视频处理领域脱颖而出。该软件不仅支持多种视频格式的转换,还内置了丰富的视频编辑功能,让用户能够轻…

海康VisionMaster使用学习笔记12-通信框架介绍

1. 通信的用途 用途: 通信是连通算法平台和外部设备的重要渠道,在算法平台中既支持外部数据的读入也支持数据的写出,当通信构建起来以后既可以把软件处理结果发送给外界,又可以通过外界发送字符来触发相机拍照或者软件运行。 2. 通信的种类…

提升工作效率的五大神器

在这个信息爆炸、节奏加速的时代,高效工作已经成为了职场人士追求的目标。如何在短时间内完成更多的工作任务,同时保持高质量的输出?答案在于合理利用工具。以下是五个能够显著提升工作效率的软件推荐,它们各自在任务管理、团队协…

【LLM大模型】大模型涌现能力及 Prompt Engineering提示词

涌现能力 GPT3是第一批拥有“涌现能力”的大语言模型,即模型未经特定任务的训练,但在适当的提示下,仍然能够解决某些特定领域的问题。 例如大语言模型可以解答数学问题、辅助进行编程、甚至是进行问答等,其实都属于模型的涌现能…

FMEA项目难落地?原因在这里

很多企业反馈到“FMEA项目难落地”其实并不是大家不想做好FMEA,目前各个企业做不好的FMEA的最关键的原因,还是大家做FMEA的方法不正确。详情如深圳天行健企业管理咨询公司下文所述: 1、 分析对象定义不清 做FMEA时,首先得弄清楚你…

Xterminal工具的安装与使用体验

Xterminal工具的安装与使用体验 一、Xterminal简介二、Xterminal核心特性三、Xterminal使用场景四、Xterminal下载地址五、Xterminal的基本使用5.1 设置仓库密码5.2 SSH连接5.3 Windows远程桌面5.4 笔记功能5.5 AI工具 六、总结 一、Xterminal简介 Xterminal是一款专为开发者设…

ubuntu虚拟机VBOX无法读取usb设备的解决办法

关闭虚拟电脑,在设置->USB设置选择你的usb版本再试试看再右下角右键选择你的设备应该就行了