傳染病的數學模型是數學建模中的典型問題,常見的傳染病模型有 SI、SIR、SIRS、SEIR 模型。html
SIS 模型型將人羣分爲 S 類和 I 類,考慮患病者能夠治癒而變成易感者,但不考慮免疫期。python
本文詳細給出了 SIS 模型的建模、例程、運行結果和模型分析,讓小白都能懂。算法
『Python小白的數學建模課 @ Youcans』 帶你從數模小白成爲國賽達人。編程
Python小白的數學建模課-09.微分方程模型
Python小白的數學建模課-B2.新冠疫情 SI模型
Python小白的數學建模課-B3.新冠疫情 SIS模型
Python小白的數學建模課-B4.新冠疫情 SIR模型
Python小白的數學建模課-B5.新冠疫情 SEIR模型
Python小白的數學建模課-B6.改進 SEIR疫情模型數組
傳染病動力學是對傳染病進行定量研究的重要方法。它依據種羣繁衍遷移的特性、傳染病在種羣內產生及傳播的機制、醫療與防控條件等外部因素,創建能夠描述傳染病動力學行爲的數學模型,經過對模型進行定性、定量分析和數值計算,模擬傳染病的傳播過程,預測傳染病的發展趨勢,研究防控策略的做用。函數
SI 模型把人羣分爲易感者(S類)和患病者(I類)兩類,易感者(S類)與患病者(I類)有效接觸即被感染,變爲患病者,無潛伏期、無治癒狀況、無免疫力。工具
SI 模型適用於只有易感者和患病者兩類人羣,且沒法治癒的疾病。spa
按照 SI 模型,最終全部人都會被傳染而變成病人,這是由於模型中沒有考慮病人能夠治癒。所以只能是健康人患病,而患病者不能恢復健康(甚至也不會死亡,而是不斷傳播疫情),因此終將所有被傳染。code
SIS 模型將人羣分爲 S 類和 I 類,考慮患病者(I 類)能夠治癒而變成易感者(S 類),但不考慮免疫期,所以患病者(I 類)治癒變成易感者之後還能夠被感染而變成患病者。orm
SIS 模型適用於只有易感者和患病者兩類人羣,能夠治癒,但會反覆發做的疾病,例如腦炎、細菌性痢疾等治癒後也不具備免疫力的傳染病。
SIS 模型假設:
須要說明的是,不考慮生死或人口流動,一般是因爲考慮一個封閉環境並且假定疫情隨時間的變化比生死、遷移隨時間的變化顯著得多, 所以後者能夠忽略不計。
SIS 模型的微分方程:
由
得:
由日治癒率 \(\mu\) 可知平均治癒天數爲 \(1/\mu\),也稱平均傳染期。定義 \(\sigma = \lambda / \mu\),其含義是每一個病人在傳染期內所傳染的平均人數,稱爲傳染期接觸數。例如,平均傳染期 \(1/\mu = 5\),日接觸率 \(\lambda = 2\)(天天傳染 2人),則傳染期接觸數 \(\sigma = 10\)。
SIS 模型的解析解爲:
注意:網上有些博文中解析解的公式誤寫成 \(exp((\lambda-\mu)t)\) ,漏掉了一個負號。
SIS 模型是常微分方程初值問題,可使用 Scipy 工具包的 scipy.integrate.odeint() 函數求數值解。
scipy.integrate.odeint(func, y0, t, args=())
**scipy.integrate.odeint() **是求解微分方程的具體方法,經過數值積分來求解常微分方程組。
odeint() 的主要參數:
odeint() 的返回值:
odeint() 的編程步驟:
# 1. SIS 模型,常微分方程,解析解與數值解的比較 from scipy.integrate import odeint # 導入 scipy.integrate 模塊 import numpy as np # 導入 numpy包 import matplotlib.pyplot as plt # 導入 matplotlib包 def dy_dt(y, t, lamda, mu): # SIS 模型,導數函數 dy_dt = lamda*y*(1-y) - mu*y # di/dt = lamda*i*(1-i)-mu*i return dy_dt # 設置模型參數 number = 1e5 # 總人數 lamda = 1.2 # 日接觸率, 患病者天天有效接觸的易感者的平均人數 sigma = 2.5 # 傳染期接觸數 mu = lamda/sigma # 日治癒率, 天天被治癒的患病者人數佔患病者總數的比例 fsig = 1-1/sigma y0 = i0 = 1e-5 # 患病者比例的初值 tEnd = 50 # 預測日期長度 t = np.arange(0.0,tEnd,1) # (start,stop,step) print("lamda={}\tmu={}\tsigma={}\t(1-1/sig)={}".format(lamda,mu,sigma,fsig)) # 解析解 if lamda == mu: yAnaly = 1.0/(lamda*t +1.0/i0) else: yAnaly= 1.0/((lamda/(lamda-mu)) + ((1/i0)-(lamda/(lamda-mu))) * np.exp(-(lamda-mu)*t)) # odeint 數值解,求解微分方程初值問題 ySI = odeint(dy_dt, y0, t, args=(lamda,0)) # SI 模型 ySIS = odeint(dy_dt, y0, t, args=(lamda,mu)) # SIS 模型 # 繪圖 plt.plot(t, yAnaly, '-ob', label='analytic') plt.plot(t, ySIS, ':.r', label='ySIS') plt.plot(t, ySI, '-g', label='ySI') plt.title("Comparison between analytic and numerical solutions") plt.axhline(y=fsig,ls="--",c='c') # 添加水平直線 plt.legend(loc='best') # youcans plt.axis([0, 50, -0.1, 1.1]) plt.show()
本圖爲例程 2.2 的運行結果,圖中對解析解(藍色)與使用 odeint() 獲得的數值解(紅色)進行比較。在該例中,沒法觀察到解析解與數值解的差別,代表數值解的偏差很小。
本圖也比較了對相同日接觸率和患病者初值下 SI模型與 SIS模型進行了比較。SI 模型更早進入爆發期,最終收斂到 100%;SIS 模型下進入爆發期較晚,患病者的比例最終收斂到某個常數(與模型參數有關)。
考察 SI 模型與 SIS模型的關係,顯然 SI 模型是 SIS 模型在 \(\mu = 0\) 時的特殊狀況。
對於 SIS 模型,須要考慮日接觸率 \(\lambda\) 與日治癒率 \(\mu\) 的關係、患病者比例的初值 \(i_0\) 的影響,總人數 N 沒有影響。
直觀地考慮,若是天天治癒的人數高於感染的人數,則疫情逐漸好轉,不然疫情逐漸嚴重。所以日接觸率 \(\lambda\) 與日治癒率 \(\mu\) 的關係很是關鍵,這就是傳染期接觸數 \(\sigma = \lambda / \mu\) 的意義。
當 \(\sigma<1\) 時,傳染期接觸數小於 1,日接觸率小於日治癒率,患病率單調降低,最終清零,與患病率初值無關。 \(\sigma\) 越小,疫情清零速度越快; \(\sigma\) 越接近於 1,疫情清零越慢,但最終仍將清零。
分析其實際意義,傳染期接觸數小於 1,代表在傳染期內通過接觸而使易感者變成患病者的數量,小於在傳染期內治癒的患病者的數量,所以患病者數量、比例都會逐漸下降,因此最終能夠清零,稱爲無病平衡點。
當 \(\sigma=1\) 時,不論患病率初值如何,患病率也是單調降低,最終趨近於 0。雖然在數學上患病率只能趨近於 0 而不等於 0,但考慮到總人數 N 是有限的,而患病者和易感者人數須要取整,所以 \(\sigma=1\) 時最終也會清零。
當 \(\sigma>1\) 時,傳染期接觸數大於 1,日接觸率大於日治癒率,患病率的升降有兩種狀況:
這代表,當 \(\sigma>1\) 時疫情終將穩定但不會清零,而是長期保持必定的患病率,稱爲地方病平衡點。
當 \(\sigma=1\) 時,不論患病率初值如何,患病率都單調降低並最終趨於 0。
患病率的一階導數 \(di/dt\) 的變化曲線,代表不論傳染期接觸數和初值如何,患病率的變化率都將收斂到 0,所以疫情終將穩定。當 \(\sigma<1\) 時, \(di/dt\) 始終是負值,單調上升趨近於 0; 當 \(\sigma>1\) 時, \(di/dt\) 始終是正值,先上升達到峯值後再逐漸減少趨近於 0。
本圖爲患病率 \(i(t)\) 與一階導數 \(di/dt\) 在不一樣傳染期接觸數下的關係曲線(相空間圖)。當 \(\sigma\leq 1\) 時,曲線收斂到原點 \((0,0)\),即存在無病平衡點; 當 \(\sigma>1\) 時,曲線收斂到 \((1-1/\sigma,0)\),即存在地方病平衡點。
# 4. SIS 模型,模型參數對 di/dt的影響 from scipy.integrate import odeint # 導入 scipy.integrate 模塊 import numpy as np # 導入 numpy包 import matplotlib.pyplot as plt # 導入 matplotlib包 def dy_dt(y, t, lamda, mu): # SIS 模型,導數函數 dy_dt = lamda*y*(1-y) - mu*y # di/dt = lamda*i*(1-i)-mu*i return dy_dt # 設置模型參數 number = 1e5 # 總人數 lamda = 1.2 # 日接觸率, 患病者天天有效接觸的易感者的平均人數 # sigma = np.array((0.1, 0.5, 0.8, 0.95, 1.0)) # 傳染期接觸數 sigma = np.array((0.5, 0.8, 1.0, 1.5, 2.0, 3.0)) # 傳染期接觸數 y0 = i0 = 0.05 # 患病者比例的初值 tEnd = 100 # 預測日期長度 t = np.arange(0.0,tEnd,0.1) # (start,stop,step) for p in sigma: ySIS = odeint(dy_dt, y0, t, args=(lamda,lamda/p)) # SIS 模型 yDeriv = lamda*ySIS*(1-ySIS) - ySIS*lamda/p # plt.plot(t, yDeriv, '-', label=r"$\sigma$ = {}".format(p)) plt.plot(ySIS, yDeriv, '-', label=r"$\sigma$ = {}".format(p)) #label='di/dt~i' print("lamda={}\tmu={}\tsigma={}\t(1-1/sig)={}".format(lamda,lamda/p,p,(1-1/p))) # 繪圖 plt.axhline(y=0,ls="--",c='c') # 添加水平直線 plt.title("i(t)~di/dt in SIS model") # youcans-xupt plt.legend(loc='best') plt.show()
SIS 模型代表:
須要指出的是,本文討論的 SIS模型是把考察地區視爲一個疫情均勻分佈的總體進行研究。實際上,在考察區域的疫情分佈必然是不均衡的,可能在局部區域發生疫情爆發致使該區域患病人數激增,是否會影響 SIS 模型的演化過程和穩定性呢?相關研究代表,擴散速度的不一樣可能致使種羣空間分佈的差別,在低風險區域將達到無病平衡點,在高風險區域仍將達到地方病平衡點。
【本節完】
版權聲明:
歡迎關注 『Python小白的數學建模課 @ Youcans』 原創做品
原創做品,轉載必須標註原文連接:(https://www.cnblogs.com/youcans/p/14968504.html)。
Copyright 2021 Youcans, XUPT
Crated:2021-06-09
歡迎關注 『Python小白的數學建模課 @ Youcans』,每週更新數模筆記
Python小白的數學建模課-01.新手必讀
Python小白的數學建模課-02.數據導入
Python小白的數學建模課-03.線性規劃
Python小白的數學建模課-04.整數規劃
Python小白的數學建模課-05.0-1規劃
Python小白的數學建模課-06.固定費用問題
Python小白的數學建模課-07.選址問題
Python小白的數學建模課-09.微分方程模型
Python小白的數學建模課-B2.新冠疫情 SI模型
Python小白的數學建模課-B3.新冠疫情 SIS模型
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計迴歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法