Python代码反向解析列线图nomogram自动计算各项得分及总得分

如果想了解列线图制作的原理可以参照已有的文章,推荐的一篇:【肿瘤预测模型系列】Nomogram 绘制原理及R&SAS实现。

目录

  • 前言
  • 一、编程过程中的变量名称说明
  • 二、python代码反向解析列线图
    • 1.将OR值转换为beta值
    • 2.计算各个变量的取值范围
    • 3.取以上两者的乘积
    • 4.求各个变量的最大得分
    • 5.求各个变量单位刻度得分
    • 6.求实际取值时列线图各个变量的"距离"
    • 7.求实际取值时,各个变量的列线图得分
    • 8.求各个变量的得分之和(总得分)
    • 9.以上代码整理成函数
    • 10.举例
  • 总结


前言

总的来说,本文所做的工作是换一个角度来说明列线图的制作原理。之前的有许多的文章来已经说明了这个列线图是如何制作的,以及他这个评分是如何计算出来的,因为静态的列线图不便于实际的使用,通过编程的可以将分值的评分过程进行自动化。经过本人的研究,根据论文所公布的 OR值以及列线图所标注的内容就可以进行列线图分值计算的自动化,从这个过程中,我们也可以了解到列线图制作的一个过程。


提示:以下是本篇文章正文内容,下面案例可供参考

一、编程过程中的变量名称说明

在编程过程中用到了一些变量的名称,为了更地理解编程的过程,现在这里对这些变量的命名的名称做一些解释。
#ls_:列表(list);
#ls_or: OR值列表;
#ls_right_value:列线图中各变量右侧所标注的值;
#ls_left_value:列线图中各变量左侧所标注的值;
#ls_distance:列线图中各变量的取值范围, 即以上两个变量的差值;
#ls_xvar:列线图中各变量的取值。
Python代码反向解析列线图nomogram自动计算各项得分及总得分_第1张图片

二、python代码反向解析列线图

1.将OR值转换为beta值

代码如下,论文给出OR值是更长见:

ls_beta=[np.log(x) for x in ls_or]
ls_beta_abs=[np.abs(x) for x in ls_beta]#进一步取其绝对值

2.计算各个变量的取值范围

ls_distance_abs=[np.abs(a-b) for a,b in zip(ls_right_value,ls_left_value)]
# 各自标尺的右边数值与左边数值的差,也取其绝对值

3.取以上两者的乘积

  ls_pi_pre=[a*b for a,b in zip(ls_beta_abs,ls_distance_abs)]

4.求各个变量的最大得分

 ls_max_score=[]
 for pi_pre in ls_pi_pre:        
     max_score=np.divide(pi_pre,np.max(ls_pi_pre))*100
     ls_max_score.append(max_score)
#从这里可以看到,各个变量的最大得分是成比例的, "最大乘积"人为规定为100,其它的按照"乘积""最大乘积"的比例确定.

5.求各个变量单位刻度得分

# 计算过程是"最大得分"除以"变量取值范围"       
ls_unit_score=[a/b for a,b in zip(ls_max_score,ls_distance_abs)]

6.求实际取值时列线图各个变量的"距离"

# 求实际情况下,变量取某个值时,其与"最小取值"的距离(差值)      
ls_actual_distance=[a-b for a,b in zip(ls_xvar, ls_left_value)]
ls_actual_distance_abs=map(np.abs,ls_actual_distance)

7.求实际取值时,各个变量的列线图得分

#单位得分乘以实际的"距离"  
ls_score=[a*b for a,b in zip(ls_unit_score,ls_actual_distance_abs)]

8.求各个变量的得分之和(总得分)

total_score=0
for i,val in enumerate(ls_score):
   total_score +=ls_score[i]

9.以上代码整理成函数

整理成函数,提供括号内参数即可根据列线图计算出各个变量实际取值的得分和总得分,然后在列线图上查询可以获得事件发生的概率值,代码如下:

 def score(ls_right_value,ls_left_value,ls_or,ls_xvar):#提供列线图右边的数值和左边的数值,分类变量为10,多分类变量为多个10
        ls_beta=[np.log(x) for x in ls_or]
        ls_beta_abs=[np.abs(x) for x in ls_beta]
        ls_distance_abs=[np.abs(a-b) for a,b in zip(ls_right_value,ls_left_value)]# 各自标尺的右边数值与左边数值的差
        ls_pi_pre=[a*b for a,b in zip(ls_beta_abs,ls_distance_abs)]
        ls_max_score=[]#求各个变量最大的得分
        for pi_pre in ls_pi_pre:        
            max_score=np.divide(pi_pre,np.max(ls_pi_pre))*100
            ls_max_score.append(max_score)
        ls_unit_score=[a/b for a,b in zip(ls_max_score,ls_distance_abs)]#求各个变量每个刻度单位的得分
        ls_actual_distance=[a-b for a,b in zip(ls_xvar, ls_left_value)]#求实际的总得分
        ls_actual_distance_abs=map(np.abs,ls_actual_distance)
        ls_score=[a*b for a,b in zip(ls_unit_score,ls_actual_distance_abs)]
        total_score=0
        for i,val in enumerate(ls_score):
            total_score +=ls_score[i]
        return ls_score,total_score

10.举例

先提供一张列线图,与上面是同一张。
Python代码反向解析列线图nomogram自动计算各项得分及总得分_第2张图片提供相应的参数:ls_or, ls_right_value, ls_left_value, ls_xvar

if __name__=="__main__":
    ls_or=[1.26579,2.50828,0.94866]
    ls_score,total_score=logistic.score(ls_right_value=[10,1,10],ls_left_value=[1,0,75],ls_or=ls_or,ls_xvar=[5,1,40])
    print(ls_score)
#这里是求肿瘤直径为5,男性,40岁患者的各个变量的评分。

总结

以上过程说明了列线图的特点包括,1.线段的长短是按照“乘积”的比例确定的;2.“最大乘积”的得分人为确定为100分,其它“乘积”的得分按照比例计算。代码和示例都是逻辑回归构建的列线图。列线图中还有一个指标叫做“linear indicator”, 是可选项,其值是“PI-mean(PI)”,PI(prognostic index)是各个变量乘积的和,不包括intercept,“-mean(PI)”是一个"normalization"的数据处理方式,这个琢磨了好一阵子。本人目前致力于临床预测模型的构建和评价,列线图的推广和动态化,欢迎各位同好关注。

你可能感兴趣的:(研发管理,笔记,python,机器学习)