• Posts tagged "传染病"

Blog Archives

用R语言解读传染病模型

算法为王系列文章,涵盖了计算机算法,数据挖掘(机器学习)算法,统计算法,金融算法等的多种跨学科算法组合。在大数据时代的背景下,算法已经成为了金字塔顶的明星。一个好的算法可以创造一个伟大帝国,就像Google。

算法为王的时代正式到来….

关于作者:

  • 张丹, 分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-infectious-disease

前言

传染病学是人们在不断地同危害人类健康严重的疾病作斗争中发展起来的,新冠疫情已经持续三年了,近期在北京和上海两个超大城市,还在不停的变种和传播,居家办公,每天核酸,都已经变成了生活的常态。

好奇心驱使我要研究一下传染病,为什么疫情会有这么大的传染性,如果不做防控会怎么样。结合传染病学的专业知识,通过R语言的技术手段,彻底明白了传染病传播的一些底层原理。

由于本人非传染病专业,文中关于传染病的专业内容大都从网上汇集和再整理,当出现本文描述与教课书不符时,请以专业教材为准。

目录

  1. 传染病动力学介绍
  2. 自由增长模型
  3. SI模型
  4. SIS模型
  5. SIR模型

1. 传染病动力学介绍

在全球抗击新冠肺炎疫情的过程中,传染病动力学模型发挥了巨大的作用。传染病动模型,根据传染病的传播速度不同,空间范围各异,传播途径多样,动力学机理等各种因素,对传染病模型按照传染病的类型划分为 SI,SIR,SIRS,SEIR 模型。

对传染病的研究方法主要有四种:描述性研究、分析性研究、实验性研究和理论性研究。传染病动力学是对传染病进行理论性定量研究的一种重要方法。它是根据种群生长的特性,疾病的发生及在种群内的传播、发展规律,以及与之有关的社会等因素,建立能反映传染病动力学特性的数学模型。通过对模型动力学性态的定性、定量分析和数值模拟,来显示疾病发展程,寻找对期预防和控制的最优策略。

2. 自由增长模型

自由增长模型,是一种条件最简单的传染病模型,模型整体上呈现指数增长趋势,对传染病传播率ρ非常敏感。模型适合于古代医疗条件不发达、不懂得对病人进行防疫隔离时,发生恶性瘟疫的情形。

模型假设:

  • I(t)为t时刻的感染者人数,I(t)是连续、可微函数。
  • ρ是常数,为每个病人每天有效接触的人数,即足以使人致病的接触, ρ >0

模型构建:

  • 从t到t+Δt的时间里,病人增加的人数为
I(t+Δt) – x(t) = ρ * I(t)* Δt

模型求解:

  • 当t=0时,初始病人人数为 I0 得,

𝑑𝐼/𝑑𝑡= ρ * I
I(0) = I0

R语言代码实现


# 加载程序包
> library(deSolve)  # 用于计算积分
> library(magrittr) 
> library(ggplot2)
> library(reshape2)
> setwd("C:/work/R/covid19")

定义2个公共函数,draw()函数用于画图,rbinddf()函数用于list转型为data.frame。


# 画图函数
> draw<-function(sdf,title="SIR模型",ylab="感染人数",xlab="时间周期",ylog=FALSE){
+   g<-ggplot(data = sdf, mapping = aes(x=time,y=value,colour=type))
+   g<-g+geom_line() + geom_point()                                   #绘制线图和点图
+   g<-g+scale_shape_manual(values = c(21,23))                        #自定义点形状
+   if(ylog) g<-g+scale_y_log10()
+   g<-g+ggtitle(title)+xlab(xlab)+ylab(ylab)
+   g
+ }

# 按行合并
> rbinddf<-function(ldf=list(),names=NULL){
+   n <- length(ldf)
+   res <- NULL
+   if(n>0){
+     for (i in seq(n)) {
+       if(!is.null(names)){
+         type <- names[i]
+       }
+       res <- rbind(res, data.frame(ldf[[i]],type=type))
+     }
+   }
+   return(res)
+ }

定义自由增长模型内核函数


# case1 自由增长模型
> calc1 <- function(rio = 0.3,         # 传染率系数,每个病人每天传染的人数
+                   times = 0:20,      # 病情发展时间
+                   I = 1) {           # 已感染者1人
+   # 公式
+   s_equations <- function(times, vars, params) {
+     with(as.list(c(vars, params)), {
+       dI <- rio * I
+       return(list(dI))
+     })
+   }
+   
+   # 解微分方程
+   ode(
+     func = s_equations,
+     y = c(I = I),
+     times = times,
+     parms = c(rio = rio)
+   ) %>%  as.data.frame
+ }

分别计算当ρ(rio) = 0.3, 0.25, 0.2 时的感染者人员。


> s1 <- calc1(rio = 0.3)
> s2 <- calc1(rio = 0.25)
> s3 <- calc1(rio = 0.2)

# 合并3组结果
> sdf1<-rbinddf(list(s1,s2,s3),names=c("s1","s2","s3"))
> head(sdf1)         # 查看数据集
  time        I type
1    0 1.000000   s1
2    1 1.349861   s1
3    2 1.822121   s1
4    3 2.459609   s1
5    4 3.320123   s1
6    5 4.481699   s1

把模拟进行可视化展示。


> names(sdf1)<-c("time","value","type")
> draw(sdf1,title="自由增长模型",ylab="感染人数",xlab="时间周期")

输出如图所示

自由增长模型,并不符合实际情况。在病人有效接触的人群中,有健康人也有病人,而其中只有健康人才可以被传染为病人,所以我们接下来介绍的SI模型,就区别2类人群。

3. SI模型

SI模型,适用于只有易感者和患病者两类人群,且不会反复发作的疾病。人群分为易感染者(Susceptible)和已感染者(Infective)两类(取两个词的首字母,称之为SI模型)。

易感者与患病者有效接触即被感染,变为患病者,无潜伏期、无治愈情况、无免疫力。SI模型对传染病传播率ρ非常敏感,而且只要我们把每个病人、每天接触的人数有效降低,传染病的传染速度就会变得非常慢。只要防疫力度够大,控制住传染病是完全可能的。这种模型比较适合,被传染后无法恢复健康的,比如HIV等情形。

模型假设:

  • I(t)为t时刻的感染者人数,I(t)是连续、可微函数。
  • ρ是常数,为每个病人每天有效接触的人数,即足以使人致病的接触, ρ >0
  • 在疾病传播期内所考察地区的总人数不变,不考虑生死和迁移。
  • 当病人与健康者有效接触时,使健康者受感染变为病人

模型构建:
已感染人数为 N * i(t),所有已感染人每天有效接触人数为 ρ * N * i(t),其中被传染的易感染人的比例 s(t),因此每天增加的感染者人数为 ρ * N * i(t) * s(t)。

  • N:总人数,不变
  • s(t):t时刻易感染者在总人数中所占比例。
  • i(t):t时刻已感染者在总人数中所占比例。
  • ρ是常数,每个病人每天有效接触的平均人数是常数,称为日接触率, ρ >0

从t到t+Δt的时间里,病人增加的人数为

N * (i(t+Δt)– i(t)) = ρ *  i(t) * s(t) * Δt

模型求解:

  • N总人数不变,因此 s(t) + i(t) = 1
  • 当t=0时,初始病人占比为 i0 得,

𝑑𝑖/𝑑𝑡= ρ * i * (1-i)
i(0) = 𝑖0

编写模型内核函数。


> calc2 <- function(rio = 0.3,                # 接触率,传染率系数
+                  times = 0:100,             # 病情发展时间
+                  i = 0.000001) {            # 已感染者,初始占比:百万分之一
+   # 公式
+   si_equations <- function(time, vars, params) {
+     with(as.list(c(vars, params)), {
+       di <- rio * i * (1 - i)
+       return(list(di))
+     })
+   }
+   
+   # 解微分方程
+   ode(
+     func = si_equations,  
+     y = c(i = i),         
+     times = times,        
+     parms = c(rio = rio)
+   ) %>%  as.data.frame
+ }

分别计算当传播率ρ(rio)为0.3,0.25,0.2,0.15,0.12时的结果,已感染者比例𝑖0 =0.000001(百万分之一)


> si1 <- calc2(rio = 0.3)
> si2 <- calc2(rio = 0.25)
> si3 <- calc2(rio = 0.2)
> si4 <- calc2(rio = 0.15)
> si5 <- calc2(rio = 0.12)
> sdf2<-rbinddf(list(si1,si2,si3,si4,si5),
+              names=c("si1","si2","si3","si4","si5"))
> names(sdf2)<-c("time","value","type")

# 画图
> draw(sdf2,title="SI模型",ylab="感染人数占比",xlab="时间周期")

4. SIS模型

人群分为易感染者(Susceptible)和已感染者(Infective)两类,已感染者(Infective)可以被治愈,变成易感染者(Susceptible)(称之为SIS模型)。SIS模型与SI模型的差异,在于SIS模型假设已感染者(Infective)可以被治愈,重新变成易感染者(Susceptible),比如季节性流感等。

1、传染的速度,取决于病人的传染速度,与病人的治愈速度之间的相对水平,如果病人的治愈速度,大于病人的传染速度,即μ>ρ,那么该传染病最终会消失;
2、即便病人的传染速度高于治愈速度,最终也只有一部分人群会被感染;
3、最终感染的人群比例,为1-1/sigma,sigma = ρ / μ ,sigma是整个传染期内每个病人的有效接触人数,可以理解为病人在整个生病期内,接触的总人数。

模型假设

  • 在疾病传播期内所考察地区的总人数不变,不考虑生死和迁移。
  • 当病人与健康者有效接触时,使健康者受感染变为病人。
  • 人被全部治愈,所需要的天数为1/μ,为传染病的平均传染期。

模型构建:
已感染人数为 N * i(t),所有已感染人每天有效接触人数为 ρ * N * i(t),其中被传染的易感染人的比例 s(t),因此每天增加的感染者人数为 ρ * N * i(t) * s(t)。被治愈的人数为 μ * N * i(t)。

  • N:总人数,不变
  • s(t):t时刻易感染者在总人数中所占比例。
  • i(t):t时刻已感染者在总人数中所占比例。
  • ρ是常数,每个病人每天有效接触的平均人数是常数,为日接触率, ρ >0
  • μ是常数,每天被治愈的病人数占病人总数的比例,为日治愈率

从t到t+Δt的时间里,病人增加的人数为

N * (i(t+Δt)– i(t)) = ρ *  i(t) * s(t) * Δt – μ * N * i(t) * Δt

模型求解:

  • N总人数不变,因此 s(t) + i(t) = 1
  • 当t=0时,初始病人占比为 i0 得,

𝑑𝑖/𝑑𝑡= ρ * i * (1-i) – μ * i
i(0) = 𝑖0

编写模型内核函数。


> calc3 <- function(rio = 0.3,                 # 接触率,传染率系数
+                   mu=0.1,                    # 治愈率
+                   times = 0:150,             # 病情发展时间
+                   i = 0.000001) {            # 已感染者初始占比:百万分之一
+   sis_equations<-function(time,vars,params){
+     with(as.list(c(vars,params)),{
+       di<-rio*i*(1-i)-mu*i
+       return(list(c(di)))
+     })
+   }
+   
+   ode(
+     func=sis_equations,
+     y=c(i=i),
+     times=times,
+     parms=c(rio=rio,mu=mu)
+   ) %>% as.data.frame()
+ }

分别日接触率 ρ(rio) = 0.3、0.25、0.2、0.15、0.12,日治愈率 μ =0.1,已感染者比例 𝑖0 =0.000001(百万分之一)


> sis1 <- calc3(rio = 0.27,mu=0.1)
> sis2 <- calc3(rio = 0.25,mu=0.1)
> sis3 <- calc3(rio = 0.20,mu=0.1)
> sis4 <- calc3(rio = 0.15,mu=0.1)
> sis5 <- calc3(rio = 0.12,mu=0.1)
> sdf<-rbinddf(list(sis1,sis2,sis3,sis4,sis5),
+              names=c("sis1","sis2","sis3","sis4","sis5"))
> names(sdf)<-c("time","value","type")
> draw(sdf,title="SIS模型",ylab="感染人数占比",xlab="时间周期")

5. SIR模型

人群分为易感染者(Susceptible)和已感染者(Infective)和恢复者(Removed)三类(称之为SIR模型)。SIR模型与SIS模型的差异,在于SIR模型假设已感染者(Infective)被治愈后会具备免疫力,不会被感染,从而成为恢复者(Removed),SIR模型已经初步接近实际的传染病模型。

模型假设:

  • 在疾病传播期内所考察地区的总人数不变,不考虑生死和迁移。
  • 当病人与健康者有效接触时,使健康者受感染变为病人。
  • 人被全部治愈,所需要的天数为1/μ,为传染病的平均传染期。

模型构建:
已感染人数为 N * i(t),已感染人每天有效接触人数为 ρ * I(t),被传染的易感染人的比例 S(t)/N,因此每天增加的感染者人数为 ρ * I(t) * S(t)/N,被治愈的人数为 μ * I(t)。

  • N:总人数,不变
  • S(t):t时刻易感染者在总人数中所占比例。
  • I(t):t时刻已感染者在总人数中所占比例。
  • R(t): t时刻恢复者在总人数中所占比例。
  • ρ是常数,每个病人每天有效接触的平均人数是常数,为日接触率, ρ >0
  • μ是常数,每天被治愈的病人数占病人总数的比例,为日治愈率

从t到t+Δt的时间里,易感染者人数,已感染者人数,恢复者人数计算:


# 易感染者人数计算
S(t+ Δt) – S(t) = - ρ * I(t) * Δt/N   

# 已感染者人数计算
I(t+ Δt) – I(t) = ρ * I(t) * S(t) * Δt/N - μ * I(t) * Δt

# 恢复者人数计算
R(t+ Δt) – R(t) = μ * I(t) * Δt

模型求解:

  • N总人数不变,因此 s(t) + i(t) = 1
  • 当t=0时,初始病人占比为 i0 得,

𝑑𝑆/𝑑𝑡= -ρ * I * S/N
𝑑𝐼/𝑑𝑡= ρ * I * S/N – μ * I
𝑑𝑟/𝑑𝑡= μ * I

编写模型内核函数。


> calc4 <- function(rio = 0.3,                 # 接触率,传染率系数
+                   mu=0.1,                    # 治愈率
+                   times = 0:150,             # 病情发展时间
+                   S=1000*1000*10,            # 易感染者1000万人
+                   I=10,                      # 已感染者10人
+                   R=5) {                     # 已移出者5人
+   sir_equations<-function(time,vars,params){
+     with(as.list(c(vars,params)),{
+       N<-S+I+R
+       dS<- -rio*I*S/N
+       dI<-rio*I*S/N - mu*I
+       dR<-mu*I
+       return(list(c(dS,dI,dR)))
+     })
+   }
+   ode(
+     func=sir_equations,
+     y=c(S=S,I=I,R=R),
+     times=times,
+     parms=c(rio=rio,mu=mu)
+   ) %>% as.data.frame()
+ }

当日接触率ρ(rio) = 0.25,日治愈率 μ(mu) =0.1,易感染者S=1000*1000*10,已感染者 I=10,移出者R=100


> sir1<-calc4(rio=0.25,mu=0.1,times=0:150,S=1000*1000*10,I=10,R=100)
> head(sir1)
  time        S        I        R
1    0 10000000 10.00000 100.0000
2    1  9999997 11.61831 101.0789
3    2  9999994 13.49852 102.3324
4    3  9999991 15.68299 103.7887
5    4  9999986 18.22099 105.4808
6    5  9999981 21.16971 107.4466
> sdf4<-melt(sir1,id.vars = c("time"))
> head(sdf4)
  time variable    value
1    0        S 10000000
2    1        S  9999997
3    2        S  9999994
4    3        S  9999991
5    4        S  9999986
6    5        S  9999981
> names(sdf4)<-c("time","type","value")
> draw(sdf4,title="SIR模型",ylab="感染人数",xlab="时间周期")

通过对传播病动力学的基本模型学习,让我了解了传染病的传播基本知识,使我更加坚信坚持“动态清零”的意义是重大的。文本以手写R代码实现模型为主,下一篇文章:用专业工具EpiModel玩转传染病模型

参考文章:

文本完整的代码,已经上传github,可以自由下载使用:https://github.com/bsspirit/infect/blob/main/code/model.r

转载请注明出处:
http://blog.fens.me/r-infectious-disease

打赏作者

2022 微软Build After Party:用R语言解读传染病模型

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹,数据分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-ms-build-20220618

前言

近期疫情的反复不断,让北京和上海2个超大城市也受到疫情影响。居家办公,远程开会,已经成为了生活的常态。在这样的背景下,我学习了一些传染病的知识,理解国家坚持动态清零政策的布局,是非常有必要的。

使用R语言结合传染病领域前辈们的专业经验,可以让我们快速上手跨学科的领域,并模拟疫情传播的场景。通过本次分享让大家能感受到疫情传播的可怕,以及我们需要积极的面对,和科学的预防。

目录

  1. 我分享的主题:用R语言解读传染病模型
  2. 会议体验和照片分享

1. 我分享的主题:用R语言解读传染病模型

本次分享的主题,用R语言解读传染病模型。新冠疫情几次变异,极大地影响着我们的正常生活和工作。特别是2022年2月以来的Delta变异株感染,在上海和北京这种人口超大型城市中,有着超强的传染力。政府防疫工作的强力介入,隔离和居家已经是常态了,有新闻指出Delta变异株感染1人可传9人。

在流行病学领域,有几种不同传染病的传播模型,可以模拟病毒的传播过程。本次分享将使用R语言,来给大家演示病毒传播的过程。了解了病毒传播的逻辑,能让我们更加坚定战胜病毒的决心。本次分享的PPT和代码,我上传到了github:https://github.com/bsspirit/infect

我主要为分5个部分进行介绍:

  1. 传染病模型原理:自由增长模型、SI模型、SIS模型、SIR模型
  2. 用R语言手动实现
  3. 基于EpiModel包的自动化实现
  4. 如何获取新冠数据
  5. 北京的数据带入模型预测

在传染病领域,有4种最基本的传染病模型,分别是自由增长模型、SI模型、SIS模型、SIR模型,这4个模型,分别涉及到现实从得病到治愈再到得病等的病人的状态,通过状态转移人数在计算传播效率。这4个模型,都是可以通过微分方程进行求解的,所以我们可以手动撸代码来计算。具体使用可参考:用R语言解读传染病模型

当然在R语言中,传染病领域专家也提供了,专门的工具包来帮助我们解决传染病的计算和模型的问题,这就是EpiModel包。 EpiModel,提供了用于模拟和分析传染病动力学数学模型的工具,支持的流行病模型类包括确定性隔间模型、随机个体接触模型和随机网络模型。疾病类型包括有和没有人口统计的 SI、SIR 和 SIS 流行病,具有可用于扩展的实用程序,以构建和模拟任意复杂性的流行病模型。 网络模型类基于在 R 的 Statnet 软件套件中实现的时间指数随机图模型 (ERGM) 的统计框架。具体使用可参考:专业工具EpiModel解读传染病模型

2. 会议体验和照片分享

本次活动是微软直通车的活动,主要由微软MVP给大家进行一些技术分享,我们不讲虚的都是干活,边讲PPT,边撸代码。

本次会议报名页: https://mp.weixin.qq.com/s/AXbQO718ZwfYhJ–6bGKyA

2.1 会议主题

MVP嘉宾代表团:由 3位MVP组成,郝冠军,卿毅,张丹。

张丹,用R语言进行量化文本分析,像结构化数据一样来管理文本PPT下载

新冠疫情几次变异,极大地影响着我们的正常生活和工作。特别是2022年2月以来的 Delta 变异株感染,在上海和北京这种人口超大型城市中,有着超强的传染力。政府防疫工作的强力介入,隔离和居家已经是常态了,有新闻指出 Delta 变异株感染1人可传9人。

在流行病学领域,有几种不同传染病的传播模型,可以模拟病毒的传播过程。本次分享将使用R语言,来给大家演示病毒传播的过程。了解了病毒传播的逻辑,能让我们更加坚定战胜病毒的决心。

卿毅,Dynamics 365 与 Power Platform 的集成

低代码/零代码是现在企业数字化转型非常重要的一环。在 Microsoft Build 2022 上,微软发布了 Microsoft 智能数据平台,开发者可以通过低代码连接 Microsoft 智能数据平台的上的数据场景 ,低代码/零代码时代不是取代开发人员 ,而是让通过低代码的方式和 Dynamics 365 业务系统一起创建针对混合办公的协作应用。

郝冠军,.NET 与 Visual Studio 的最新更新

来自产品经理和一线开发人员的一手信息。长年奋战在一线的开发者。目前关注于前端和微服务领域。Angular 技术热爱者,《ASP.NET 本质论》作者。

2.2 相关照片

霸姐,微软MVP大中华区项目负责人。

康康,微软MVP项目助理。

感觉线上的分享还是没有线下分享体验好,似乎少一些沟通的氛围。最后,整个分享结束,感谢组织者刘力科,感谢霸姐支持也都辛苦啦。

转载请注明出处:
http://blog.fens.me/meeting-ms-build-20220618

打赏作者