R中的预测准确性

时间:2018-11-21 11:27:19

标签: r

我已遵循this StMoMo包装文件中的说明,以使Lee Carter适合加拿大的死亡率数据。

我的项目的下一步是在适合该加拿大数据时,测量Lee Carter模型的预测准确性。

为此,我尝试使用precision(),但是由于我的Lee Carter fit是“ fitStMoMo”类而不是“ forecast”类或时间序列,因此遇到了错误。

我是否可以在“ fitStMoMo”对象上使用其他预测准确性函数,该函数将为我计算平均误差,均方根误差,平均绝对误差,平均百分比误差,平均绝对百分比误差和平均绝对比例误差?

Reprex

在StMoMo文档中使用EWMaleData创建的Reprex专门用于标记错误:

library("StMoMo")
library("demography")
library("forecast")

constLC <- function(ax, bx, kt, b0x, gc, wxt, ages){
    c1 <- mean(kt[1, ], na.rm = TRUE)
    c2 <- sum(bx[, 1], na.rm = TRUE)
    list(ax = ax + c1 * bx, bx = bx / c2, kt = c2 * (kt - c1))
}
LC <- StMoMo(link = "logit", staticAgeFun = TRUE, periodAgeFun = "NP",
constFun = constLC)
LC <- lc(link = "logit")
LC$gnmFormula
#> [1] "D/E ~ -1 + offset(o) + factor(x) + Mult(factor(x), factor(t), inst = 1)"

EWMaleData
#> Mortality data for England and Wales
#>     Series:  male
#>     Years: 1961 - 2011
#>     Ages:  0 - 100
#>     Exposure:  central

EWMaleIniData <- central2initial(EWMaleData)
ages.fit <- 55:89
wxt <- genWeightMat(ages = ages.fit, years = EWMaleIniData$years,
clip = 3)
LCfit <- fit(LC, data = EWMaleIniData, ages.fit = ages.fit, wxt = wxt)
#> StMoMo: The following cohorts have been zero weigthed: 
#>   1872 1873 1874 1954 1955 1956 
#> StMoMo: Start fitting with gnm
#> Initialising
#> Running start-up iterations..
#> Running main iterations.....
#> Done
#> StMoMo: Finish fitting with gnm

LCfor <- forecast(LCfit, h = 50)
class(LCfit)
#> [1] "fitStMoMo"
class(LCfor)
#> [1] "forStMoMo"
accuracy(LCfit)
#> Error in accuracy.default(LCfit): First argument should be a forecast object 
#>   or a time series.
accuracy(LCfor)
#> Error in accuracy.default(LCfor): First argument should be a forecast object
#>   or a time series.

1 个答案:

答案 0 :(得分:1)

我不确定accuracy()中的forecast是如何工作的,但是在某种程度上,它必须比较实际值和预测值,并返回有关它们之间的差异的度量。从广义上讲,这可以视为交叉验证的一种形式。由于accuracy()StMoMo对象不起作用,我们最好自己开发一个交叉验证例程。
有关这种交叉验证形式的简短介绍,我建议在tsCV()的{​​{1}}上使用Rob Hyndman's notes。如果可以在这里使用forecast,那将是很好的选择,但它仅适用于单变量时间序列,而死亡率数据本质上是多元时间序列。
我还应该提到,在今天之前,我从未听说过死亡率模型,因此我对模型理论的这一部分非常模糊。

第一位与已经发布的内容相同

tsCV()

然后情况有所不同。在时间序列上执行CV的中心点是对我们实际拥有的数据进行预测,但是我们假装没有。因此,我们必须对数据进行子集处理,以便要预测的数据块不属于模型。在这个具体示例中,我们将使用前30年,然后预测下10年

library(StMoMo)
library(demography)
library(forecast)

data(EWMaleData)

constLC <- function(ax, bx, kt, b0x, gc, wxt, ages){
    c1 <- mean(kt[1, ], na.rm = TRUE)
    c2 <- sum(bx[, 1], na.rm = TRUE)
    list(ax = ax + c1 * bx, bx = bx / c2, kt = c2 * (kt - c1))
}

LC <- StMoMo(link="logit", staticAgeFun=TRUE, periodAgeFun="NP", constFun=constLC)
LC <- lc(link="logit")

EWMaleIniData <- central2initial(EWMaleData)

现在我们有了十年的预测,我们可以将这些年与实际数据进行比较,并使用我们想要的任何误差度量来查看预测的准确性。

ages.fit <- 55:89
years.fit <- EWMaleIniData$years[1]:(EWMaleIniData$years[1] + 30)
years.for <- 10

wxt <- genWeightMat(ages=ages.fit, years=years.fit, clip=3)
LCfit <- fit(LC, data=EWMaleIniData, ages.fit=ages.fit,
  years.fit=years.fit, wxt=wxt)
LCfor <- forecast(LCfit, h=years.for)

该位仅用于显示结果

cvy <- LCfor$years  # years used in forecast
cva <- LCfor$ages   # ages used in forecast

pred <- LCfor$rates # predicted mortality rates

# actual mortality rates subset to the same ages and years as forecast
actual <- EWMaleIniData$Dxt/EWMaleIniData$Ext
actual <- actual[rownames(actual) %in% cva,
                 colnames(actual) %in% cvy]

# A collection of error measures. plenty of others can be devised
err <- pred - actual
Q <- pred/actual
rmse <- sqrt(rowMeans(err^2))
mae <- rowMeans(abs(err))
smape <- 100 * (rowMeans(exp(abs(log(Q)))) - 1)

enter image description here

如Hyndman的注释所示,要正确执行此操作,我们必须使用时间序列中几个点的预测值和平均得分来进行比较。