【统计分析】Bland-Altman图:MedCalc操作指南与Python实现

news2024/12/20 15:13:28

  之前有记录过一致性分析中的天选之子ICC(传送),也提到过Bland-Altman图,Bland-Altman图在一致性分析中作为一种既定量又定性的方法,还有着高颜值的表达展现,受到了广泛地应用。
  如下图所示,Bland-Altman分析主打一个高端大气:
在这里插入图片描述
  图源论文:Comprehensive Assessment of Coronary Calcification in Intravascular OCT Using a Spatial-Temporal Encoder-Decoder Network

1. Bland-Altman图简介

  Bland-Altman分析主要运用到什么场景呢?比较两种方法测量的一致性。例如:测量脑出血的体积,医生手动测量会得到一组值,而基于深度学习的分割模型测量会得到另一组值,利用Bland-Altman分析可以评价模型与医生测量结果之间的一致性与偏差。简言之,衡量模型是否可靠,能不能用于临床实践。
  此外,Bland-Altman图也可用于评估一种测量技术的可重复性,通过对一系列受试者使用单一方法进行重复测量进行比较。在这种情况下,Bland-Altman图还可以用来检查方法的可变性或精确度是否与被测量的特征的大小有关。
  那么Bland-Altman图表达了什么呢?Bland-Altman图是散点图,设对 K K K 个样本的测量,医生测量值为 X = { x 1 , … , x K } X = \left\{ {{x_1}, \ldots ,{x_K}} \right\} X={x1,,xK},模型测量值为 Y = { y 1 , … , y K } Y = \left\{ {{y_1}, \ldots ,{y_K}} \right\} Y={y1,,yK},对于每一个样本,一般情况下,Bland-Altman图中的纵坐标为 x i {x_i} xi y i {y_i} yi 的差值,横坐标为 x i {x_i} xi y i {y_i} yi 差值的均值。

2. MedCalc操作指南

(1)数据录入:File→New 新建一个data,录入数据,类似于excel表格

在这里插入图片描述

(2)绘制Bland-Altman图:Statistics→Method comparison→Bland & Altman plot

出现以下对话框

在这里插入图片描述

①First/Second method: 分别选择两组数据

②Plot against(X-axis): 横坐标x轴,一般选择Average of both methods
  Average of both methods: 两组数据的平均值
  First/Second method: 以其中一组数据为横坐标
  Geometric mean of both methods: 两组数据的几何平均数

③纵坐标y轴:
  Plot differences: 两组数据的差值
  Plot difference as %: 两组数据差值占均值的百分比,当差异的可变性随着测量幅度的增加而增加时,此选项非常有用。
  Plot ratios: 绘制两组数据的比值而非差值,当差异的可变性随着测量幅度的增加而增加时,该选项也很有用,然而,当First/Second method任何一种包含零值时,程序将给出警告。

④显示Options:
  Draw line of equality (difference=0) : 绘制差值 d=0 的横线,用于检测系统差异
  Draw lines for 95%CI of mean of difference: 绘制差值平均值的95%置信区间,平均差异的95% CI说明了系统性差异的大小。如果差值 d=0 的横线不在区间内,则存在显著的系统差异。
  Draw lines for 95% CI of limits of agreement: 显示一致性上限和下限的95%置信区间的线条。
  Draw regression line of differences: 绘制差值的回归线,并可以给出回归线 95% 置信区间(95% Confidence Interval)

选择好后,点击确定,得到Bland-Altman图如下:

在这里插入图片描述

  图中上下两条 棕色水平虚线 表示 95%一致性界限的上下限,中间的 蓝色水平实线 代表差值的平均值,橘黄色水平虚线 表示差值平均值为 0 的位置,绿色的虚点画线 为差值平均值的95%置信区间; 两种方法测量结果的一致程度越高,代表差值平均数的线( 蓝色实线 )就越接近代表差值平均数为 0 的线( 橘黄色虚线 )。

在Bland-Altman图上右键→info 可以查看详细数据信息
在这里插入图片描述

3. Python实现

  当然了,Python也可以方便地完成Bland-Altman图绘制

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt


def bland_altman_plot(data1, data2, *args, **kwargs):
    data1 = np.asarray(data1)
    data2 = np.asarray(data2)
    mean = np.mean([data1, data2], axis=0)  # data1与data2的均值
    diff = data1 - data2  # data1与data2的差值
    md = np.mean(diff)  # data1与data2差值的平均值
    sd = np.std(diff, axis=0)  # data1与data2差值的标准差
    
    plt.rcParams['font.sans-serif'] = ['Times New Roman']
    plt.rcParams['axes.facecolor'] = 'whitesmoke'
    plt.rcParams['axes.unicode_minus'] = False

    fig = plt.figure(figsize=(7.5, 5), dpi=300)
    ax = plt.axes()
    ax.set_facecolor('white')
    ax.set_xmargin(0.16)

    plt.axhline(md, color='purple', linestyle='-.', lw=2, zorder=1)
    plt.axhline(md + 1.96 * sd, color=sns.color_palette()[3], linestyle='--', lw=2, zorder=1)

    print('差值的均值为:%.3f (%.3f ~ %.3f)' % (md, md - 1.96 * sd, md + 1.96 * sd))
    plt.axhline(md - 1.96 * sd, color=sns.color_palette()[3], linestyle='--', lw=2)
    plt.scatter(mean, diff, *args, **kwargs, marker="o", s=60, color="", edgecolor="royalblue", alpha=1, zorder=2)
    plt.ylim(-0.2, 0.7)
    
    ax.spines['top'].set_linewidth(1.8)
    ax.spines['right'].set_linewidth(1.8)
    ax.spines['bottom'].set_linewidth(1.8)
    ax.spines['left'].set_linewidth(1.8)

    # 区间上界
    plt.text(max(mean) + 0.008, md + 1.96 * sd + 0.015, '1.96 SD', fontsize=14)
    plt.text(max(mean) + 0.070, md + 1.96 * sd - 0.045, '%.3f' % (md + 1.96 * sd), fontsize=14)
    # 均值线
    plt.text(max(mean) + 0.070, md + 0.015, 'Mean', fontsize=14)
    plt.text(max(mean) + 0.070, md - 0.045, '%.3f' % md, fontsize=14)
    # 区间下界
    plt.text(max(mean) - 0.045, md - 1.96 * sd + 0.015, '-1.96 SD', fontsize=14)
    plt.text(max(mean) - 0.010, md - 1.96 * sd - 0.045, '%.3f' % (md - 1.96 * sd), fontsize=14)

    plt.xlabel("Mean value between doctor and model", fontsize=16)  
    plt.ylabel("Difference between doctor and model", fontsize=16)
    plt.gcf().subplots_adjust(bottom=0.15)

    plt.tick_params(width=1.5, labelsize=14)  
    plt.show()

data1 = [5.49, 3.41, 5.25, 4.41, 4.07, 5.94, 5.76, 4.81, 5.77, 4.84,
         4.50, 4.53, 6.25, 5.33, 5.15, 5.38, 4.98, 6.37, 5.67, 4.52,
         5.26, 5.79, 4.58, 5.00, 4.89, 4.80, 4.69, 4.80, 4.92, 5.52,
         4.03, 3.26, 4.99, 5.17, 3.91, 4.07, 4.96, 4.81, 3.99, 7.03,
         3.99, 5.74, 4.73, 5.04, 4.72, 5.23, 4.78, 4.58, 4.45, 4.22,
         4.95, 5.23, 4.63, 4.82, 4.90, 4.32, 3.79, 4.99, 4.29, 4.76,
         4.60, 4.20, 6.45, 4.15, 4.68, 4.99, 5.09, 5.23, 5.04, 4.31, 
         5.27, 4.33, 5.95, 3.66, 6.32, 4.49, 4.14, 5.32, 6.12, 4.19]

data2 = [5.41, 3.21, 5.15, 4.38, 3.89, 5.76, 5.40, 4.61, 5.44, 4.39, 
         4.57, 4.46, 5.86, 4.99, 4.82, 5.22, 4.97, 6.03, 5.18, 4.46, 
         5.04, 5.31, 4.37, 4.81, 4.54, 4.29, 4.69, 4.68, 4.67, 5.38, 
         3.92, 3.21, 4.87, 5.00, 3.58, 3.80, 4.75, 4.80, 3.89, 6.77, 
         3.84, 5.49, 4.47, 4.39, 4.64, 5.11, 4.66, 4.41, 4.43, 3.96, 
         4.89, 4.99, 4.50, 4.67, 4.61, 4.09, 3.64, 4.60, 4.21, 4.55,
         4.65, 4.13, 6.09, 3.94, 4.53, 4.74, 5.01, 4.71, 4.41, 4.13, 
         5.18, 4.18, 5.29, 3.47, 6.09, 4.39, 3.94, 5.17, 5.82, 3.96]

bland_altman_plot(data1, data2)

如下图所示:主打一个个性设置

在这里插入图片描述

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

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

相关文章

Explaining predictive models: the Evidence Counterfactual

Imagine being targeted with an advertisement for this blog. You’d like to know: why did the AI model predict you’d be interested in the Faculty of Business and Economics’ blog, based on the hundreds of web pages you visited? The answer could be: becaus…

搭建ubuntu容器内C/C++开发调试环境

一、创建容器 为了让容器内的调试器(gdb、lldb)能够正常调试,在创建容器时需要添加参数: podman添加参数:--cap-addSYS_PTRACE,docker添加参数--cap-addSYS_PTRACE --security-opt seccompunconfined 否…

chatgpt赋能python:Python快捷键——另存为

Python快捷键——另存为 Python是一种高级编程语言,由Guido van Rossum于1991年创立。它的干净简洁,常规用途在计算机编程领域找到了广泛的应用。Python语言是一种普遍而有效的编程语言,有不少的Python程序员喜欢利用快捷键来提高编程效率。…

中医养生APP小程序开发 了解传统文化传承医学经典

中国文化博大精深,中国传统文化更是历史久远,一直到几千年后的今天很多传统文化依然对我们现在的生活有着重大的影响,比如中医。随着人们对健康关注度的提高,很多人把目光投向了追本溯源的中医上,企图通过中医养生达到…

搜索算法(四) 广度优先搜素算法

一、BFS bfs一层一层地遍历图或树,一般用队列实现,可以计算距离目标的步数。 二、例题 1) 力扣https://leetcode.cn/problems/shortest-bridge/ 这道题实际是计算两个岛屿之间的最短距离,可以先用dfs搜索到第一个岛屿并且记录第…

TDEngine - taosdump的安装与使用实战

taosdump的安装与使用实战 一、taosdump简介二、下载三、安装四、taosdump主要参数五、taosdump数据导出(备份)六、taosdump数据导入七、不同版本的数据迁移7.1 问题:报错- create database 语句不一致7.2 解决:修改导出的dbs.sql…

MTK平台的SWT异常的简单总结(2)——SWT原理和分析

(1)原理性 (2)SWT如何抓取Log 遇到SWT问题详细可参考MTK提供的FAQ:SWT机制介绍。 获取Ap Log的路径:/sdcard/debuglogger/mobilelog/APLog_XXXXX 获取db的路径:/data/aee_exp 如果db没有打包…

RK3288 Android5.1添加WiFiBT模块AP6212

CPU:RK3288 系统:Android 5.1 注:RK3288系统,目前 Android 5.0 Kernel 3.10 SDK 支持 Braodcom,Realtek 等 WiFi BT 模块 各个 WiFi BT 模块已经做到动态兼容,Android 上层不再需要像以前一样进 行特定宏的配置 此…

华为OD机试真题 Java 实现【关联子串】【2023Q1 100分】,附详细解题思路

一、题目描述 给定两个字符串str1和str2, str1进行排列组合只要有一个为str2的子串则认为str1是str2的关联子串, 请返回子串在str2的起始位置,若不是关联子串则返回-1。 二、输入描述 qwe dsgfasgfwe 三、输出描述 -1 四、解题思路 …

遇到大数据处理,你会怎么办?快来看一下位图和布隆过滤器(下)

目录 前文 一,为什么有布隆过滤器 二,什么是布隆过滤器 三,布隆过滤器的实现 四,布隆过滤器的优缺点 4.1 布隆过滤器的优点 4.2 布隆过滤器的缺点及其改进方式 4.2.1 查找误判及其改进方式分析 4.2.2 不能删除以及改进方式分…

【HTML】第 1 节 - HTML 初体验

欢迎来到博主 Apeiron 的博客,祝您旅程愉快 。 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、HTML 概念 2.1、HTML 定义 2.2、标签语法 3、HTML 基本骨架 4、标签的关系 5、注释 6、总结 1、缘起 最近在学习微信小程…

程序员0基础转行大数据年薪25万,只因我做了这件事...

现在我在成都的一家企业做大数据架构师,一个月税前可以拿到20k,还有项目奖金,一年下来最少也能拿25万。生活和工作也都在有条不紊地运转,每天也会有新的挑战,这正是我想要的生活。 01 机械工程专业 但我决定转行互联…

SpringBoot自定义starter之接口日志输出

文章目录 前言文章主体1 项目全部源码2 项目结构介绍3 starter 的使用3.1 配置文件 application,yml的内容3.2 启动类3.3 控制器类 4 测试结果 结语 前言 本文灵感来源是一道面试题。 要求做一个可以复用的接口日志输出工具,在使用时引入依赖,即可使用。…

MySQL数据库 10.DCL操作

目录 🤔 前言: 🤔DCL介绍: 🤔1.DCL管理用户: 1.查询用户: 图示: 2.创建用户 示例1: 运行结果:​ 示例2: 运行结果:​ 3.修改…

算法修炼之筑基篇——筑基一层中期(解决01背包,完全背包,多重背包)

✨博主:命运之光​​​​​​ 🦄专栏:算法修炼之练气篇​​​​​ 🍓专栏:算法修炼之筑基篇 ✨博主的其他文章:点击进入博主的主页​​​​​​ 前言:学习了算法修炼之练气篇想必各位蒟蒻们的基…

安全——网络安全协议的引入

TCP/IP安全缺陷 信息泄露 概述 网络中投递的报文往往包含账号、口令等敏感信息,若这些信息泄露则是灾难性的后果。其中嗅探是一种常见而隐蔽的网络攻击手段。 嗅探 概述 问题:在共享式网络架构下,所有的数据都是以广播方式进行发送&…

程序员大专毕业,月薪2w是什么体验?

在这个数据驱动的时代,大数据行业的发展前景也非常广阔,我相信我的未来会越来越光明 01 开始学习 是迈向前方的第一步 我是三月,一个来自小城市的大专毕业生。现在在杭州一家公司做大数据开发工程师,目前薪资是20k*13。 我本身…

运维小白必学篇之基础篇第十三集:网络概述中继实验

网络概述中继实验 实验作业(主机名为自己的名字): 1、搭建中继环境,要求如下: 网络要求: 内网:192.168.50.50 网关:192.168.50.254 192.168.60.254 外网:192.168.60.60 主…

【论文阅读】An Object SLAM Framework for Association, Mapping, and High-Level Tasks

一、系统概述 这篇文章是一个十分完整的物体级SLAM框架,偏重于建图及高层应用,在前端的部分使用了ORBSLAM作为基础框架,用于提供点云以及相机的位姿,需要注意的是,这篇文章使用的是相机,虽然用的是点云这个…

DevOps该怎么做?

年初在家待了一段时间看了两本书收获还是挺多的. 这些年一直忙于项目, 经历了软件项目的每个阶段, 多多少少知道每个阶段是个什么, 会做哪些事情浮于表面, 没有深入去思考每个阶段背后的理论基础, 最佳实践和落地工具. 某天leader说你书看完了, 只有笔记没有总结, 你就写个总结…