Reserving based on log-incremental payments in R, part II

Following on from last week’s post I will continue to go through the paper Regression models based on log-incremental payments by Stavros Christofides [1]. In the previous post I introduced the model from the first 15 pages up to section F. Today I will progress with sections G to K which illustrate the model with a more realistic incremental claims payments triangle from a UK Motor Non-Comprehensive account:

# Page D5.17
tri <- t(matrix(
c(3511, 3215, 2266, 1712, 1059, 587, 340,
4001, 3702, 2278, 1180, 956, 629, NA,
4355, 3932, 1946, 1522, 1238, NA, NA,
4295, 3455, 2023, 1320, NA, NA, NA,
4150, 3747, 2320, NA, NA, NA, NA,
5102, 4548, NA, NA, NA, NA, NA,
6283, NA, NA, NA, NA, NA, NA), nc=7))
The rows show origin period data, e.g. accident years, underwriting years or years of account and the columns present the development periods or lags. The triangle appears to be fairly well behaved. The last two years in rows 6 and 7 appear to be slightly higher than rows 2 to 5 and the values in row 1 are lower in comparison to the later years. The last payment of £1,238 in the third row stands out a bit as well.

Before I plot the data, I will transform the triangle into a data frame and add extra columns:
m <- dim(tri)[1]; n <- dim(tri)[2]
dat <- data.frame(
origin=rep(0:(m-1), n),
dev=rep(0:(n-1), each=m),
value=as.vector(tri))

## Add dimensions as factors
dat <- with(dat, data.frame(origin, dev, cal=origin+dev,
value, logvalue=log(value),
originf=factor(origin),
devf=as.factor(dev),
calf=as.factor(origin+dev)))
I am particularly interested in the decay of claims payments in the development year direction for each origin year on the original and log-scale. The interaction.plot of the stats package does an excellent job for this:
op <- par(mfrow=c(2,1), mar=c(4,4,2,2))
with(dat, interaction.plot(x.factor=dev, trace.factor=origin,
response=value))
points(dat$devf, dat$value, pch=16, cex=0.5)
with(dat, interaction.plot(x.factor=dev, trace.factor=origin,
response=logvalue))
points(dat$devf, dat$logvalue, pch=16, cex=0.5)
par(op)
Indeed the origin years 1 to 4 (rows 2 to 5) look quite similar and the decay of claims in development year direction appears to be linear on a log-scale from development year 1 onwards.

Based on those observations Christofides suggests two models; the first one will have a unique level for each origin year and a unique level for the zero development period. The parameters for development periods 1 to 6 are assumed to follow a linear relationship with the same slope:
$$\begin{align} \ln(P_{ij}) & = Y_{ij} = a_i + d_j + \epsilon_{ij} \;\; \mbox{for } i,\,j \mbox{ from } 0 \mbox{ to } 6\\
\mbox{where } d_0 &= d,\;\; d_j = s \cdot j\;\; \mbox{for } j > 0 \end{align}$$ and $\epsilon_{ij} \sim N(0, \sigma^2)$. The second model will be a reduced version of the above with only two levels for the origin years 5 and 6. Hence, I add four more columns to my data frame:
dat <- with(dat, 
data.frame(dat,
a6 = ifelse(origin == 6, 1, 0),
a5 = ifelse(origin == 5, 1, 0),
d = ifelse(dev < 1, 1, 0),
s = ifelse(dev < 1, 0, dev)))

dat <- dat[order(dat$origin),] # to have similar output as in the paper
As in the earlier section of the paper and my previous post, I start with a model using all levels of the origin factor:
# Page D5.2021
summary(Fit1 <- lm(logvalue ~ 0 + originf + d + s, data=na.omit(dat)))

# Call:
# lm(formula = logvalue ~ 0 + originf + d + s, data = na.omit(dat))
#
# Residuals:
# Min 1Q Median 3Q Max
# -0.22142 -0.03973 0.01116 0.03289 0.19622
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# originf0 8.57284 0.07569 113.262 < 2e-16 ***
# originf1 8.57379 0.07152 119.884 < 2e-16 ***
# originf2 8.66487 0.06936 124.923 < 2e-16 ***
# originf3 8.55412 0.07022 121.814 < 2e-16 ***
# originf4 8.63666 0.07587 113.841 < 2e-16 ***
# originf5 8.84550 0.09059 97.646 < 2e-16 ***
# originf6 9.04182 0.13368 67.638 < 2e-16 ***
# d -0.29622 0.06990 -4.238 0.000445 ***
# s -0.43496 0.01849 -23.526 1.63e-15
# —
# Signif. codes: 0 ‘
’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 0.1139 on 19 degrees of freedom
# Multiple R-squared: 0.9999, Adjusted R-squared: 0.9998
# F-statistic: 1.428e+04 on 9 and 19 DF, p-value: < 2.2e-16
Clearly all origin levels are significantly different from zero, yet most of them are actually quite similar. The tests in the above output don’t make much sense as they test the various intercepts against zero. That’s easy to fix, I take out the first term ‘0 +’, which forced lm to fit individual intercepts. The next model makes much more sense:
# Page D5.2122
summary(Fit2 <- lm(logvalue ~ originf + d + s, data=na.omit(dat)))

# Call:
# lm(formula = logvalue ~ originf + d + s, data = na.omit(dat))
#
# Residuals:
# Min 1Q Median 3Q Max
# -0.22142 -0.03973 0.01116 0.03289 0.19622
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 8.5728353 0.0756903 113.262 < 2e-16 ***
# originf1 0.0009565 0.0639346 0.015 0.988220
# originf2 0.0920366 0.0686753 1.340 0.195997
# originf3 -0.0187149 0.0752609 -0.249 0.806287
# originf4 0.0638284 0.0843021 0.757 0.458254
# originf5 0.2726676 0.0982451 2.775 0.012052 *
# originf6 0.4689829 0.1315930 3.564 0.002072 **
# d -0.2962154 0.0699026 -4.238 0.000445 ***
# s -0.4349597 0.0184885 -23.526 1.63e-15
# —
# Signif. codes: 0 ‘
’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 0.1139 on 19 degrees of freedom
# Multiple R-squared: 0.9832, Adjusted R-squared: 0.9762
# F-statistic: 139.1 on 8 and 19 DF, p-value: 3.287e-15
Following Christofides I reduce the model, assuming a constant intercept (or constant claims in development period 0) for the origin years 0 to 4 and separate ones for the the origin years 5 and 6:
# Page D5.23
summary(Fit3 <- lm(logvalue ~ a5 + a6 + d + s, data=na.omit(dat)))

# Call:
# lm(formula = logvalue ~ a5 + a6 + d + s, data = na.omit(dat))
#
# Residuals:
# Min 1Q Median 3Q Max
# -0.21567 -0.04910 0.00654 0.05137 0.27198
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 8.60795 0.05150 167.142 < 2e-16 ***
# a5 0.24353 0.08517 2.859 0.008870 **
# a6 0.44111 0.12170 3.625 0.001421 **
# d -0.30345 0.06779 -4.476 0.000172 ***
# s -0.43967 0.01666 -26.390 < 2e-16
# —
# Signif. codes: 0 ‘
’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 0.1119 on 23 degrees of freedom
# Multiple R-squared: 0.9804, Adjusted R-squared: 0.977
# F-statistic: 287.7 on 4 and 23 DF, p-value: < 2.2e-16
Wonderful, all coefficients appear to be significant and I am left with a model of only five parameters. Next I look at the residual plots:
# Resdiual plots
op <- par(mfrow=c(2,2), mar=c(4,4,2,2))
attach(model.frame(Fit3))
with(na.omit(dat),
plot.default(rstandard(Fit3) ~ origin,
main=“Residuals vs. origin years”))
abline(h=0, lty=2)

with(na.omit(dat),
plot.default(rstandard(Fit3) ~ dev,
main=“Residuals vs. dev. years”))
abline(h=0, lty=2)
with(na.omit(dat),
plot.default(rstandard(Fit3) ~ cal,
main=“Residuals vs. payments years”))
abline(h=0, lty=2)
plot.default(rstandard(Fit3) ~ logvalue,
main=“Residuals vs. fitted”)
abline(h=0, lty=2)
detach(model.frame(Fit3))
par(op)
The residual plots look quite well behaved. The last payment in year 2 does appear to be a bit of an outlier and also the pattern in the payment or calendar year direction gives an indication of potential claims inflation which should be investigated further.

Following the paper and for the purpose of this post I want to focus on deriving estimators for the payments in future years and their standard errors. I did most of the leg work last week, so I here bring the various calculations for the forecast and error estimation together into a new function:
log.incr.predict <- function(
model, # lm output
newdata, # same argument as in predict
origin.var=“origin”, # name of the origin column in newdata
dev.var=“dev” # name of the dev column in newdata
){
origin <- newdata[[origin.var]]
dev <- newdata[[dev.var]]

Pred <- predict(model, newdata=newdata, se.fit=TRUE)

Y <- Pred$fit
VarY <- Pred$se.fit^2 + Pred$residual.scale^2
P <- exp(Y + VarY/2)
VarP <- exp(2Y + VarY)(exp(VarY)-1)
seP <- sqrt(VarP)

## Recreate formula to derive the model.frame and future design matrix
model.formula <- as.formula(paste(”~“, as.character(formula(model)[3])))
## See also package formula.tool

mframe <- model.frame(model.formula, data=newdata)
fdm <- model.matrix(model.formula, data=newdata)
varcovar <- fdm %% vcov(model) %% t(fdm)

OverallVar <- t(P) %% (exp(varcovar)-1) %% P
Total.SE <- sqrt(OverallVar)
Total.Reserve <- sum(P)

# Prepare output
Incr=data.frame(origin, dev, Y, VarY, P, seP, CV=seP/P)
out <- list(Forecast=Incr[order(newdata[[origin.var]]),],
Totals=data.frame(Total.Reserve,
Total.SE=Total.SE,
CV=Total.SE/Total.Reserve)
)

return(out)
}
With the above function it is straightforward to carry out the prediction of future claims payments and standard errors. As a bonus I can estimate claims payments beyond the available data, as my models assume an exponential decay. Here I will assume in line with Christofides that claims payments will stop 6 years after the latest available development data:
tail.years <- 6
# Create a data frame for the future periods
fdat <- data.frame(
origin=rep(0:(m-1), n+tail.years),
dev=rep(0:(n+tail.years-1), each=m)
)
fdat$cal <- with(fdat, origin + dev)

fdat <- with(fdat,
data.frame(fdat,
originf = factor(origin),
a6 = ifelse(origin == 6, 1, 0),
a5 = ifelse(origin == 5, 1, 0),
d = ifelse(dev < 1, 1, 0),
s = ifelse(dev < 1, 0, dev)))
So, here are the results for my two models:
FM2 <- log.incr.predict(Fit2, subset(fdat, cal>6))
FM2 # Page D5.3233

# $Forecast
# origin dev Y VarY P seP CV
# 50 0 7 5.528118 0.01947679 254.13254 35.639951 0.1402416
# 57 0 8 5.093158 0.02232053 164.73171 24.748983 0.1502381
# 64 0 9 4.658198 0.02584791 106.81754 17.284935 0.1618174
# 71 0 10 4.223239 0.03005895 69.28774 12.103614 0.1746862
# 78 0 11 3.788279 0.03495363 44.95921 8.479513 0.1886046
# 85 0 12 3.353319 0.04053196 29.18296 5.935315 0.2033829
# 44 1 6 5.964034 0.01852071 392.79744 53.704591 0.1367234
# 51 1 7 5.529074 0.02098384 254.56748 37.070434 0.1456212
# 58 1 8 5.094114 0.02413062 165.03864 25.792598 0.1562822
# 65 1 9 4.659155 0.02796105 107.03279 18.023389 0.1683913
# 72 1 10 4.224195 0.03247512 69.43788 12.615584 0.1816816
# 79 1 11 3.789235 0.03767285 45.06346 8.829618 0.1959374
# 86 1 12 3.354276 0.04355423 29.25507 6.172516 0.2109896
# 38 2 5 6.490074 0.01787515 664.48422 89.238683 0.1342977
# 45 2 6 6.055114 0.01994216 430.55926 61.106559 0.1419237
# 52 2 7 5.620154 0.02269282 279.08060 42.280723 0.1515000
# 59 2 8 5.185195 0.02612713 180.95676 29.441747 0.1627005
# 66 2 9 4.750235 0.03024509 117.37306 20.567807 0.1752345
# 73 2 10 4.315275 0.03504670 76.15712 14.383028 0.1888599
# 80 2 11 3.880315 0.04053196 49.43118 10.053456 0.2033829
# 87 2 12 3.445356 0.04670087 32.09519 7.017665 0.2186516
# 32 3 4 6.814282 0.01765354 918.83680 122.623541 0.1334552
# 39 3 5 6.379322 0.01929729 595.24359 83.088604 0.1395876
# 46 3 6 5.944362 0.02162469 385.74431 57.033048 0.1478519
# 53 3 7 5.509403 0.02463574 250.06492 39.492611 0.1579294
# 60 3 8 5.074443 0.02833043 162.16401 27.489339 0.1695157
# 67 3 9 4.639483 0.03270878 105.19731 19.182172 0.1823447
# 74 3 10 4.204524 0.03777077 68.26581 13.393528 0.1961967
# 81 3 11 3.769564 0.04351641 44.31495 9.345848 0.2108960
# 88 3 12 3.334604 0.04994571 28.77702 6.512388 0.2263051
# 26 4 3 7.331785 0.01813609 1542.02654 208.610284 0.1352832
# 33 4 4 6.896825 0.01930228 998.72172 139.427318 0.1396058
# 40 4 5 6.461865 0.02115212 647.06155 94.606974 0.1462102
# 47 4 6 6.026906 0.02368561 419.36786 64.925326 0.1548171
# 54 4 7 5.591946 0.02690275 271.88995 44.897168 0.1651299
# 61 4 8 5.156986 0.03080354 176.33544 31.188388 0.1768697
# 68 4 9 4.722027 0.03538797 114.40224 21.712803 0.1897935
# 75 4 10 4.287067 0.04065606 74.24682 15.124104 0.2037003
# 82 4 11 3.852107 0.04660779 48.20251 10.528803 0.2184285
# 89 4 12 3.417148 0.05324318 31.30473 7.320629 0.2338506
# 20 5 2 7.975584 0.02024479 2938.65106 420.248726 0.1430074
# 27 5 3 7.540624 0.02079769 1902.68762 275.827175 0.1449671
# 34 5 4 7.105664 0.02203424 1232.35383 183.942131 0.1492608
# 41 5 5 6.670704 0.02395444 798.45748 124.322818 0.1557037
# 48 5 6 6.235745 0.02655829 517.50747 84.899789 0.1640552
# 55 5 7 5.800785 0.02984579 335.52888 58.400959 0.1740564
# 62 5 8 5.365825 0.03381694 217.61641 40.359033 0.1854595
# 69 5 9 4.930866 0.03847173 141.18931 27.961671 0.1980438
# 76 5 10 4.495906 0.04381018 91.63481 19.391972 0.2116223
# 83 5 11 4.060946 0.04983227 59.49323 13.447943 0.2260416
# 90 5 12 3.625987 0.05653801 38.63875 9.318818 0.2411780
# 14 6 1 8.606859 0.02956698 5550.49295 961.508610 0.1732294
# 21 6 2 8.171899 0.02896367 3591.69920 615.713978 0.1714269
# 28 6 3 7.736939 0.02904400 2324.96711 399.122363 0.1716680
# 35 6 4 7.301979 0.02980798 1505.50472 261.874245 0.1739445
# 42 6 5 6.867020 0.03125561 975.20492 173.764972 0.1781830
# 49 6 6 6.432060 0.03338689 631.91417 116.434338 0.1842566
# 56 6 7 5.997100 0.03620181 409.60831 78.645947 0.1920028
# 63 6 8 5.562141 0.03970039 265.59988 53.450274 0.2012436
# 70 6 9 5.127181 0.04388262 172.28023 36.489139 0.2118011
# 77 6 10 4.692221 0.04874849 111.78704 24.985402 0.2235089
# 84 6 11 4.257262 0.05429801 72.55978 17.139964 0.2362185
# 91 6 12 3.822302 0.06053118 47.11388 11.769112 0.2498014
#
# $Totals
# Total.Reserve Total.SE CV
# 1 34377.1 2742.493 0.07977674


FM3 <- log.incr.predict(Fit3, subset(fdat, cal>6))
FM3 # Page D5.35

# $Forecast
# origin dev Y VarY P seP CV
# 50 0 7 5.530256 0.01823949 254.51909 34.531073 0.1356718
# 57 0 8 5.090586 0.02089800 164.19172 23.860337 0.1453200
# 64 0 9 4.650915 0.02411166 105.95042 16.551577 0.1562200
# 71 0 10 4.211245 0.02788045 68.38717 11.498964 0.1681450
# 78 0 11 3.771575 0.03220439 44.15371 7.987864 0.1809104
# 85 0 12 3.331904 0.03708347 28.51545 5.542545 0.1943699
# 44 1 6 5.969926 0.01613612 394.64811 50.334287 0.1275422
# 51 1 7 5.530256 0.01823949 254.51909 34.531073 0.1356718
# 58 1 8 5.090586 0.02089800 164.19172 23.860337 0.1453200
# 65 1 9 4.650915 0.02411166 105.95042 16.551577 0.1562200
# 72 1 10 4.211245 0.02788045 68.38717 11.498964 0.1681450
# 79 1 11 3.771575 0.03220439 44.15371 7.987864 0.1809104
# 86 1 12 3.331904 0.03708347 28.51545 5.542545 0.1943699
# 38 2 5 6.409597 0.01458789 612.09698 74.199726 0.1212222
# 45 2 6 5.969926 0.01613612 394.64811 50.334287 0.1275422
# 52 2 7 5.530256 0.01823949 254.51909 34.531073 0.1356718
# 59 2 8 5.090586 0.02089800 164.19172 23.860337 0.1453200
# 66 2 9 4.650915 0.02411166 105.95042 16.551577 0.1562200
# 73 2 10 4.211245 0.02788045 68.38717 11.498964 0.1681450
# 80 2 11 3.771575 0.03220439 44.15371 7.987864 0.1809104
# 87 2 12 3.331904 0.03708347 28.51545 5.542545 0.1943699
# 32 3 4 6.849267 0.01359481 949.62249 111.100293 0.1169942
# 39 3 5 6.409597 0.01458789 612.09698 74.199726 0.1212222
# 46 3 6 5.969926 0.01613612 394.64811 50.334287 0.1275422
# 53 3 7 5.530256 0.01823949 254.51909 34.531073 0.1356718
# 60 3 8 5.090586 0.02089800 164.19172 23.860337 0.1453200
# 67 3 9 4.650915 0.02411166 105.95042 16.551577 0.1562200
# 74 3 10 4.211245 0.02788045 68.38717 11.498964 0.1681450
# 81 3 11 3.771575 0.03220439 44.15371 7.987864 0.1809104
# 88 3 12 3.331904 0.03708347 28.51545 5.542545 0.1943699
# 26 4 3 7.288937 0.01315686 1473.67697 169.593220 0.1150817
# 33 4 4 6.849267 0.01359481 949.62249 111.100293 0.1169942
# 40 4 5 6.409597 0.01458789 612.09698 74.199726 0.1212222
# 47 4 6 5.969926 0.01613612 394.64811 50.334287 0.1275422
# 54 4 7 5.530256 0.01823949 254.51909 34.531073 0.1356718
# 61 4 8 5.090586 0.02089800 164.19172 23.860337 0.1453200
# 68 4 9 4.650915 0.02411166 105.95042 16.551577 0.1562200
# 75 4 10 4.211245 0.02788045 68.38717 11.498964 0.1681450
# 82 4 11 3.771575 0.03220439 44.15371 7.987864 0.1809104
# 89 4 12 3.331904 0.03708347 28.51545 5.542545 0.1943699
# 20 5 2 7.972137 0.01949165 2927.43785 410.706570 0.1402956
# 27 5 3 7.532467 0.01989258 1886.37635 267.385161 0.1417454
# 34 5 4 7.092796 0.02084866 1215.87674 176.480269 0.1451465
# 41 5 5 6.653126 0.02235988 783.91921 117.879486 0.1503720
# 48 5 6 6.213456 0.02442624 505.56105 79.498576 0.1572482
# 55 5 7 5.773785 0.02704774 326.13428 54.001429 0.1655804
# 62 5 8 5.334115 0.03022439 210.44560 36.864508 0.1751736
# 69 5 9 4.894445 0.03395617 135.83253 25.244126 0.1858474
# 76 5 10 4.454774 0.03824310 87.69772 17.315310 0.1974431
# 83 5 11 4.015104 0.04308517 56.63610 11.883707 0.2098257
# 90 5 12 3.575434 0.04848238 36.58634 8.154476 0.2228831
# 14 6 1 8.609387 0.02849728 5561.56881 945.584646 0.1700212
# 21 6 2 8.169717 0.02791130 3581.98421 602.630554 0.1682393
# 28 6 3 7.730046 0.02788045 2307.65333 388.020444 0.1681450
# 35 6 4 7.290376 0.02840476 1487.09261 252.420631 0.1697410
# 42 6 5 6.850706 0.02948420 958.57481 165.817262 0.1729831
# 49 6 6 6.411035 0.03111878 618.06557 109.883703 0.1777865
# 56 6 7 5.971365 0.03330851 398.62418 73.361414 0.1840365
# 63 6 8 5.531694 0.03605338 257.16584 49.273391 0.1916016
# 70 6 9 5.092024 0.03935339 165.95237 33.247674 0.2003447
# 77 6 10 4.652354 0.04320854 107.12090 22.509569 0.2101324
# 84 6 11 4.212683 0.04761883 69.16486 15.274447 0.2208412
# 91 6 12 3.773013 0.05258426 44.67014 10.379573 0.2323604
#
# $Totals
# Total.Reserve Total.SE CV
# 1 33846.53 2545.076 0.07519459
The two models produce very similar results and it shouldn’t be much of a surprise as they are quite similar indeed. The second model has thanks to its smaller number of parameters a proportionally smaller standard error and may hence be the preferred choice.

For comparison here is the output of a Mack chain-ladder model [2] run on the same triangle using the ChainLadder package [3], assuming a tail factor of 1.05 and standard error of 0.02:
library(ChainLadder)
M <- MackChainLadder(incr2cum(tri), est.sigma=“Mack”,
tail=1.05, tail.se=0.02)
M
# MackChainLadder(Triangle = incr2cum(tri), est.sigma = “Mack”,
# tail = 1.05, tail.se = 0.02)
#
# Latest Dev.To.Date Ultimate IBNR Mack.S.E CV(IBNR)
# 1 12,690 0.952 13,324 634 254 0.4010
# 2 12,746 0.927 13,752 1,006 263 0.2611
# 3 12,993 0.882 14,732 1,739 282 0.1623
# 4 11,093 0.804 13,795 2,702 303 0.1120
# 5 10,217 0.701 14,574 4,357 527 0.1210
# 6 9,650 0.547 17,653 8,003 801 0.1001
# 7 6,283 0.289 21,714 15,431 1,032 0.0669
#
# Totals
# Latest: 75,672.00
# Dev: 0.69
# Ultimate: 109,544.16
# IBNR: 33,872.16
# Mack S.E.: 2,563.40
# CV(IBNR): 0.08

The chain ladder method provides similar forecast to the log-incremental regression model, but at the price of many more parameters. Also my estimation of the tail factor and standard error is just my wet finger in the air.

Next week I will discuss sections L - M, which examine how data normalisation and claims inflation can be addressed.

Conclusions

The log-incremental regression model provides an intuitive and elegant stochastic claims reserving model. By the way, at the time of writing Christofides noted that the calculation on a 12Mhz computer with maths co-processor took just less than two minutes(!).

I wonder if the first step of the model selection process could be simplified further. In particular the aspect of finding periods of developments where the decay in claims payments could be regarded linear. Nathan Lemoine posted an interesting article on picewise linear regression using the segmented package [4] . An alternative might use functions of the strucchange package [5].

Using hierarchical or multilevel models as presented by J. Guszcza [6] appears a natural next step for claims reserving. Thankfully Jim provides his R code as well. The Clark LDF model which Jim mentions, has already been implemented by Dan Murphy in R as part of the ChainLadder package.

Lastly I wonder if the plm package [7] for linear models of panel data could be useful as well?

As usual, you find the R code of this post as a gist on Github and feedback and comments are appreciated.

References

[1] Stavros Christofides. Regression models based on log-incremental payments. Claims Reserving Manual. Volume 2 D5. September 1997

[2] Thomas Mack. The standard error of chain ladder reserve estimates: Recursive calculation and inclusion of a tail factor. Astin Bulletin, Vol. 29(2):361 – 266, 1999.

[3] Markus Gesmann, Dan Murphy, and Wayne Zhang. ChainLadder: Mack-, Bootstrap and Munich-chain-ladder methods for insurance claims reserving, 2012. R package version 0.1.5-4.

[4] Vito M.R. Muggeo. segmented: Segmented relationships in regression models with breakpoints/changepoints estimation, 2012. R package version 0.2-9.3.

[5] Achim Zeileis, Friedrich Leisch, Kurt Hornik, Christian Kleiber. strucchange: Testing, Monitoring, and Dating Structural Changes, 2012. R package version 1.4-7.

[6] James Guszcza. Hierarchical Growth Curve Models for Loss Reserving, Fall 2008. Casualty Actuarial Society E-Forum.

[7] Yves Croissant, Giovanni Millo. plm: Linear Models for Panel Data, 2012. R package version 1.3-1.

Session Info

R version 2.15.2 Patched (2013-01-01 r61512)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] grid splines stats graphics grDevices utils datasets methods base

other attached packages:
[1] ChainLadder_0.1.5-4 tweedie_2.1.5 statmod_1.4.16 cplm_0.6-4
lme4_0.999999-0 ggplot2_0.9.3 coda_0.16-1 biglm_0.8 DBI_0.2-5
reshape2_1.2.2 actuar_1.1-5 RUnit_0.4.26 systemfit_1.1-14 lmtest_0.9-30
zoo_1.7-9 car_2.0-15 nnet_7.3-5 MASS_7.3-22 Matrix_1.0-10 lattice_0.20-10
Hmisc_3.10-1 survival_2.37-2

loaded via a namespace (and not attached):
[1] cluster_1.14.3 colorspace_1.2-0 dichromat_1.2-4 digest_0.6.0
gtable_0.1.2 labeling_0.1 minqa_1.2.1 munsell_0.4 nlme_3.1-106
plyr_1.8 proto_0.3-10 RColorBrewer_1.0-5 sandwich_2.2-9 scales_0.2.3
stats4_2.15.2 stringr_0.6.2

Related

comments powered by Disqus