Obviously the birds are going to have a different birth rate and death rate every single year. You could find the 19 different birth rates and 19 different death rates to perfectly fit the first twenty years of the Grants' counts.
So do it. Fit one year by hand, then take the rest.
But if you do that: what's the death rate for 1996? The birth rate? I have never thrown this exact eraser at that table on this day in my life. If I throw it that direction, what's going to happen? Everybody knows. Why? The rules don't change.
Here the rule is one number per year, and it changes every year. So each year, before it is unveiled, you say how many birds there will be.
p <- read.csv("data/clean/finch_pop.csv")N <- p$scandens; fit <- 20# one pair of numbers for every year of the recordb <- numeric(fit); d <- numeric(fit)b[2] <- 0.200d[2] <- 0.200for (t in 3:fit) { d[t] <- 0.2; b[t] <- N[t]/N[t-1] - 1 + d[t] }# the model is the data. 38 numbers, no error leftyhat <- N[1:(fit-1)] * (1 + b[2:fit] - d[2:fit])mean(abs(yhat - N[2:fit]))# and for year 21 there is no b and no d to useb[fit+1]
Models are wrong. But they can be usefully wrong. A model is a simplification of the world in order to better understand it. Fitting a model means finding the parameters that best predict the response from the predictors. The fit is how well that prediction matches reality.
So instead of trying to predict twenty years of data with 38 parameters that are each made up to fit what we've already seen, we're going to try it with two, and see how far we're off.
Same twenty years. Two numbers, and functionally one — only births minus deaths does anything. Get the miss as low as it will go. Then unveil the rest of the record.
p <- read.csv("data/clean/finch_pop.csv")N <- p$scandens; fit <- 2:20; held <- 21:37b <- 0.20d <- 0.20yhat <- N[1:36] * (1 + b - d)# fitted on the first twenty, scored on the restmean(abs(yhat[fit-1] - N[fit]))mean(abs(yhat[held-1] - N[held]))
Two more numbers, but not two more years. Rain that year, and how crowded the island already was.
Neither of those is true. The rain does not make nestlings; it makes seeds, and nobody counted the seeds. Crowding is not a cause, it is a stand-in for every way an island runs out of room. Never true — but often close enough.
Using fewer parameters means we can test how reliable each one is. These two are worth testing because they say something about 1996 as well as about 1983, which is more than a birth rate for 1983 ever did.
Fit them on the same twenty years. Then unveil.
p <- read.csv("data/clean/finch_pop.csv")r <- read.csv("data/clean/grant_rainfall.csv")N <- p$scandenswet <- log10(r[match(p$year, r$Year), 2] + 1) - 1.88b0 <- 0.30d0 <- 0.30rainPull <- 0.00crowdPull <- 0.00b <- b0 + rainPull * wet[1:36]d <- d0 + crowdPull * (log10(N[1:36]) - 2.24)yhat <- N[1:36] * (1 + b - d)mean(abs(yhat[1:19] - N[2:20]))mean(abs(yhat[20:36] - N[21:37]))
Three models, the same twenty years to learn from, the same years held back.
Every extra parameter is one more opportunity to be wrong. Adding more isn't safer — it's more surface area for error. But the 38-parameter model and the 4-parameter model do not fail the same way, and the count is not what separates them.
Read the row you did the most work for. Then read the row that predicted best. It's a model — how good are the data that you buy that prediction.
| What you fitted | Parameters | Miss on the fitted years | Miss on the years you predicted | Miss on all 17 held-back years |
|---|
# the whole lesson, as a tablescore <- function(yhat, obs, idx) mean(abs(yhat[idx] - obs[idx]))fitted <- 2:20held <- 21:37data.frame( model = c("one pair per year", "one pair, all years", "rain + crowding"), np = c(38, 2, 4), in = c(score(y1, N, fitted), score(y2, N, fitted), score(y3, N, fitted)), out = c(NA, score(y2, N, held), score(y3, N, held)))