Off by 50 or off by 10?

June 8, 2009 at 9:22 am 1 comment

| Gabriel |

Via MR, the NY Times has an article noting that two models of swine flu drastically under-estimated the spread of the epidemic. It notes that the actual number of American cases is something like 100,000 but the estimates were about 2,000. The natural inference is to think that they were off by a laughably wild factor of 50. However this just shows how hard it is to think about nonlinearity. The authors of the original predictions blamed the error on an underestimate of the number of infections seeding the system.

This sounds very plausible to me and in fact I can demonstrate just how sensitive contagion models are to such assumptions as the number of seed values. Here’s a graph of two contagions. Although the assumptions vary by an order of magnitude, they diverge by even more.

projection_pooled

Here’s are some of the simplifying assumptions:

  • the diffusion follows a Bass model
  • after the intial cases there are no exogenous infections (e.g., from foreign travel)
  • the population is homogenous population with no network structure

Here’s the Stata code so anyone with a copy of Stata should be able to replicate this and even fiddle with the parameters.

capture program drop bassproject
program define bassproject
	set more off
	syntax anything(name=commandinput) [, graphoff nosave]
	local match=regexm("`commandinput'","a ?\(([^\)]+)\) ?")
	if `match'==1 {
		local a=regexs(1)
	}
	else {
		local a=0
	}
	local match=regexm("`commandinput'","b ?\(([0-9]*\.?[0-9]*)\) ?")
	if `match'==1 {
		local b=regexs(1)
	}
	else {
		local b=0
	}
	local match=regexm("`commandinput'","[nN]?max ?\(([0-9]*\.?[0-9]*)\) ?")
	if `match'==1 {
		local nmax=regexs(1)
	}
	else {
		local nmax=1
	}
	local match=regexm("`commandinput'","seed ?\(([0-9]*\.?[0-9]*)\) ?")
	if `match'==1 {
		local seed=regexs(1)
	}
	else {
		local seed=0.01
	}
	local match=regexm("`commandinput'","periods ?\(([0-9]*\.?[0-9]*)\) ?")
	if `match'==1 {
		local periods=regexs(1)
 	}
	else {
		local periods=20
	}
	local match=regexm("`commandinput'","modeln?a?m?e? ?\(([^\)]+)\)")
	if `match'==1 {
		local modelname=regexs(1)
	}
	else {
		local model="model"
	}
	disp "model named(`modelname')."
	disp "delta_Nt=(`a' + `b' * Nt) * (`nmax' - Nt)"
	disp "projected over `periods' spells with N_0=`seed'"
	preserve
	clear
	set obs `periods'
	quietly gen t=[_n]-1
	quietly gen Nt=.
	quietly gen deltan=.
	quietly replace Nt=`seed' in 1
	quietly replace deltan=(`a' + (`b' * Nt)) * (`nmax' - Nt) in 1
	forvalues period=2/`periods' {
		quietly replace Nt=Nt[_n-1]+deltan[_n-1] in `period'
		quietly replace deltan=(`a' + (`b' * Nt)) * (`nmax' - Nt) in `period'
	}
	sort t
	ren Nt nt_`modelname'
	drop deltan
	if "`nosave'"~="nosave" {
		save projection_`modelname', replace
	}
	if "`graphoff'"~="graphoff" {
		twoway (line nt_`modelname' t, lwidth(thick)), ytitle(Saturation to Date) xtitle(Time) /* ylabel(none, nolabels)  xlabel(none, nolabels) */
		graph export projection_`modelname'.png, replace
	}
	clear
	restore
end

cd ~/Documents/codeandculture/blackswine
*the assumptions go in the following two lines. aside from periods, all #s should be between 1 and 0
bassproject a(0) b(.5) seed(.00001) nmax(1) periods (20) model(smallseed)
bassproject a(0) b(.5) seed(.0001) nmax(1) periods (20) model(bigseed)

use projection_bigseed.dta, clear
append using projection_smallseed
lab var nt_bigseed "Assume many seed"
lab var nt_smallseed "Assume few seed"
twoway (line nt_bigseed t, lwidth(thick)) (line nt_smallseed t, lwidth(thick)), ytitle(Saturation to Date) xtitle(Time) /* ylabel(none, nolabels)  xlabel(none, nolabels) */
graph export projection_pooled.png, replace

Entry filed under: Uncategorized. Tags: .

Nested logit vs multinomial logit Scraping 101

1 Comment

  • 1. Mike3550  |  June 8, 2009 at 10:14 am

    Gabriel – you might be interested in this post by a flu epidemiologist who has had some of the best public health and scientific coverage of the swine flu outbreak (and, unfortunately, in this post it comes home to his own family). There is a graph in there that shows the makeup of different types of flu that have occurred during the regular flu season and the drastic uptick since the swine flu outbreak.


The Culture Geeks


%d bloggers like this: