SIR模型和Python实现

article/2025/9/26 12:54:18

一、SIR模型介绍

SIR模型时传染病中最基础最核心的模型,研究的是某个封闭地区的疫情传播规律。

SIR模型的动力学关系如下图:

健康人数S的变化与 健康人数S和正感人数I的乘积(代表健康人数和正感人数的接触)成正比,其中α代表交叉感染率

移出人数的变化与正感人数的数量成正比,其中β代表回复率。

基于上面的是自,SIR模型可以表示成一个常微分方程组如下图:

 当s(t)=β/α时就是病毒最严重的时候;

S^{-1}表示S的反函数,代表S越大,t越小,越早结束疫情

封城就是为了较低交叉感染率α,并提高治愈率β

以上就是关于SIR模型的简单介绍,我是从B站上学习到的,更多可以看遇见数学的视频:数学建模系列之SIR传染病模型(1)——模型的建立与演绎_哔哩哔哩_bilibili

接下来我将用Python实现SIR模型在某真实社交网络(基于networkx)上的传播过程模拟。

代码参考了这篇文章:人群接触网络中的 SIR 疫情模拟 - 云+社区 - 腾讯云

二、接触网络中的SIR模型

在 SIR 模型中,假设人之间是随机接触的。如果人之间的接触关系不是随机的,而是形成了一个接触网络。那么在这个网络中,每个人接触到感染者的概率不再相等,而与他在网络中的位置相关。

 比如对于这张图,c接触到感染者的概率远远大于h,因此其染病的概率也会更高。

因此我们可以更新SIR模型的规则:(这也是参考了上面腾讯云的文章)

与传统 SIR 模型类似,有两个重要的参数:感染率 α 和恢复率 β。我们需要给每个节点引入一个状态,取值为 S,I,R 中的一种。每一个时间步中,需要动态对每一个节点的状态进行更新。更新规则如下:

  • 如果当前节点是恢复者,则下一步,节点状态依然是恢复者。​

  • 如果当前节点是感染者,则下一步,β的概率转化为恢复者。1 - β的概率依然是感染者。

  • 如果当前节点是易感者(健康者),则需要计算其邻居节点中感染者的数量,假设其有 k 个邻居为感染者。则该节点下一步转化为感染者的概率为 1-(1-\alpha)^{k},否则继续保持易感者状态。

         下面这个概率的含义就是对于每个邻居感染者,易感者有1-α的概率保持健康,故有(1-\alpha)^{k}概率保持健康

三、Python实现SIR模型

1.导入数据

这里我导入的是一个节点表和一个边表,边表用来构建网络图,节点表用来选择初始感染者:

import pandas
import csv
import randomnode_df = pandas.read_csv('E:/data/节点.csv')
all_nodes_list = node_df.values.tolist()  #获取文件中所有节点edge = []   #获取所有边
with open('E:/data/边.csv','r',encoding='utf-8-sig') as f: data = f.readlines()  for line in data: line = list(line.replace('\r','').replace('\n','').replace('\t','').split(','))single_edge = tuple([line[1],line[4]])edge.append(single_edge)

2.绘制初始网络

所有节点都是健康的

import networkx as nx
ba = nx.Graph()
ba.add_edges_from(edge)
for node in ba.nodes():ba.nodes[node]["state"] = "S"

3. 更新网络节点状态

先考虑单个节点的更新

我们使用一个简单的函数来实现一个节点的状态的更新。

首先,如果一个节点是恢复者,那么下一步还是恢复者,其节点状态保持不变。 如果一个节点是感染者,那么其恢复的概率是 β。用程序实现的方法为,先均匀生成一个0到1的随机数 p,如果 p < β,则节点恢复,否则节点依然处于感染状态。

如一个节点是易感者,先要去其邻居节点中看看一共有多少个邻居是感染者,有 k 个邻居是感染者,那么当前节点被感染的概率是 1 - (1 - α)k。我们生成一个0到1的随机数 p,如果 p < 1 - (1 - α)k,则节点被感染,否则不被感染。

import random# 根据 SIR 模型,更新单一节点的状态
def updateNodeState(G,node, alpha, beta):if G.nodes[node]["state"] == "I": #感染者p = random.random() # 生成一个0到1的随机数if p < beta:   # gamma的概率恢复G.nodes[node]["state"] = "R" #将节点状态设置成“R”elif G.nodes[node]["state"] == "S": #易感者p = random.random() # 生成一个0到1的随机数k = 0  # 计算邻居中的感染者数量for neibor in G.adj[node]: # 查看所有邻居状态,遍历邻居用 G.adj[node]if G.nodes[neibor]["state"] == "I": #如果这个邻居是感染者,则k加1k = k + 1if p < 1 - (1 - alpha)**k:  # 易感者被感染G.nodes[node]["state"] = "I" 

再对网络中所有节点进行更新

def updateNetworkState(G, alpha, beta):for node in G: #遍历图中节点,每一个节点状态进行更新updateNodeState(G,node, alpha, beta)

用函数countSIR统计三类人群数量

# 计算三类人群的数量
def countSIR(G):S = 0;I = 0for node in G:if G.nodes[node]["state"] == "S":S = S + 1elif G.nodes[node]["state"] == "I":I = I + 1return S,I, len(G.nodes) - S - I    

所有函数都准备好后,我们进行网络和参数初始化设置

#随机选取一个节点为初始感染者  
ba.nodes["123549878"]["state"] = "I" days = 50 #设置模拟的天数
alpha = 0.0003 #感染率
beta = 0.10 #恢复率#设置不同人群的显示颜色,易感者为橘色,感染者为红色,恢复者为绿色
color_dict = {"S":"orange","I":"red","R":"green"} 

在图中开始SIR模型的模拟,设置模拟天数,开始执行模拟过程

# 模拟天数为days,更新节点状态
import matplotlib.pyplot as plt
#fig,ax = plt.subplots(111)
%matplotlib inline
import time
SIR_list = []
for t in range(0,days):updateNetworkState(ba,alpha,beta) #对网络状态进行模拟更新SIR_list.append(list(countSIR(ba))) #计算更新后三种节点的数量

模型结果可视化

df = pd.DataFrame(SIR_list,columns=["S","I","R"])
df.plot(figsize=(9,6),color=[color_dict.get(x) for x in df.columns])

我的数据得到的结果如下

 我的网络结果中分为几个隔离比较大的社区,所以有一部分人群始终没有被感染。

4.探究不同节点作为初始感染者传播网络的区别

比如我想知道在一个网络中的谣言传播情况,想看看随机选一个节点,通过这个节点看看最后有多少个人会接触到这个谣言(其实就是传播停止时的恢复者)

import matplotlib.pyplot as plt
import time
import pandas as pd
#fig,ax = plt.subplots(111)
%matplotlib inline
import time
# 获得所有节点的属性
def get_last_node_state(all_nodes_list,G):SIR_result = []for item in all_nodes_list:node_attri = []node_attri.extend(item)try:for node in G.nodes():G.nodes[node]["state"] = "S"   #将网络中所有节点设为健康者G.nodes[str(item[0])]["state"] = "I"    #将某一节点设为感染者for t in range(0,days):updateNetworkState(G,beta,gamma)  #对网络状态进行模拟更新node_result = pd.DataFrame([i[1] for i in G.nodes(data=True)], index=[i[0] for i in G.nodes(data=True)])state_count = node_result.groupby('state')['label'].count().to_dict() #按感染情况分组R_count = state_count['R']   #计算恢复者数量node_attri.append(R_count)SIR_result.append(node_attri)except Exception as e:print(e)              return SIR_result   #返回结果形式为[节点id,节点接触到的人数(恢复者人数)]#执行函数
SIR_result = get_last_node_state(all_nodes_list,ba)


http://chatgpt.dhexx.cn/article/dYEUqagr.shtml

相关文章

SIR传染病模型(微分方程系列1)

一&#xff1a;基本参数 SIR模型是常见的一种描述传染病传播的数学模型&#xff0c;其基本假设是将人群分为以下三类&#xff1a; S:(Susceptible):易感人群&#xff0c;指未得病者&#xff0c;但缺乏免疫能力&#xff0c;与感病者接触后容易受到感染。 I:(Infective):患病人…

【整站下载器】小飞兔整站下载V5.0

小飞兔整站下载是一款只需输入一个网址就能下载一个网站的软件&#xff0c;它可以从Internet的任何地方抓回你想要的任何文件&#xff0c;整站下载主要是用来快速搭建网站、深层分析网站、网站克隆等。

【小飞兔整站下载】整站下载器哪个好用_整站下载工具哪个好

小飞兔整站下载是一款可以下载整个网站内容的软件&#xff0c;你只要输入一个网址&#xff0c;软件能自动分析网站链接、图片、样式、文件等资源&#xff0c;并能将整个网站下载到本地&#xff0c;能在本地正常跳转、浏览。 官网&#xff1a;https://xft.fzxgj.top/ 直接上图…

快速获取一个网站的所有资源,图片,html,css,js等等

今天介绍一款软件,可以快速获取一个网站的所有资源,图片,html,css,js… 以获取某车官网为例 我来展示一下这个软件的功能. 1、输入网站地址 2、下载文件 到此,爬取网站就结束了,有些网站的资源使用的是国外的js,css,速度会有些差异,但效果都是一样的.爬取下来就能使用.放…

小飞升值记——(5)

目录 一&#xff1a;学习痕迹 二&#xff1a;学习结语 一&#xff1a;学习痕迹 二&#xff1a;学习结语 1.注意断句 2.注意refill的读音&#xff0c;重音在后面

根据url一键爬取前端页面资源文件,恐怖如斯-----小飞兔

前言 有一天你在网上发现一个很好看的前端页面,你想要弄下来在自己的项目上使用,于是你去查看源码,复制html代码和资源文件,过程非常的麻烦,而且很可能缺胳膊少腿,这里我给大家推荐一款可以一键爬取前端页面资源文件的工具给大家,希望对大家有所帮助. 下载 https://download.cs…

小飞兔整站下载如何设置特殊标签?

小飞兔整站下载如何设置特殊标签&#xff1f; 为什么提供自定义标签的功能&#xff1f;如何设置自定义标签&#xff1f; 为什么提供自定义标签的功能&#xff1f; 随着html5网站的快速发展&#xff0c;很多网站做了格式各样的特殊标签&#xff0c;而我们需要匹配特殊标签的资源…

c语言兔子繁殖问题pia,上海虹口幼升小转学报名,在喂养幼兔的时候我们要注意。...

上海虹口幼升小转学报名&#xff0c;在喂养幼兔的时候我们要注意&#xff0c;在喂养幼兔的时候我们要注意&#xff0c;不能直接用自来水为给幼兔喝&#xff0c;因为幼鸡初期的消化食物是很慢的&#xff0c;做好室内清洁卫生并对猫咪进行隔离幼猫在有猫癣的时候&#xff0c;这样…

最新版本 Stable Diffusion 开源 AI 绘画工具之汉化篇

✨ 目录 &#x1f388; 汉化预览&#x1f388; 下载插件方法一&#x1f388; 下载插件方法二&#x1f388; 下载插件方法三&#x1f388; 简单汉化&#x1f388; 双语汉化 &#x1f388; 汉化预览 在上一篇文章中&#xff0c;我们安装好了 Stable Diffusion 开源 AI 绘画工具但…

StyleGAN 调整面部表情,让虚拟人脸更生动

✨ 目录 🎈 人脸表情🎈 调整步骤🎈 调整结果🎈 人脸表情 通过上一篇文章 StyleGAN 生成的人脸:https://tinygeeker.blog.csdn.net/article/details/129667295人脸图片都是比较中规中矩的,如果能够给人脸增加一些表情的话,会让人脸显得更加的自然和逼真那么调整人脸的…

springMVC小bug webapp/.html访问不到

我们要访问 test.html 启动tomcat 404 web服务器中也有一个web。xml 父servlet&#xff1a;是给所有web.xml准备服务静态资源的 但是子类也是 一个/ 这个/会覆盖父xml 父类有jsp不会拦截&#xff0c;子类没有重写所有会访问.jsp 两个解决方法&#xff1a;方法1&#…

运用帝国CMS建站仿站的简单教程(初学者进)

帝国CMS是一款管理网站的软件系统&#xff0c;主要就是将网站生成模板&#xff08;核心操作为创建变量和模板并调用&#xff09;并通过该系统在网站上发布新信息&#xff0c;它具有许多的功能&#xff0c;细节方面也有很多&#xff0c;这里就不一一展示了&#xff0c;主要就是简…

计算机毕业设计制作模仿网站的期末作业通过神器——各种扒站方法(网站,软件)

官网链接&#xff1a;点我进入在线扒站 扒站完尽快下载&#xff0c;详情官网查看。 以下是一些需要下载的扒站工具 名字&#xff1a;teleport ultra 下载&#xff1a;Teleport 官网 名字&#xff1a;仿站小工具 小飞兔 下载&#xff1a;小飞兔官网 名字&#xff1a;Interne…

小飞兔整站下载V16.5-站点克隆工具

简介&#xff1a; 小飞兔网站克隆神器&#xff0c;一键复制克隆网站、小白必备&#xff01; 有了这个东西&#xff0c;看到自己喜欢的网站直接复制下了&#xff0c;再用dw修改内容&#xff0c;省事多了。 网盘下载地址&#xff1a; https://zijieyunpan.cn/AtqSxg3OdJe 图片…

【参赛作品4】初窥openGauss 之参数自调优(X-Tuner)

TPC-H 是一个面向分析型业务(AP)的基准测试&#xff0c;它由一系列热点查询组成&#xff0c;这些热点查询都是高度复杂的&#xff0c;因此执行时间往往都比较长。 在本次实验测试中&#xff0c;将手动向数据库加载TPC-H数据&#xff0c;并保存在名为 tpch 的数据库中。默认TPC-…

亲测好用的油管音乐播放器:Tuner Mac版

Tuner for YouTube music Mac版是一款优质的youtube音乐播放器&#xff0c;Tuner支持快速搜索想要听的音乐&#xff0c;支持创建自定义播放列表、在线播放等功能&#xff0c;另外Tuner for YouTube music mac版还提供了画中画功能&#xff0c;你可以直接观看视频&#xff0c;还…

读论文---Clip微调---CLIP Itself is a Strong Fine-tuner

标题 摘要 Recent studies have shown that CLIP has achieved remarkable success in performing zero-shot inference while its fine-tuning performance is not satisfactory. In this paper, we identify that fine-tuning performance is significantly impacted by hyp…

Tuner工作原理详解

1、TV自动搜台原理:https://wenku.baidu.com/view/3b771f8b84868762caaed514 2、彩电自动搜台的原理与维修:http://tv.baoxiu.com/a/201001/170815.htm 3、TV Tuner搜台基础: https://wenku.baidu.com/view/bd0cefd133d4b14e85246882.html 4、TV+Tuner+Application+on+DVD+t…

Pytorch-Lightning--Tuner

Pytorch-Lightning–Tuner lr_find() 参数详解 参数名称含义默认值modelLightningModule实例train_dataloaders训练数据加载器Noneval_dataloaders验证数据加载器NonedatamoduleLightningDataModule实例Nonemin_lr学习率最小值1e-08max_lr学习率最大值1num_training测试学习…

MATLAB/simulink中PID Tuner工具箱使用方法(针对Plant cannot be linearized问题)

问题描述 在PID tuner工具箱对PID参数自动调节时&#xff0c;由于matlab无法将控制对象线性化&#xff0c;出现"Plant cannot be linearized. Use the Plant menu to create or select a new plant."问题。 操作步骤 首先选择Identify New Plant 按钮 然后选择Simu…