Domanda:
L'adattamento del modello SIR con i dati 2019-nCoV non converge
vonjd
2020-01-28 13:21:33 UTC
view on stackexchange narkive permalink

Sto cercando di calcolare il numero di riproduzione di base $ R_0 $ del nuovo virus 2019-nCoV adattando un modello SIR ai dati correnti. Il mio codice è basato su https://arxiv.org/pdf/1605.01931.pdf, p. 11ff:

  libreria (deSolve)
libreria (RColorBrewer)

#https: //en.wikipedia.org/wiki/Timeline_of_the_2019%E2%80%9320_Wuhan_coronavirus_outbreak#Cases_Chronology_in_Mainland_China
<- c infetto (45, 62, 121, 198, 291, 440, 571, 830, 1287, 1975, 2744, 4515)
giorno <- 0: (length (Infected) -1)
N <- 1400000000 #pop della Cina
init <- c (S = N-1, I = 1, R = 0)
trama (giorno, infetto)
 

enter image description here

  SIR <- funzione (ora, stato, parametri) {
  par <- as.list (c (state, parameters))
  con (par, {dS <- -beta * S * I
  dI <- beta * S * I - gamma * I
  dR <- gamma * I
  elenco (c (dS, dI, dR))
  })
}

RSS.SIR <- function (parameters) {
  nomi (parametri) <- c ("beta", "gamma")
  out <- ode (y = init, times = day, func = SIR, parms = parameters)
  fit <- out [, 3]
  RSS <- sum ((Infected - fit) ^ 2)
  ritorno (RSS)
}

inferiore = c (0, 0)
superiore = c (0,1, 0,5)

set.seed (12)
Opt <- optim (c (0.001, 0.4), RSS.SIR, method = "L-BFGS-B", lower = lower, upper = upper)
Opz $ messaggio
## [1] "NEW_X"

Opt_par <- Opt $ par
nomi (Opt_par) <- c ("beta", "gamma")
Opt_par
## beta gamma
## 0.0000000 0.4438188

t <- seq (0, 100, length = 100)
fit <- data.frame (ode (y = init, times = t, func = SIR, parms = Opt_par))
col <- brewer.pal (4, "GnBu") [- 1]
matplot (fit $ time, fit [, 2: 4], type = "l", xlab = "Day", ylab = "Number of subject", lwd = 2, lty = 1, col = col)
punti (giorno, infetto)
legenda ("right", c ("Susceptibles", "Infecteds", "Recovereds"), lty = 1, lwd = 2, col = col, inset = 0.05)
 

enter image description here

  R0 <- N * Opt_par [1] / Opt_par [2]
nomi (R0) <- "R0"
R0
## R0
## 0
 

Ho anche provato ad adattarmi con GA (come nel documento), anche senza alcun risultato.

My question
Sto commettendo errori o non ci sono ancora abbastanza dati?O il modello SIR è troppo semplice?Apprezzerei suggerimenti su come modificare il codice in modo da ricavarne alcuni numeri ragionevoli.

Addendum
Ho scritto un post sul blog basato sul modello finale e sui dati attuali:
Epidemiologia: quanto è contagioso il Novel Coronavirus (2019-nCoV)?

Potresti provare un modello SEIR (Susceptible-Exposed-Infectious-Recovered), perché il virus nCov ha un periodo di incubazione significativo.
@dain: Grazie ... come è stato migliorato il modello SIR per diventare un modello SEIR?
@vonjd nel tuo blog scrivi che il tuo adattamento risulta in $ R_0 \ circa 2 $.Nota che questo è solo perché la funzione `optim` termina troppo presto.Di seguito sto mostrando un grafico con una soluzione $ R_0 \ circa 1.005 $, che si adatta meglio (ho anche aggiunto il codice per ottenerlo utilizzando il solutore itterativo, che è il più robusto).
Cinque risposte:
Sextus Empiricus
2020-01-28 22:29:18 UTC
view on stackexchange narkive permalink

Ci sono diversi punti che puoi migliorare nel codice

Condizioni al contorno errate

Il tuo modello è fissato su I = 1 per il tempo zero. Puoi modificare questo punto nel valore osservato o aggiungere un parametro nel modello che sposta l'ora di conseguenza.

  init <- c (S = N-1, I = 1, R = 0)

# dovrebbe essere

init <- c (S = N-Infected [1], I = Infected [1], R = 0)
 

Scale di parametri disuguali

Come altre persone hanno notato l'equazione

$$ I '= \ beta \ cdot S \ cdot I - \ gamma \ cdot I $$

ha un valore molto grande per $ S \ cdot I $ questo fa sì che il valore del parametro $ \ beta $ molto piccolo e l'algoritmo che controlla se le dimensioni dei passaggi nelle iterazioni raggiungono un certo punto non varierà i passaggi in $ \ beta $ e $ \ gamma $ allo stesso modo (le modifiche in $ \ beta $ avranno un effetto molto maggiore rispetto alle modifiche in $ \ gamma $ ).

Puoi cambiare la scala nella chiamata alla funzione optim per correggere queste differenze di dimensione (e controllare la tela di iuta ti permette di vedere se funziona un po '). Ciò viene fatto utilizzando un parametro di controllo. Inoltre potresti voler risolvere la funzione in fasi separate rendendo l'ottimizzazione dei due parametri indipendente l'una dall'altra (vedi di più qui: Come gestire le stime instabili durante l'adattamento della curva? questo viene fatto anche in il codice qui sotto, e il risultato è una convergenza molto migliore; sebbene si raggiungano comunque i limiti dei limiti inferiore e superiore)

  Opt <- optim (c (2 * coefficients (mod) [2] / N, coefficients (mod) [2]), RSS.SIR, method = "L-BFGS-B", inferiore = inferiore, superiore = superiore,
         hessian = TRUE, control = list (parscale = c (1 / N, 1), factr = 1))
 

più intuitivo potrebbe essere scalare il parametro nella funzione (nota il termine beta / N al posto di beta )

  SIR <- funzione (ora, stato, parametri) {
  par <- as.list (c (stato, parametri))
  con (par, {dS <- -beta / N * S * I
  dI <- beta / N * S * I - gamma * I
  dR <- gamma * I
  elenco (c (dS, dI, dR))
  })
}
 

Condizione iniziale

Perché il valore di $ S $ è all'inizio più o meno costante (ovvero $ S \ approx N $ ) l'espressione per gli infetti all'inizio può essere risolta come un'unica equazione:

$$ I '\ approx (\ beta \ cdot N - \ gamma) \ cdot I $$

Quindi puoi trovare una condizione iniziale utilizzando un adattamento esponenziale iniziale:

  # ottiene una buona condizione di partenza
mod <- nls (Infected ~ a * exp (b * day),
           start = list (a = Infected [1],
                        b = log (infetto [2] / infetto [1])))
 

Instabile, correlazione tra $ \ beta $ e $ \ gamma $

C'è un po 'di ambiguità su come scegliere $ \ beta $ e $ \ gamma $ per la condizione di partenza.

Ciò renderà anche il risultato della tua analisi non così stabile. L'errore nei singoli parametri $ \ beta $ e $ \ gamma $ sarà molto grande perché molte coppie di $ \ beta $ e $ \ gamma $ fornirà un RSS più o meno altrettanto basso.

Il grafico seguente è per la soluzione $ \ beta = 0.8310849; \ gamma = 0,4137507 $

example solution

Tuttavia, il valore Opt_par modificato $ \ beta = 0.8310849-0.2; \ gamma = 0.4137507-0.2 $ funziona altrettanto bene:

example variation


Utilizzo di una parametrizzazione diversa

La funzione optim ti permette di leggere l'iuta

  > Opt <- optim (optimsstart, RSS.SIR, method = "L-BFGS-B", lower = lower, upper = upper,
+ iuta = VERO)
> Opt $ hessian
            b
b 7371274104-7371294772
  -7371294772 7371315619
 

La hessiana può essere correlata alla varianza dei parametri ( In R, dato un output da optim con una matrice hessiana, come calcolare gli intervalli di confidenza dei parametri usando la matrice hessiana?). Ma nota che per questo scopo hai bisogno dell'Hessian della probabilità di log che non è lo stesso dell'RSS (differisce di un fattore, vedi il codice sotto).

Sulla base di ciò puoi vedere che la stima della varianza campionaria dei parametri è molto ampia (il che significa che i tuoi risultati / stime non sono molto accurati). Ma nota anche che l'errore è molto correlato. Ciò significa che è possibile modificare i parametri in modo tale che il risultato non sia molto correlato. Alcuni esempi di parametrizzazione potrebbero essere:

$$ \ begin {array} {} c & = & \ beta - \ gamma \\ R_0 & = & \ frac {\ beta} {\ gamma} \ end {array} $$

tale che le vecchie equazioni (si noti che viene utilizzato un ridimensionamento di 1 / N):

$$ \ begin {array} {rccl} S ^ \ prime & = & - \ beta \ frac {S} {N} & I \\ I ^ \ prime & = & (\ beta \ frac {S} {N} - \ gamma) & I \\ R ^ \ prime & = & \ gamma &I \ end {array} $$

diventa

$$ \ begin {array} {rccl} S ^ \ prime & = & -c \ frac {R_0} {R_0-1} \ frac {S} {N} & I& \\ I ^ \ prime & = & c \ frac {(S / N) R_0 - 1} {R_0-1} &I& \ underbrace {\ approx c I} _ {\ text {for $ t = 0 $ quando $ S / N \ circa 1 $}} \\ R ^ \ prime & = & c \ frac {1} {R_0-1} & I& \ end {array} $$

che è particolarmente interessante poiché ottieni questo $ I ^ \ prime = cI $ approssimativo per l'inizio. TQuesto ti farà vedere che stai sostanzialmente stimando la prima parte che è approssimativamente una crescita esponenziale. Sarai in grado di determinare con estrema precisione il parametro di crescita, $ c = \ beta - \ gamma $ . Tuttavia, $ \ beta $ e $ \ gamma $ o $ R_0 $ , non può essere facilmente determinato.

Nel codice seguente viene eseguita una simulazione con lo stesso valore $ c = \ beta - \ gamma $ ma con valori diversi per $ R_0 = \ beta / \ gamma $ . Puoi vedere che i dati non sono in grado di permetterci di differenziare quale scenario diverso (quale diverso $ R_0 $ ) abbiamo a che fare (e avremmo bisogno di più informazioni, ad es le posizioni di ogni individuo infetto e cercando di vedere come si è diffusa l'infezione).

È interessante che diversi articoli fingano già di avere stime ragionevoli di $ R_0 $ . Ad esempio questo preprint Novel coronavirus 2019-nCoV: stima anticipata dei parametri epidemiologici e previsioni epidemiche ( https://doi.org/10.1101/2020.01.23.20018549)

fitting with different R_0


Un po 'di codice:

  ####
####
####

libreria (deSolve)
libreria (RColorBrewer)

#https: //en.wikipedia.org/wiki/Timeline_of_the_2019%E2%80%9320_Wuhan_coronavirus_outbreak#Cases_Chronology_in_Mainland_China
< infetto- c (45, 62, 121, 198, 291, 440, 571, 830, 1287, 1975, 2744, 4515)
giorno <- 0: (length (Infected) -1)
N <- 1400000000 #pop della Cina

### modifica 1: usa una diversa condizione al contorno
### init <- c (S = N-1, I = 1, R = 0)
init <- c (S = N-Infected [1], I = Infected [1], R = 0)
trama (giorno, infetto)

SIR <- funzione (ora, stato, parametri) {
  par <- as.list (c (stato, parametri))
  #### modifica 2; utilizzare variabili ugualmente scalate
  con (par, {dS <- -beta * (S / N) * I
  dI <- beta * (S / N) * I - gamma * I
  dR <- gamma * I
  elenco (c (dS, dI, dR))
  })
}

SIR2 <- funzione (ora, stato, parametri) {
  par <- as.list (c (stato, parametri))
  ####
  #### utilizzare come variabile di modifica delle variabili
  #### const = (beta-gamma)
  #### delta = gamma / beta
  #### R0 = beta / gamma > 1
  ####
  #### beta-gamma = beta * (1-delta)
  #### beta-gamma = beta * (1-1 / R0)
  #### gamma = beta / R0
  con (par, {
    beta <- const / (1-1 / R0)
    gamma <- const / (R0-1)
    dS <- - (beta * (S / N)) * I
    dI <- (beta * (S / N) -gamma) * I
    dR <- (gamma) * I
    elenco (c (dS, dI, dR))
  })
}

RSS.SIR2 <- funzione (parametri) {
  nomi (parametri) <- c ("const", "R0")
  out <- ode (y = init, times = day, func = SIR2, parms = parameters)
  adatta <- out [, 3]
  RSS <- sum ((Infected - fit) ^ 2)
  ritorno (RSS)
}

### tracciare valori diversi R0

# usa il modello esponenziale ordinario per determinare const = beta - gamma
const <- coef (mod) [2]




RSS.SIR <- funzione (parametri) {
  nomi (parametri) <- c ("beta", "gamma")
  out <- ode (y = init, times = day, func = SIR, parms = parameters)
  adatta <- out [, 3]
  RSS <- sum ((Infected - fit) ^ 2)
  ritorno (RSS)
}

inferiore = c (0, 0)
superiore = c (1, 1) ### regola il limite perché scala 1 / N diversa

### modifica: ottieni una buona condizione di partenza
mod <- nls (Infected ~ a * exp (b * day),
           start = list (a = Infected [1],
                        b = log (infetto [2] / infetto [1])))
optimsstart <- c (2,1) * coef (mod) [2]

set.seed (12)
Opt <- optim (optimsstart, RSS.SIR, method = "L-BFGS-B", lower = lower, upper = upper,
             iuta = VERO)
Optare

### matrice di covarianza stimata dei coefficienti
### nota il grande errore, ma anche la forte correlazione (quasi 1)
## nota il ridimensionamento con stima di sigma perché dobbiamo usare l'Assia di loglikelihood
sigest <- sqrt (Opt  $ value / (length (Infected) -1))
risolvere (1 / (2 * sigest ^ 2) * Opt $  hessian)

####
#### utilizzando parametri alternativi
#### per questo usiamo la funzione SIR2
####

optimsstart <- c (coef (mod) [2], 5)
inferiore = c (0, 1)
upper = c (1, 10 ^ 3) ### regola il limite perché ora usiamo R0 che dovrebbe essere >1

set.seed (12)
Opt2 <- optim (optimsstart, RSS.SIR2, method = "L-BFGS-B", inferiore = inferiore, superiore = superiore,
              hessian = TRUE, control = list (maxit = 1000,
                                             parscale = c (10 ^ -3,1)))
Opt2

# ora la varianza stimata del primo parametro è piccola
# il 2 ° parametro è ancora con grande varianza
#
# quindi possiamo prevedere molto bene il beta-gamma
# questa beta - gamma è il coefficiente di crescita iniziale
# ma i valori individuali di beta e gamma non sono molto noti
#
# si noti inoltre che l'iuta non è al MLE poiché abbiamo raggiunto il limite inferiore
#
sigest <- sqrt (Opt2  $ value / (length (Infected) -1))
risolvere (1 / (2 * sigest ^ 2) * Opt2 $  hessian)

#### Possiamo anche stimare la varianza di
#### Stima Monte Carlo
##
## supponendo che i dati vengano distribuiti come media +/- q media
## con q tale che significa RSS = 52030
##
##
##


### Due funzioni RSS per eseguire l'ottimizzazione in modo annidato
RSS.SIRMC2 <- funzione (const, R0) {
  parametri <- c (const = const, R0 = R0)
  out <- ode (y = init, times = day, func = SIR2, parms = parameters)
adatta <- out [, 3]
  RSS <- sum ((Infected_MC - fit) ^ 2)
  ritorno (RSS)
}
RSS.SIRMC <- funzione (const) {
  ottimizzare (RSS.SIRMC2, inferiore = 1, superiore = 10 ^ 5, const = const) $ obiettivo
}

getOptim <- function () {
  opt1 <- ottimizza (RSS.SIRMC, inferiore = 0, superiore = 1)
  opt2 <- ottimizza (RSS.SIRMC2, inferiore = 1, superiore = 10 ^ 5, const = opt1  $ minimo)
  return (elenco (RSS = opt2 $  obiettivo, const = opt1  $ minimo, R0 = opt2 $  minimo))
}

# dati modellati che utilizziamo per generare ripetutamente dati con rumore
Opt_par <- Opt2  $ par
nomi (Opt_par) <- c ("const", "R0")
modInfected <- data.frame (ode (y = init, times = day, func = SIR2, parms = Opt_par)) $  I

# facendo il modello annidato per ottenere RSS
set.seed (1)
Infected_MC <- Infected
modnested <- getOptim ()

errrate <- modnested $ RSS / sum (infetto)


par <- c (0,0)
per (i in 1: 100) {
  Infected_MC <- rnorm (length (modInfected), modInfected, (modInfected * errrate) ^ 0.5)
  OptMC <- getOptim ()
  par <- rbind (par, c (OptMC  $ const, OptMC $  R0))
}
par <- par [-1,]

trama (par, xlab = "const", ylab = "R0", ylim = c (1,1))
titolo ("Simulazione Monte Carlo")
cov (par)


### conclusione: il parametro R0 non può essere stimato in modo affidabile

##### Fine della stima Monte Carlo


### tracciare valori diversi R0

# usa il modello esponenziale ordinario per determinare const = beta - gamma
const <- coef (mod) [2]
R0 <- 1.1

# grafico
grafico (-100, -100, xlim = c (0,80), ylim = c (1, N), log = "y",
     ylab = "infetto", xlab = "giorni", yaxt = "n")
asse (2, las = 2, at = 10 ^ c (0: 9),
     etichette = c (espressione (1),
              espressione (10 ^ 1),
              espressione (10 ^ 2),
              espressione (10 ^ 3),
              espressione (10 ^ 4),
              espressione (10 ^ 5),
              espressione (10 ^ 6),
              espressione (10 ^ 7),
              espressione (10 ^ 8),
espressione (10 ^ 9)))
axis (2, at = rep (c (2: 9), 9) * rep (10 ^ c (0: 8), each = 8), labels = rep ("", 8 * 9), tck = -0.02 )
title (bquote (paste ("scenario's for different", R [0])), cex.main = 1)

# tempo
t <- seq (0,60,0.1)

# modello di trama con differenti R0
per (R0 in c (1.1,1.2,1.5,2,3,5,10)) {
  fit <- data.frame (ode (y = init, times = t, func = SIR2, parms = c (const, R0))) $ I
  linee (t, fit)
  testo (t [601], adatta [601],
       bquote (incolla (R [0], "=",. (R0))),
       cex = 0,7, pos = 4)
}

# osservazioni sulla trama
punti (giorno, infetto)
 

Come viene stimato R0?

Il grafico sopra (che viene ripetuto sotto) ha mostrato che non c'è molta variazione nel numero di "infetti" in funzione di $ R_0 $ e i dati sul numero di persone infette non forniscono molte informazioni su $ R_0 $ (tranne se è superiore o inferiore a zero).

Tuttavia, per il modello SIR esiste una grande variazione nel numero di ripristinati o nel rapporto infetti / ripristinati. Questo è mostrato nell'immagine sottostante dove il modello è tracciato non solo per il numero di persone infette ma anche per il numero di persone guarite. Sono tali informazioni (oltre a dati aggiuntivi come informazioni dettagliate su dove e quando le persone sono state infettate e con chi hanno avuto contatti) che consentono la stima di $ R_0 $ .

exmple

Aggiorna

Nell'articolo del tuo blog scrivi che l'adattamento sta portando a un valore di $ R_0 \ approx 2 $ .

Tuttavia questa non è la soluzione corretta. Trovi questo valore solo perché optim termina in anticipo quando ha trovato una soluzione sufficientemente buona e i miglioramenti per una determinata dimensione del vettore $ \ beta, \ gamma $ stanno diventando piccoli.

Quando utilizzi l'ottimizzazione nidificata, troverai una soluzione più precisa con un $ R_0 $ molto vicino a 1.

Vediamo questo valore $ R_0 \ approx 1 $ perché è così che il modello (sbagliato) è in grado di ottenere questa variazione del tasso di crescita nella curva.

fit close to 1

  ###
####
####

libreria (deSolve)
libreria (RColorBrewer)

#https: //en.wikipedia.org/wiki/Timeline_of_the_2019%E2%80%9320_Wuhan_coronavirus_outbreak#Cases_Chronology_in_Mainland_China
< infetto- c (45,62,121,198,291,440,571,830,1287,1975,
              2744,4515,5974,7711,9692,11791,14380,17205,20440)
#Infected <- c (45,62,121,198,291,440,571,830,1287,1975,
# 2744,4515,5974,7711,9692,11791,14380,17205,20440,
# 24324,28018,31161,34546,37198,40171,42638,44653)
giorno <- 0: (length (Infected) -1)
N <- 1400000000 #pop della Cina

init <- c (S = N-Infected [1], I = Infected [1], R = 0)

# funzione modello
SIR2 <- funzione (ora, stato, parametri) {
  par <- as.list (c (stato, parametri))
  con (par, {
    beta <- const / (1-1 / R0)
    gamma <- const / (R0-1)
    dS <- - (beta * (S / N)) * I
    dI <- (beta * (S / N) -gamma) * I
    dR <- (gamma) * I
    elenco (c (dS, dI, dR))
  })
}

### Due funzioni RSS per eseguire l'ottimizzazione in modo annidato
RSS.SIRMC2 Funzione < (R0, const) {
  parametri <- c (const = const, R0 = R0)
  out <- ode (y = init, times = day, func = SIR2, parms = parameters)
  adatta <- out [, 3]
  RSS <- sum ((Infected_MC - fit) ^ 2)
  ritorno (RSS)
}

RSS.SIRMC <- funzione (const) {
  ottimizzare (RSS.SIRMC2, inferiore = 1, superiore = 10 ^ 5, const = const) $ obiettivo
}

# wrapper per ottimizzare e restituire i valori stimati
getOptim <- function () {
  opt1 <- ottimizza (RSS.SIRMC, inferiore = 0, superiore = 1)
opt2 <- ottimizza (RSS.SIRMC2, inferiore = 1, superiore = 10 ^ 5, const = opt1  $ minimo)
  return (elenco (RSS = opt2 $  obiettivo, const = opt1  $ minimo, R0 = opt2 $  minimo))
}

# facendo il modello annidato per ottenere RSS
Infected_MC <- Infected
modnested <- getOptim ()

rss <- sapply (seq (0.3,0.5,0.01),
       FUN = funzione (x) ottimizza (RSS.SIRMC2, inferiore = 1, superiore = 10 ^ 5, const = x) $ obiettivo)

trama (seq (0.3,0.5,0.01), rss)

ottimizzare (RSS.SIRMC2, inferiore = 1, superiore = 10 ^ 5, const = 0,35)


# Visualizza
modnested

### tracciare valori diversi R0

const <- modnested  $ const
R0 <- modnested $  R0

# grafico
grafico (-100, -100, xlim = c (0,80), ylim = c (1,6 * 10 ^ 4), log = "",
     ylab = "infetto", xlab = "giorni")
title (bquote (paste ("scenario's for different", R [0])), cex.main = 1)

### questo è ciò che la tua beta e gamma dal blog
beta = 0,6746089
gamma = 0,3253912
fit <- data.frame (ode (y = init, times = t, func = SIR, parms = c (beta, gamma))) $ I
linee (t, fit, col = 3)

# modello di trama con differenti R0
t <- seq (0,50,0.1)
for (R0 in c (modnested  $ R0,1.07,1.08,1.09,1.1,1.11)) {
  fit <- data.frame (ode (y = init, times = t, func = SIR2, parms = c (const, R0))) $ I
  linee (t, fit, col = 1 + (modnested $ R0 == R0))
  testo (t [501], adattato [501],
       bquote (incolla (R [0], "=",. (R0))),
       cex = 0.7, pos = 4, col = 1 + (modnested $  R0 == R0))
}

# osservazioni sulla trama
punti (giorno, infetto, cex = 0,7)
 

Se usiamo la relazione tra persone recuperate e infette $ R ^ \ prime = c (R_0-1) ^ {- 1} I $ allora vediamo anche l'opposto, vale a dire un grande $ R_0 $ di circa 18:

  I <- c (45,62,121,198,291,440,571,830,1287,1975,2744,4515,5974,7711,9692,11791,14380,17205,20440, 24324,28018,31161,34546,37198,40171,42638 , 44653)
D <- c (2,2,2,3,6,9,17,25,41,56,80,106,132,170,213,259,304,361,425,490,563,637,722,811,908,1016,1113)
R <- c (12,15,19,25,25,25,25,34,38,49,51,60,103,124,171,243,328,475,632,892,1153,1540,2050,2649,3281,3996,4749)
Un <- I-D-R

grafico (A [-27], diff (R + D))
mod <- lm (diff (R + D) ~ A [-27])
 

dare:

  > const
[1] 0,3577354
> const / mod $ coefficienti [2] +1
  A [-27]
17.87653
 

Questa è una restrizione del modello SIR che modella $ R_0 = \ frac {\ beta} {\ gamma} $ dove $ \ frac {1} {\ gamma} $ è il periodo di tempo in cui qualcuno è malato (tempo da infetto a guarito) ma potrebbe non essere necessario che qualcuno sia contagioso. Inoltre, i modelli di compartimento sono limitati poiché l'età dei pazienti (quanto tempo si è ammalati) non viene presa in considerazione e ogni età dovrebbe essere considerata come un compartimento separato.

Ma in ogni caso. Se i numeri di wikipedia sono significativi (potrebbero essere messi in dubbio), solo il 2% degli attivi / infetti si riprende quotidianamente, e quindi il parametro $ \ gamma $ sembra essere piccolo (non importa quale modello usi).

Grazie!Un piccolo punto: non dovrebbe essere `c (2 * coefficienti (mod) [2] / N, coefficienti (mod) [1])` nella funzione optbin?
@vondj i coefficienti (mod) [2] è il fattore esponenziale che si riferisce a $$ I '\ approx \ underbrace {(\ beta \ cdot N - \ gamma)} _ {\ text {fattore di adattamento esponenziale}} \ cdot I$$ Quindi hai $ \ text {factor} = \ beta \ cdot N - \ gamma $ E ho scelto qui $ \ beta = 2 \ text {factor} / N $ e $ \ gamma = \ text {factor} $.Il parametro coefficienti (mod) [1] è il punto di partenza (l'altezza) della curva esponenziale.
Ok, grazie ancora ... penso di aver incluso tutti i tuoi suggerimenti ... eppure ancora non ne ricavo alcun valore sensibile (R0 è ancora infinito) ... penso che il mio modello non possa essere salvato: -(
si prega di dare un'occhiata: http://blog.ephorie.de/wp-content/uploads/2020/01/fitting_2019-nCov_with_optim2.pdf
nota extra: mi piace scalare i parametri nella funzione chiamata invece che tramite l'opzione parscale.L'opzione parscale non ridimensiona l'output dell'iuta, il che è un po 'fastidioso.
pdfs: penso che il ribasso standard con pandoc.
ok, penso di aver provato entrambe le versioni ora ... anche se questa (ridimensionamento in ottim) termina con un errore, viene prodotto un qualche tipo di adattamento (sebbene R0 sia ancora Inf): http://blog.ephorie.de/wp-content / upload / 2020/01 / fitting_2019-nCov_with_optim2.pdf
Questa versione (ridimensionamento in SIR) non funziona: http://blog.ephorie.de/wp-content/uploads/2020/01/fitting_2019-nCov_with_optim3.pdf
Ah, ora la variante tre funziona e dà beta = 0,8310849 e gamma = 0,4137507!Grazie mille per tutto lo sforzo!
Come hai creato le due trame a destra?
Ma tieni presente che questi due parametri singolarmente presentano un grosso errore.Sarà qualcosa di simile a una combinazione lineare dei due (qualcosa di vicino a $ \ beta- \ gamma $ o $ \ beta / N - \ gamma $, a seconda del ridimensionamento) che verrà approssimata con alta precisione.
Il grafico a destra è in scala logaritmica.
In relazione alla mia ultima aggiunta (inclusi i casi di recupero nel calcolo) un modo molto rapido per valutare $ R_0 $ è usare $$ - \ frac {S ^ \ prime} {R ^ \ prime} = R_0 \ frac {S}{N} \ approx R_0 $$ e nota che la velocità con cui le persone vengono infettate è molto maggiore della velocità con cui le persone si riprendono.Quindi, in base a questi dati, $ R_0 $ dovrebbe essere considerato alto.Ciò non richiede adattamento.
Wow, sono totalmente sopraffatto dallo sforzo che ci metti in questo!Posso chiederti se vuoi scrivere un post di follow-up sul mio blog in cui discuti di questi punti per un pubblico più ampio ... Penso che potrebbe valere la pena!(Sono ovviamente aperto anche a qualsiasi altro argomento che desideri condividere con un pubblico più vasto!) Grazie ancora per tutto !!
@vonjd Ho alcune idee per arricchire questa risposta / post.Contattami di nuovo dopo il fine settimana se non avessi risposto di nuovo entro quell'ora.
Sembra fantastico!Come posso contattarti?Puoi contattarmi qui: https://blog.ephorie.de/about
la prima reazione che ho visto "condizioni al contorno sbagliate", stavo pensando a vincoli di ottimizzazione.potrebbe essere il termine "valore iniziale errato" sarebbe meglio.
@HaitaoDu infatti, per questo problema specifico si potrebbe utilizzare il termine "valore iniziale" o "valore iniziale".Ma personalmente preferisco il termine "condizione al contorno" che è un termine molto comune quando viene utilizzato intorno alle equazioni differenziali.Pensa ad esempio a https://en.m.wikipedia.org/wiki/Boundary_value_problem
grazie per la tua risposta e commento, aggiungerei altri 50 punti alla tua meritata reputazione !!
pensi che impostare N = 1.4b pop della Cina sia un problema?perché il virus inizia in una città.Nel mondo reale, ho sempre difficoltà a impostare questi parametri ...., qual è il presupposto corretto o addirittura stretto?
@HaitaoDu in un blogpost sul sito di vondj ho risolto questo problema.Ho impostato N a parametri liberi nel raccordo.Ma ancora meglio sarebbe usare un modello diverso.Il modello SIR regolare presume erroneamente una miscelazione omogenea della popolazione, parametri epidemiologici costanti, infezione istantanea (senza incubazione), modelli deterministici anziché stocastici, e ogni persona è la stessa.Va bene per un primo sguardo, ma in questo caso dovresti adattarti rapidamente a modelli più complessi.
Si noti inoltre che è sbagliato parlare del * valore * $ R_0 $ come se fosse l'unica cosa che conta.Può essere più complesso di così.In un post sul blog di follow-up (da pubblicare) mostrerò un esempio di crescita esponenziale per una media di $ R_0 = 1/3 $ in un modello SIR di rete.(La crescita è dovuta a una forte infettività eterogenea degli individui, come i superdiffusori non tutti si riprodurranno nella stessa quantità)
@SextusEmpiricus, ti sarei grato se modifichi la tua risposta e includi un codice completo alla fine invece di pezzi perché mi sono perso.Inoltre ho provato la funzione nls con nuovi dati e ricevo l'errore "singular gradiente".
@SimpleNEasy il codice in questa risposta è davvero un po 'rotto.Puoi visualizzare un esempio migliore su https://blog.ephorie.de/contagiousness-of-covid-19-part-i-improvements-of-mathematical-fitting-guest-post.
@SextusEmpiricus Grazie.E se consideriamo il modello SEIR ?, come ottimizzare la terza variabile sconosciuta che verrà aggiunta oltre a beta e gamma.
@SimpleNEasy Credo che un modello SEIR stia rendendo il modello ancora più [mal condizionato] (https://en.wikipedia.org/wiki/Well-posed_problem).La categoria esposta sta solo causando una sorta di ritardo nell'autocorrelazione (in un modello SIR l'attuale popolazione infetta influenza direttamente la successiva popolazione infetta, ma in realtà dovrebbe esserci un certo ritardo), ma non cambierà lacurva epidemica tanto che rimane più o meno una funzione esponenziale dove il fattore di crescita sta lentamente cambiando .....
.... chiedi "come ottimizzare la terza variabile sconosciuta", ma nota che il messaggio chiave della mia risposta è che non puoi davvero stimare questi valori, con un adattamento solo a una singola serie temporale.Avrai bisogno di informazioni più dettagliate, ad es.(informazioni su chi sta infettando chi e quando le persone hanno avuto contatti e informazioni sull'evoluzione dei sintomi) .....
... ma comunque, per quello che vale, un modello che si comporta come un modello SEIR è [questo modello SIR spaziale] (https://stats.stackexchange.com/a/461455/164061).L'effetto dell'infezione esposta è nell'approccio basato su agenti in cui calcoliamo un tempo di attesa / incubazione (casuale) per quando una persona infetta inizia a infettare gli altri (che è un po 'simile al cambiamento da esposto a infetto e al tempo di residenzanel gruppo esposto).Tuttavia non è facile adattare tali modelli, ma poi di nuovo, credo che non dovremmo provare ad adattare questi modelli .....
... solo quando il tempo di incubazione è molto lungo, potresti vedere un comportamento periodico nelle curve per i modelli SEIR.
@SextusEmpiricus Spiegazione perfetta.Ho letto alcuni articoli secondo cui covid-10 non dovrebbe essere modellato con SIR, invece dovrebbe essere con SEIR a causa del periodo di incubazione.Tuttavia, sono totalmente d'accordo con la tua giustificazione.
@SimpleNEasy Penso che per la modellazione potrebbe avere senso.* Se conosci i parametri epidemiologici * puoi creare una curva più sensata che si riferisca ai parametri che conosci.Ma nelle altre direzioni l'uso delle curve per stimare i parametri epidemiologici non funziona così bene e la differenza tra SIR e SEIR non ha molta importanza.In questa risposta possiamo vedere che è solo il parametro $ K = \ beta - \ gamma $ che può essere stimato in modo affidabile.
Cerchiamo di [continuare questa discussione in chat] (https://chat.stackexchange.com/rooms/108335/discussion-between-simpleneasy-and-sextus-empiricus).
@SextusEmpiricus, Ho provato a eseguire il codice nel blog su un diverso set di dati e non sono riuscito a ottenere un adattamento per i dati.Ho pubblicato una domanda con i miei dati.Qualsiasi suggerimento https://stats.stackexchange.com/questions/467948/fixing-convergence-in-sir-model-using-modified-fit-model-to-fit-covid-19-data
S. Catterall Reinstate Monica
2020-01-28 18:35:19 UTC
view on stackexchange narkive permalink

Potresti riscontrare problemi numerici a causa delle dimensioni molto elevate della popolazione $ N $ , che imporrà la stima di $ \ beta $ per essere molto vicino allo zero.È possibile parametrizzare nuovamente il modello come \ begin {align} {\ mathrm d S \ over \ mathrm d t} & = - \ beta {S I / N} \\ [1.5ex] {\ mathrm d I \ over \ mathrm d t} & = \ beta {S I / N} - \ gamma I \\ [1.5ex] {\ mathrm d R \ over \ mathrm d t} & = \ gamma I \\ \ end {align}

Questo renderà la stima di $ \ beta $ più grande, quindi si spera che tu possa ottenere qualcosa di più sensato dall'ottimizzazione.

In questo contesto il modello SIR è utile ma fornisce solo un adattamento molto approssimativo a questi dati (si presume che l'intera popolazione della Cina si mescoli in modo omogeneo). Forse non è poi così male come primo tentativo di analisi. Idealmente vorresti un qualche tipo di modello spaziale o di rete che rifletta meglio la vera struttura di contatto nella popolazione. Ad esempio, un modello di metapopolazione come descritto nel Programma 7.2 e nel libro allegato ( Modeling Infectious Diseases in Humans and Animals , Keeling & Rohani). Tuttavia questo approccio richiederebbe molto più lavoro e anche alcuni dati sulla struttura della popolazione. Un'alternativa approssimativa potrebbe essere sostituire $ I $ in $ \ beta SI / N $ (in entrambi delle prime due equazioni) con $ I ^ \ delta $ dove $ \ delta $ , che probabilmente è $ <1 $ , è un terzo parametro da stimare. Un tale modello cerca di catturare il fatto che la forza dell'infezione su un suscettibile aumenta meno che linearmente con il numero di infetti $ I $ , evitando di specificare una popolazione esplicita struttura. Per maggiori dettagli su questo approccio, vedere ad es. Hochberg, Velocità di trasmissione non lineare e dinamiche delle malattie infettive , Journal of Theoretical Biology 153: 301-321.

Grazie ... qualche suggerimento per far funzionare questo modello?
@vonjd Vedi le modifiche sopra
Grazie ancora ... quindi devi cambiarlo nelle prime due equazioni, giusto?
@vonjd Sì, vedere ulteriori modifiche
Demetri Pananos
2020-01-28 21:23:25 UTC
view on stackexchange narkive permalink

Poiché la popolazione della Cina è enorme, i parametri saranno molto piccoli.

Dato che siamo nei primi giorni dell'infezione e poiché N è così grande, $ S (t) I (t) / N \ ll 1 $ span>.Sarebbe più ragionevole presumere che in questa fase dell'infezione il numero di persone infette sia approssimativamente esponenziale e si adatti a un modello molto più semplice.

Grazie ... potresti essere più specifico su come cambiare il codice?
@vonjd Sto pensando a come farlo da solo.Non credo che il codice sia un problema, penso che dovrai ripensare al modello.
sigoldberg1
2020-02-09 13:16:53 UTC
view on stackexchange narkive permalink

Questo è solo marginalmente correlato alla discussione dettagliata sulla codifica, ma sembra molto rilevante per la domanda originale riguardante la modellizzazione dell'attuale epidemia di 2019-nCoV.Si prega di consultare arxiv: 2002.00418v1 (documento su https://arxiv.org/pdf/2002.00418v1.pdf) per un sistema di equazioni diff ritardato ~ modello a 5 componenti, con stima dei parametri e previsioni utilizzando dde23 inMatLab.Questi sono confrontati con i rapporti pubblicati quotidianamente di casi confermati, numero guarito, ecc. Per me è abbastanza degno di discussione, perfezionamento e aggiornamento.Conclude che c'è una biforcazione nello spazio della soluzione dipendente dall'efficacia dell'isolamento, spiegando così le forti misure di sanità pubblica recentemente adottate, che finora hanno buone possibilità di successo.

Un caloroso benvenuto a te.È possibile aggiungere un breve riassunto dell'articolo - solo poche righe, per facilità di riferimento futuro.
Filip Floegel
2020-03-31 23:30:05 UTC
view on stackexchange narkive permalink

cosa ne pensi di mettere il numero iniziale di contagiosi come parametro aggiuntivo nel problema di ottimizzazione, altrimenti l'adattamento deve iniziare con la condizione iniziale.

Che funzioni.E non solo il numero iniziale di persone infettive, ma anche il numero iniziale di persone suscettibili dovrebbe essere un parametro aggiuntivo.Vedi qui in seguito alla domanda https://blog.ephorie.de/contagiousness-of-covid-19-part-i-improvements-of-mathematical-fitting-guest-post
Forse questa risposta sarebbe stata migliore come commento.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 4.0 con cui è distribuito.
Loading...