第100+25步 ChatGPT学习:概率校准 Histogram Binning

news2024/11/15 3:38:23

基于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还有哪些方法也可以实现概率校准。它给我列举了很多,那么就一个一个学习吧。

这一期,介绍一个叫做 Histogram Binning 的方法。

二、Histogram Binning

Histogram Binning(直方图分箱)是一种用于数据预处理和特征工程的技术,它通过将连续变量分成离散的区间来简化数据处理和分析。基本思想是将连续变量划分成若干个区间(bin),每个区间包含一定范围内的数据点。数据点被分配到相应的区间中,通常每个区间用一个代表值(如区间的中位数或均值)来表示。

(1)作用和优势

1)处理连续变量:许多机器学习算法(如决策树、逻辑回归等)在处理连续变量时效果不佳,分箱可以将连续变量转换为离散变量,从而提高算法性能。

2)减少噪音和异常值影响:连续变量中的噪音和异常值可能会对模型训练产生不利影响。通过分箱,可以平滑数据,减少噪音和异常值的影响。

3)平衡类分布:在处理不平衡数据时,可以通过分箱技术对少数类和多数类的数据进行平衡,增强分类器对少数类的识别能力。

三、Histogram Binning代码实现

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

(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, roc_curve, brier_score_loss
from sklearn.calibration import calibration_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='rbf', C=0.1, probability=True)
classifier.fit(X_train, y_train)

# 获取未校准的概率预测
y_train_probs = classifier.predict_proba(X_train)[:, 1]
y_test_probs = classifier.predict_proba(X_test)[:, 1]

# Histogram Binning 校准函数
def histogram_binning(probabilities, y_true, n_bins=10):
    bin_edges = np.linspace(0, 1, n_bins + 1)
    bin_indices = np.digitize(probabilities, bin_edges) - 1
    bin_sums = np.zeros(n_bins)
    bin_true_sums = np.zeros(n_bins)
    bin_counts = np.zeros(n_bins)
    
    for i in range(n_bins):
        bin_counts[i] = np.sum(bin_indices == i)
        if bin_counts[i] > 0:
            bin_sums[i] = np.sum(probabilities[bin_indices == i])
            bin_true_sums[i] = np.sum(y_true[bin_indices == i])
    
    bin_probs = np.zeros_like(probabilities)
    for i in range(n_bins):
        if bin_counts[i] > 0:
            bin_probs[bin_indices == i] = bin_true_sums[i] / bin_counts[i]
    
    return bin_probs

# 进行Histogram Binning校准
calibrated_train_probs = histogram_binning(y_train_probs, y_train)
calibrated_test_probs = histogram_binning(y_test_probs, y_test)

# 预测结果
y_train_pred = (calibrated_train_probs >= 0.5).astype(int)
y_test_pred = (calibrated_test_probs >= 0.5).astype(int)

# 混淆矩阵
cm_test = confusion_matrix(y_test, y_test_pred)
cm_train = confusion_matrix(y_train, y_train_pred)
print(cm_train)
print(cm_test)

# 绘制混淆矩阵函数
def plot_confusion_matrix(cm, classes, title='Confusion Matrix'):
    plt.imshow(cm, cmap=plt.cm.Blues)
    indices = range(len(cm))
    plt.xticks(indices, classes)
    plt.yticks(indices, classes)
    plt.colorbar()
    plt.xlabel('Predicted')
    plt.ylabel('Actual')
    for first_index in range(len(cm)):
        for second_index in range(len(cm[first_index])):
            plt.text(first_index, second_index, cm[first_index][second_index])
    plt.title(title)
    plt.show()

# 绘制测试集混淆矩阵
plot_confusion_matrix(cm_test, list(set(y_test)), 'Confusion Matrix (Test)')

# 绘制训练集混淆矩阵
plot_confusion_matrix(cm_train, list(set(y_train)), 'Confusion Matrix (Train)')

# 计算并打印性能参数
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)
    brier_score = brier_score_loss(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,
        "Brier Score": brier_score
    }
    return metrics

metrics_test = calculate_metrics(cm_test, y_test, calibrated_test_probs)
metrics_train = calculate_metrics(cm_train, y_train, calibrated_train_probs)

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模型,另一折采用Histogram Binning概率校正,在训练集内部采用交叉验证对超参数进行调参。

代码:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV, KFold
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix, roc_auc_score, roc_curve, brier_score_loss
from sklearn.calibration import calibration_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)

# 定义五折交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=666)
calibrated_probs = []
true_labels = []

for train_index, test_index in kf.split(X_train):
    X_train_fold, X_val_fold = X_train[train_index], X_train[test_index]
    y_train_fold, y_val_fold = y_train[train_index], y_train[test_index]
    
    # 内部三折交叉验证用于超参数调优
    inner_kf = KFold(n_splits=3, shuffle=True, random_state=666)
    param_grid = {'C': [0.01, 0.1, 1, 10, 100], 'kernel': ['rbf']}
    svm = SVC(probability=True)
    clf = GridSearchCV(svm, param_grid, cv=inner_kf, scoring='roc_auc')
    clf.fit(X_train_fold, y_train_fold)
    best_params = clf.best_params_
    
    # 使用最佳参数训练SVM
    classifier = SVC(kernel=best_params['kernel'], C=best_params['C'], probability=True)
    classifier.fit(X_train_fold, y_train_fold)
    
    # 获取未校准的概率预测
    y_val_fold_probs = classifier.predict_proba(X_val_fold)[:, 1]
    
    # Histogram Binning 校准函数
    def histogram_binning(probabilities, y_true, n_bins=10):
        bin_edges = np.linspace(0, 1, n_bins + 1)
        bin_indices = np.digitize(probabilities, bin_edges) - 1
        bin_sums = np.zeros(n_bins)
        bin_true_sums = np.zeros(n_bins)
        bin_counts = np.zeros(n_bins)
        
        for i in range(n_bins):
            bin_counts[i] = np.sum(bin_indices == i)
            if bin_counts[i] > 0:
                bin_sums[i] = np.sum(probabilities[bin_indices == i])
                bin_true_sums[i] = np.sum(y_true[bin_indices == i])
        
        bin_probs = np.zeros_like(probabilities)
        for i in range(n_bins):
            if bin_counts[i] > 0:
                bin_probs[bin_indices == i] = bin_true_sums[i] / bin_counts[i]
        
        return bin_probs

    # 进行Histogram Binning校准
    calibrated_val_fold_probs = histogram_binning(y_val_fold_probs, y_val_fold)
    calibrated_probs.extend(calibrated_val_fold_probs)
    true_labels.extend(y_val_fold)

# 用于测试集的SVM模型训练和校准
classifier_final = SVC(kernel=best_params['kernel'], C=best_params['C'], probability=True)
classifier_final.fit(X_train, y_train)
y_test_probs = classifier_final.predict_proba(X_test)[:, 1]
calibrated_test_probs = histogram_binning(y_test_probs, y_test)

# 预测结果
y_train_pred = (np.array(calibrated_probs) >= 0.5).astype(int)
y_test_pred = (calibrated_test_probs >= 0.5).astype(int)

# 混淆矩阵
cm_test = confusion_matrix(y_test, y_test_pred)
cm_train = confusion_matrix(y_train, y_train_pred)
print("Training Confusion Matrix:\n", cm_train)
print("Testing Confusion Matrix:\n", cm_test)

# 绘制混淆矩阵函数
def plot_confusion_matrix(cm, classes, title='Confusion Matrix'):
    plt.imshow(cm, cmap=plt.cm.Blues)
    indices = range(len(cm))
    plt.xticks(indices, classes)
    plt.yticks(indices, classes)
    plt.colorbar()
    plt.xlabel('Predicted')
    plt.ylabel('Actual')
    for first_index in range(len(cm)):
        for second_index in range(len(cm[first_index])):
            plt.text(first_index, second_index, cm[first_index][second_index])
    plt.title(title)
    plt.show()

# 绘制测试集混淆矩阵
plot_confusion_matrix(cm_test, list(set(y_test)), 'Confusion Matrix (Test)')

# 绘制训练集混淆矩阵
plot_confusion_matrix(cm_train, list(set(y_train)), 'Confusion Matrix (Train)')

# 计算并打印性能参数
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)
    brier_score = brier_score_loss(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,
        "Brier Score": brier_score
    }
    return metrics

metrics_test = calculate_metrics(cm_test, y_test, calibrated_test_probs)
metrics_train = calculate_metrics(cm_train, y_train, np.array(calibrated_probs))

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}")

# 绘制校准曲线
def plot_calibration_curve(y_true, probs, title='Calibration Curve'):
    fraction_of_positives, mean_predicted_value = calibration_curve(y_true, probs, n_bins=10)
    plt.plot(mean_predicted_value, fraction_of_positives, "s-", label="Histogram Binning")
    plt.plot([0, 1], [0, 1], "k--")
    plt.xlabel('Mean predicted value')
    plt.ylabel('Fraction of positives')
    plt.title(title)
    plt.legend()
    plt.show()

# 绘制校准曲线
plot_calibration_curve(y_test, calibrated_test_probs, title='Calibration Curve (Test)')
plot_calibration_curve(y_train, np.array(calibrated_probs), title='Calibration Curve (Train)')

输出:

哈哈哈,撤了撤了。

五、最后

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

数据不分享啦。

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

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

相关文章

Dify 中的讯飞星火平台工具源码分析

本文主要对 Dify 中的讯飞星火平台工具 spark 进行了源码分析,该工具可根据用户的输入生成图片,由讯飞星火提供图片生成 API。通过本文学习可自行实现将第三方 API 封装为 Dify 中工具的能力。 源码位置:dify-0.6.14\api\core\tools\provide…

巨潮股票爬虫逆向

目标网站 aHR0cDovL3dlYmFwaS5jbmluZm8uY29tLmNuLyMvSVBPTGlzdD9tYXJrZXQ9c3o 一、抓包分析 请求头参数加密 二、逆向分析 下xhr断点 参数生成位置 发现是AES加密,不过是混淆的,但并不影响咱们扣代码 文章仅提供技术交流学习,不可对目标服…

Java 分布式锁:原理与实践

在分布式系统中,多个节点同时操作共享资源的情况非常普遍。为了保证数据的一致性,分布式锁 应运而生。分布式锁 是一种跨多个服务器的互斥锁,用于协调分布式环境下的资源访问。 本文将介绍 Java 实现分布式锁 的几种常见方式,并结…

基于VUE的医院抗生素使用审核流程信息化管理系统

开发背景 随着医疗行业的快速发展和信息技术的不断进步,医院内部管理系统的信息化建设变得尤为重要。抗生素作为治疗感染性疾病的重要药物,在临床使用过程中需要严格控制以避免滥用导致的耐药性问题。传统的抗生素使用审核流程往往依赖于人工审核&#x…

一,初始 MyBatis-Plus

一,初始 MyBatis-Plus 文章目录 一,初始 MyBatis-Plus1. MyBatis-Plus 的概述2. 入门配置第一个 MyBatis-Plus 案例3. 补充说明:3.1 通用 Mapper 接口介绍3.1.1 Mapper 接口的 “增删改查”3.1.1.1 查询所有记录3.1.1.2 插入一条数据3.1.1.3 …

推荐3个AI论文、AI查重、AI降重工具

什么是AI论文、AI查重、AI降重工具? AI论文 AI论文指的是以人工智能(AI)相关主题为研究对象的学术论文。这类论文通常包含以下内容: 研究问题:针对某个特定的AI问题或领域的研究。方法:介绍用于解决问题…

UnLua实现继承

一、在蓝图中实现继承 1、创建父类,并绑定Lua脚本 2、创建子类蓝图,如果先创建的子类,可以修改父类继承 注意,提示选择继承父类的接口! 二、在Lua中实现继承 1、在父类Lua脚本中实现函数 BP_CharacterBase.lua func…

SysML图例-智能家居

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>>

spring boot(学习笔记第二十课) vue + spring boot前后端分离项目练习

spring boot(学习笔记第二十课) vue spring boot前后端分离项目练习 学习内容: 后端程序构建前端程序构建 1. 后端程序构建 前后端分离结构 前后端就是前端程序和后端程序独立搭建,通过Restful API进行交互,进行松耦合的设计。后端程序构建…

【吊打面试官系列-MySQL面试题】MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么?

大家好,我是锋哥。今天分享关于【MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么?】面试题,希望对大家有帮助; MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么? 以下是 MySQL_fetch_array 和 MySQL_fe…

VisionPro - 基础 - 模板匹配技术和在VP中的使用 - PMAlign - PatMax (5)- 非线性模板变形匹配

前言: 本机继续对VP的PatMax 算子进行说明:本节讲非线性变形的模板匹配。 Non-Linear Pattern Deformation By default, PatMax requires that each boundary point in the instance of a pattern found in a run-time image closely correspond to a b…

低空经济火爆,稀缺无人机教员培训详解

随着科技的飞速发展和低空经济的日益火爆,无人机技术已广泛应用于航拍、农业、物流、救援、环境监测等多个领域,成为推动社会经济发展的新引擎。然而,无人机行业的快速发展也催生了对专业无人机教员的迫切需求。本文将从基础理论学习、实操技…

[Redis][List]详细讲解

目录 0.前言1.常用命令1.LPUSH / RPUSH2.LPUSHX / RPUSHX3.LRANGE4.LPOP / RPOP5.LINDEX6.LINSERT7.LLEN8.LREM9.LTRIM10.LSET 2.阻塞版本命令0.是什么?1.BLPOP / BRPOP 3.内部编码(旧版本,仅供参考)1.ziplist(压缩链表)2.linkedlist(链表)3.quicklist(快…

yolov8旋转目标检测之绝缘子检测-从数据加载到模型训练、部署

YOLOv8 是 YOLO (You Only Look Once) 系列目标检测算法的最新版本,以其高速度和高精度而著称。在电力行业中,绝缘子是电力传输线路上的重要组件之一,它们用于支撑导线并保持电气绝缘。由于长期暴露在户外环境中,绝缘子容易出现损…

详细分析Spring的动态代理机制

文章目录 1. JDK动态代理和CGLIB动态代理的区别1.1 适用范围1.2 生成的代理类1.3 调用方式 2. 问题引入3. 创建工程验证 Spring 默认采用的动态代理机制3.1 引入 Maven 依赖3.2 UserController.java3.3 UserService.java3.4 UserServiceImpl.java(save方法添加了Tra…

【Python】探索 TensorFlow:构建强大的机器学习模型

TensorFlow 是一个开源的深度学习框架,由 Google 开发,广泛应用于机器学习和人工智能领域。自从 2015 年推出以来,它已成为研究人员、开发者和数据科学家们不可或缺的工具。TensorFlow 提供了灵活、高效的工具集,可以帮助我们构建…

API接口在金融科技领域的创新应用

导语: 随着互联网的发展和技术的进步,API接口在金融科技领域的创新应用越来越受到关注。本文将介绍API接口的基本概念,以及它在金融科技领域的应用案例。 第一部分:API接口简介及原理 API是Application Programming Interface&…

2021-03-03人工智能应用的就业效应

【摘要】文章从人工智能的概念出发,在总结已有研究方法的基础上,回顾了人工智能对就业的产业分布、岗位、工资等方面影响的理论与实证研究。文章发现,人工智能技术在替代部分岗位、促使劳动力在不同产业间流动的同时,还会加快劳动…

java 获取集合a比集合b多出来的对象元素

public class OrderListEntity {/*** deprecated 对象集合的处理* param aData 集合a* param bData 集合b* return 返回集合a比集合b多出来的部分, 通过id判断*/public static List<OrderListEntity> AHasMoreThanBData(List<OrderListEntity> aData, List<Ord…

LEAN 赋型唯一性(Unique Typing)之 Church-Rosser 定理 (Church-Rosser Theorem)及 赋型唯一性的证明

有了并行K简化的概念及其属性&#xff0c;以及其在LEAN类型理论中的相关证明&#xff0c;就可以证明&#xff0c;在K简化下的Church-Rosser 定理。即&#xff1a; 其过程如下&#xff1a; 证明如下&#xff1a; 其中的 lemma 4.9 和 4.10 &#xff0c;及 4.8 是 这整个证明过程…