R语言手动绘制连续线条的校准曲线(Calibration curve)(4)

news2024/12/23 9:13:04

校准曲线图表示的是预测值和实际值的差距,作为预测模型的重要部分,目前很多函数能绘制校准曲线。 一般分为两种,一种是通过Hosmer-Lemeshow检验,把P值分为10等分,求出每等分的预测值和实际值的差距。
在这里插入图片描述
在这里插入图片描述
我们既往已经通过多篇文章介绍了等分的校准曲线绘制,今天来介绍一下上图这种连续的,线条样的校准曲线绘制
我们先导入R包和数据,继续使用我们的早产数据

library(ggplot2)
library(rms)
bc<-read.csv("E:/r/test/zaochan.csv",sep=',',header=TRUE)
head(bc,6)
##   id low age lwt  race     smoke ptl ht ui ftv  bwt
## 1 85   0  19 182 black nonsmoker   0  0  1   0 2523
## 2 86   0  33 155 other nonsmoker   0  0  0   3 2551
## 3 87   0  20 105 white    smoker   0  0  0   1 2557
## 4 88   0  21 108 white    smoker   0  0  1   2 2594
## 5 89   0  18 107 white    smoker   0  0  1   0 2600
## 6 91   0  21 124 other nonsmoker   0  0  0   0 2622

这是一个关于早产低体重儿的数据(公众号回复:早产数据,可以获得该数据),低于2500g被认为是低体重儿。数据解释如下:low 是否是小于2500g早产低体重儿,age 母亲的年龄,lwt 末次月经体重,race 种族,smoke 孕期抽烟,ptl 早产史(计数),ht 有高血压病史,ui 子宫过敏,ftv 早孕时看医生的次数,bwt 新生儿体重数值。 我们先把分类变量转成因子

bc$race<-ifelse(bc$race=="black",1,ifelse(bc$race=="white",2,3))
bc$smoke<-ifelse(bc$smoke=="nonsmoker",0,1)
bc$race<-factor(bc$race)
bc$ht<-factor(bc$ht)
bc$ui<-factor(bc$ui)

对数据进行比例划分

set.seed(123)
tr1<- sample(nrow(bc),0.6*nrow(bc))##随机无放抽取
bc_train <- bc[tr1,]#60%数据集
bc_test<- bc[-tr1,]#40%数据集

我们先按RMS包的方法来画图,等下做个比较
建立模型

fit1<-lrm(low ~ age + lwt + race + smoke + ptl + ht + ui + ftv,
          x = TRUE, y = TRUE,
         data = bc_train )

绘图

cali <- calibrate(fit1, B = 400) 
plot(cali)

在这里插入图片描述
这张图有3条线,ideal就是校准曲线,bisa是对ideal进行的一个校正。下面我们来手动绘制ideal这条校准曲线,我们先用常规方法生成一个模型

fit<-glm(low ~ age + lwt + race + smoke + ptl + ht + ui + ftv,
         family = binomial("logit"),data = bc_train)
options(digits = 3, scipen=999)

生成模型的预测值

predicted <- predict(fit,type = c("response")) 

对预测值进行排序,并按区间抽样排列

p <- sort(predicted) 
p<-as.numeric(p)
predy <- seq(p[5], p[nrow(bc_train) - 4], length = 50)

把预测值和Y值进行lowess曲线拟合

smo <- lowess(predicted, as.numeric(fit$y), iter = 0)

我们可以看一下拟合的情况

plot(smo)

在这里插入图片描述

看到了没有,校准曲线已经初具雏形了,现在有两个方法对它进行处理,使用ggplot绘图功能直接拟合或者对这条线进行预测插值。
我先使用ggplot绘图绘图试一下,因为ggplot默认就是lowess进行拟合,这个适合数据比较紧凑的数据

plotdat<-as.data.frame(smo)
ggplot(plotdat, aes(x, y))+ 
  geom_line(aes(x = x, y = y), linewidth=1,col="blue")+
  annotate(geom = "segment", x = 0, y = 0, xend =1, yend = 1,color = "black",size=1)+ theme_minimal()+theme_bw()

在这里插入图片描述

再来就是使用插值法对它插值

calibrated.orig <- approx(smo, xout = predy, ties = function(x) x[1])$y 

插值后就可以绘图了

plot(predy, calibrated.orig, type = "l", lty=1, xlim = c(0,1), ylim = c(0,1), col= "blue")
abline(0, 1, lty = 2)
legend <- list(x=0 + .55*diff(c(0,1)), y=0 + .32*diff(c(0,1)))
legend(legend, c("Apparent","Ideal"), lty=c(3,1,2), bty="n")

在这里插入图片描述
两种画法一样,美化一下

plot(predy, calibrated.orig, type = "l", lty=1,lwd=2, xlim = c(0,0.8), ylim = c(0,0.8), col= "blue")
abline(0,1,col="black",lty=2,lwd=2)
legend(0.55,0.35,
       c("Apparent","Ideal"),
       lty=c(2,1),
       lwd=c(2,1),
       col=c("black","blue"),
       bty="n")

在这里插入图片描述
基于这个原理,我们可以应用到其他模型上,比如我们的随机森林模型,我们先导入数据,并对数据进行整理

library(randomForest)
library(pROC)
library(foreign)
bc <- read.spss("E:/r/test/bankloan_cs.sav",
                use.value.labels=F, to.data.frame=T)
bc<-bc[,c(-1:-3,-13:-15,-5)]
head(bc,6)
##   age employ address income debtinc creddebt othdebt default
## 1  28      7       2     44    17.7    2.991    4.80       0
## 2  64     34      17    116    14.7    5.047   12.00       0
## 3  40     20      12     61     4.8    1.042    1.89       0
## 4  30     11       3     27    34.5    1.751    7.56       0
## 5  25      2       2     30    22.4    0.759    5.96       1
## 6  35      2       9     38    10.9    1.462    2.68       1
bc$default<-as.factor(bc$default)

对数据进行7:3划分

set.seed(1)
index <- sample(2,nrow(bc),replace = TRUE,prob=c(0.7,0.3))
traindata <- bc[index==1,]
testdata <- bc[index==2,]

建立随机森林模型

def_ntree<- randomForest(default ~age+employ+address+income+debtinc+creddebt
                         +othdebt,data=traindata,
                         ntree=500,important=TRUE,proximity=TRUE)

生成预测概率,并对Y值概率进行提取

def_pred<-predict(def_ntree, newdata=traindata,type = "prob")##生成概率
def_pred<-as.data.frame(def_pred)
p<-def_pred$`1`

对P值排序并对预测值抽取序列

p1 <- sort(p) 
predy <- seq(p1[5], p1[as.numeric(nrow(traindata)) - 4], length = 50)

对预测的X和Y进行lowess回归拟合

smo <- lowess(p, as.numeric(def_ntree$y)-1, iter = 0)
plot(smo)

在这里插入图片描述
这个数据不够刚才的连续

plotdat<-as.data.frame(smo)
ggplot(plotdat, aes(x, y))+ 
  geom_line(aes(x = x, y = y), linewidth=1,col="blue")+
  annotate(geom = "segment", x = 0, y = 0, xend =1, yend = 1,color = "black",size=1)+ theme_minimal()+theme_bw()

在这里插入图片描述
我们使用插值法试一下

calibrated.orig <- approx(smo, xout = predy, ties = function(x) x[1])$y 
plot(predy, calibrated.orig, type = "l", lty=1,  col= "blue")
abline(0, 1, lty = 2)
legend <- list(x=0 + .55*diff(c(0,1)), y=0 + .32*diff(c(0,1)))
legend(legend, c("Apparent","Ideal"), lty=c(3,1,2), bty="n")

在这里插入图片描述
ties这里使用均值插补也是一样

calibrated.orig <- approx(smo, xout = predy, ties = mean)$y # calibrated.orig
plot(predy, calibrated.orig, type = "l", lty=1,  col= "blue")
abline(0, 1, lty = 2)
legend <- list(x=0 + .55*diff(c(0,1)), y=0 + .32*diff(c(0,1)))
legend(legend, c("Apparent","Ideal"), lty=c(3,1,2), bty="n")

在这里插入图片描述
美化一下

plot(predy, calibrated.orig, type = "l", lty=1,lwd=2, xlim = c(0,1), ylim = c(0,1), col= "blue")
abline(0,1,col="black",lty=2,lwd=2)
legend(0.55,0.35,
       c("Apparent","Ideal"),
       lty=c(2,1),
       lwd=c(2,1),
       col=c("black","blue"),
       bty="n")

在这里插入图片描述
基于这个方法,我们就可以制作出大部分模型的连续的校准曲线了。
我也随手写了一个gg5小程序,其实也没有什么,就是把过程打包一下,省点你的时间,你按我的方法完全可以复制出来,函数体如下

function(data,p,y,plot=NULL)

和我们的gg2一样,不管模型,我们绘制单独的校准曲线需要data, p, y 这3个指标,就是:数据集,预测概率和结果变量,plot=T的话自动绘图,不然就是生成绘图数据,需要手动绘图。
先绘制第一个数据的图

gg5(bc_train,pr1,bc_train$low,plot=T)

在这里插入图片描述
接下来就是随机森林的图

out<-gg5(data=traindata,p=p,y=traindata$default,plot=T)

在这里插入图片描述
需要我的gg5自写函数的公众号回复:代码

参考文献:

  1. rms包说明
  2. https://mp.weixin.qq.com/s/ISV9l9hLfRux7_3cDLRsXg

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

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

相关文章

基于组件化开发思想的微信小程序开发框架

跨端框架的出现为小程序应用的开发带来了巨大的便利性和灵活性。它们提供了统一的开发方式、代码复用的能力&#xff0c;并且与小程序容器技术紧密结合&#xff0c;实现了一次编码、多端运行的目标。开发者可以根据项目需求和团队技术栈选择合适的跨端框架&#xff0c;从而在不…

【大数据工具】Spark 伪分布式、分布式集群搭建

Spark 集群搭建 Spark 安装包下载地址&#xff1a;https://archive.apache.org/dist/spark/ 1. Spark 伪分布式安装 安装前提&#xff1a;安装 Spark 前需要先安装好 JDK 1. 上传并解压 Spark 安装包 使用 fileZilla 或其他文件传输工具上传 Spark 安装包&#xff1a;spar…

简单易懂的 nvm 和 Node.js 版本控制指南

NVM是Node.js的版本管理工具&#xff0c;可以方便地在不同版本的Node.js之间切换。它可以通过命令行或者脚本来管理Node.js的版本&#xff0c;支持在同一台机器上安装多个版本的Node.js&#xff0c;并能够方便地切换它们。 NVM的主要功能包括&#xff1a; 安装和卸载Node.js的不…

2022年国赛高教杯数学建模A题波浪能最大输出功率设计解题全过程文档及程序

2022年国赛高教杯数学建模 A题 波浪能最大输出功率设计 原题再现 随着经济和社会的发展&#xff0c;人类面临能源需求和环境污染的双重挑战&#xff0c;发展可再生能源产业已成为世界各国的共识。波浪能作为一种重要的海洋可再生能源&#xff0c;分布广泛&#xff0c;储量丰富…

DevExpress WinForms v23.1新功能抢先看——支持系统强调色更改

DevExpress WinForm 下一个主要版本&#xff08;v23.1&#xff09;将在6月份左右发布&#xff0c;本文将为大家介绍在早期访问预览版&#xff08;EAP&#xff09;中包含的新功能。 PS&#xff1a;DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具…

5月琐碎但值得的事情

转眼间时间就来到了6月份&#xff0c;又该写5月的思考总结了&#xff0c;依然记录一些5月份发生的小事或者收获&#xff0c; 这些内容本意给我记录生活的&#xff0c;如果对你有一些帮助就更好了。 往期&#xff1a; 1月的碎碎念&#xff0c;但是很有必要 二月的一些琐事&#…

chatgpt赋能python:Python如何阻止弹窗

Python如何阻止弹窗 Python是一种高级编程语言&#xff0c;它具有广泛的应用和丰富的库。它还可以被用于开发自动化程序&#xff0c;包括阻止弹窗。在本文中&#xff0c;我们将介绍如何使用Python阻止弹出窗口&#xff0c;并探讨防止弹窗的原因。 为什么要防止弹窗&#xff1…

Librosa库——语音识别,语音音色识别训练及应用

很多同学以为语音识别是非常难的&#xff0c;其实并不然&#xff0c;起初我也是这么认为&#xff0c;但后来发现语音识别是最简单的&#xff0c;因为同学们可能不知道Python有一个音频处理库Librosa&#xff0c;这个库非常的强大&#xff0c;可以进行音频处理、频谱表示、幅度转…

精彩回顾 | 来看 QTF 量化科技嘉年华上的 DolphinDB

6月2日至6月3日&#xff0c;2023“量变质变”量化科技嘉年华在上海世博中心圆满举办。 DolphinDB 作为联合主办方&#xff0c;在6月3日上午的“因子挖掘与机器学习”分论坛中&#xff0c;为广大量化粉丝们奉上了一场干货满满的主题分享与圆桌讨论&#xff0c;现场座无虚席&…

直击CACLP:新冠红利退潮,谁在裸泳,谁在冲刺?

5月可谓是很多医疗人马不停蹄的一个月&#xff0c;上海的第87届CMEF刚结束&#xff0c;28至30日&#xff0c;体外诊断&#xff08;IVD&#xff09;旗帜性行业盛会——第20届CACLP也在南昌绿地国际博览中心顺利落幕了。 纷享销客已经连续五年参与这两大行业盛会了&#xff0c;…

助力工业物联网,工业大数据之其他维度:组织机构【十五】

文章目录 01&#xff1a;其他维度&#xff1a;组织机构02&#xff1a;其他维度&#xff1a;仓库、物流附录一&#xff1a;常见问题1.错误&#xff1a;没有开启Cross Join2.错误&#xff1a;Unable to move source 01&#xff1a;其他维度&#xff1a;组织机构 目标&#xff1a;…

ChatGPT使用进阶,你一定要知道的应用技巧

鉴于ChatGPT的巨大能力&#xff0c;深入学习ChatGPT使用技巧势在必行。作为伴随着ChatGPT等大语言模型&#xff08;LLM&#xff09;出现的还有一个新的工程领域&#xff1a;提示工程&#xff08;Prompt Engineering&#xff09;。 提示工程&#xff08;Prompt Engineering&…

前端053_单点登录SSO_刷新令牌获取新令牌

刷新令牌获取新令牌 1、创建刷新令牌组件2、添加刷新组件路由配置3、EasyMock 添加刷新令牌接口4、定义 Api 调用刷新令牌接口5、Vuex 发送请求与重置状态6、重构刷新令牌组件7、测试当应用系统请求后台资源接口时,要在请求头带上 accessToken 去请求接口,如果 accessToken 有…

【Python】Python系列教程-- Python3 OS 文件/目录方法(二十七)

文章目录 前言语法错误异常异常处理try/excepttry/except...elsetry-finally 语句 抛出异常用户自定义异常定义清理行为预定义的清理行为 前言 往期回顾&#xff1a; Python系列教程–Python3介绍&#xff08;一&#xff09;Python系列教程–Python3 环境搭建&#xff08;二&…

前端数据传输失败

1 问题 通过postman可用传输数据到java但页面数据传输不成功 postman结果&#xff1a; 页面传输结果&#xff1a; 2 方法 在使用页面传输数据时不能直接使用send(username,password)&#xff0c;我们需要使用FromData属性&#xff0c;将username和password添加到FromData里&…

小程序框架Mpx的下一代脚手架升级之路|滴滴开源

导读 Mpx开源之路已经走过五个年头&#xff0c;目前支持了滴滴内部全量的小程序业务开发&#xff0c;是滴滴开源委员会孵化的精品项目。 2022年至今&#xff0c;我们对 Mpx 框架进行了多项重要功能升级&#xff0c;包括组合式API开发规范、分包异步构建支持、单元测试能力建设和…

C++知识第四篇之多态

目录 一.认识多态1. 多态分类2. 虚函数a. 介绍b. 虚函数的重写c. 协变d. 析构函数 3. 多态构成条件a. 虚函数调用多态b. 析构函数多态 4. C11新特性a. overrideb. final 5. 重载、重写(覆盖)、重定义(隐藏) 二. 抽象类1.介绍2. 接口继承 三. 多态原理1. 虚函数表2. 打印虚函数表…

力扣高频SQL50题(基础版)——第八天

力扣高频SQL50题(基础版)——第八天 1 游戏玩法分析 IV 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT ROUND(count(a2.f_date)/(SELECT count(distinct player_id) FROM Activity),2) fraction FROM Activity a1 INNER JOIN (SELECT player…

电容为什么可以通交流隔直流?

电容 电容是指容纳电荷的能力&#xff0c;在给定电位差下自由电荷的储藏量&#xff0c;记为C&#xff0c;国际单位是法拉&#xff08;F&#xff09;。 如上图所示&#xff0c;以平行板电容器为例&#xff0c;简单介绍下电容的基本原理。 在两块距离较近、相互平行的金属平板上…

hashMap 源码详解

1、 HashMap 底层源码解读(源码分析知识问答) 2、 什么是哈希碰撞&#xff1f;或者什么是哈希冲突&#xff1f;为什么会发生哈希冲突&#xff1f; 不同的关键字通过相同的哈希函数算出了一个相同的 哈希地址&#xff0c;这就叫做哈希冲突。 哈希冲突主要因为 哈希表底层的数组容…