Nothing
### actuar: Actuarial Functions and Heavy Tailed Distributions
###
### Buhlmann-Straub credibility model calculations.
###
### Computation of the between variance estimators has been moved to
### external functions bvar.unbiased() and bvar.iterative() to share
### with hache().
###
### AUTHORS: Vincent Goulet <vincent.goulet@act.ulaval.ca>,
### Sebastien Auclair, Louis-Philippe Pouliot
bstraub <- function(ratios, weights, method = c("unbiased", "iterative"),
tol = sqrt(.Machine$double.eps), maxit = 100, echo = FALSE)
{
## If weights are not specified, use equal weights as in
## Buhlmann's model.
if (missing(weights))
{
if (any(is.na(ratios)))
stop("missing ratios not allowed when weights are not supplied")
weights <- array(1, dim(ratios))
}
## Check other bad arguments.
if (ncol(ratios) < 2L)
stop("there must be at least one node with more than one period of experience")
if (nrow(ratios) < 2L)
stop("there must be more than one node")
if (!identical(which(is.na(ratios)), which(is.na(weights))))
stop(sprintf("missing values are not in the same positions in %s and in %s",
sQuote("weights"), sQuote("ratios")))
if (all(!weights, na.rm = TRUE))
stop("no available data to fit model")
## Individual weighted averages. It could happen that a contract
## has no observations, for example when applying the model on
## claim amounts. In such a situation, we will put the total
## weight of the contract and the weighted average both equal to
## zero. That way, the premium will be equal to the credibility
## weighted average, as it should, but the contract will have no
## contribution in the calculations.
weights.s <- rowSums(weights, na.rm = TRUE)
ratios.w <- ifelse(weights.s > 0, rowSums(weights * ratios, na.rm = TRUE)/weights.s, 0)
## Size of the portfolio.
ncontracts <- sum(weights.s > 0)
ntotal <- sum(!is.na(weights))
## Collective weighted average.
weights.ss <- sum(weights.s)
## Estimation of s^2
s2 <- sum(weights * (ratios - ratios.w)^2, na.rm = TRUE)/(ntotal - ncontracts)
## First estimation of a. Always compute the unbiased estimator.
a <- bvar.unbiased(ratios.w, weights.s, s2, ncontracts)
## Iterative estimation of a. Compute only if
## 1. asked to in argument;
## 2. weights are not all equal (Buhlmann model).
## 3. the unbiased estimator is > 0;
method <- match.arg(method)
if (method == "iterative" &&
diff(range(weights, na.rm = TRUE)) > .Machine$double.eps^0.5)
{
a <- if (a > 0)
bvar.iterative(ratios.w, weights.s, s2, ncontracts, start = a,
tol = tol, maxit = maxit, echo = echo)
else
0
}
## Final credibility factors and estimator of the collective mean.
if (a > 0)
{
cred <- 1/(1 + s2/(weights.s * a))
ratios.zw <- drop(crossprod(cred, ratios.w))/sum(cred)
}
else
{
cred <- numeric(length(weights.s))
ratios.zw <- drop(crossprod(weights.s, ratios.w))/sum(weights.s)
}
structure(list(means = list(ratios.zw, ratios.w),
weights = list(if (a > 0) sum(cred) else weights.ss, weights.s),
unbiased = if (method == "unbiased") c(a, s2),
iterative = if (method == "iterative") c(a, s2),
cred = cred,
nodes = list(nrow(weights))),
class = "bstraub",
model = "Buhlmann-Straub")
}
predict.bstraub <- function(object, levels = NULL, newdata, ...)
structure(object$means[[1L]] + object$cred * (object$means[[2L]] - object$means[[1L]]), ...)
## Alias for the linear Bayes case
predict.bayes <- predict.bstraub
bvar.unbiased <- function(x, w, within, n)
{
w.s <- sum(w)
x.w <- drop(crossprod(w, x))/w.s
w.s * (drop(crossprod(w, (x - x.w)^2)) - (n - 1) * within)/(w.s^2 - sum(w^2))
}
### codetools does not like the way 'a1' is defined in function
### 'bvar.iterative' below. Avoid false positive in R CMD check.
if (getRversion() >= "2.15.1") utils::globalVariables(c("a1"))
bvar.iterative <- function(x, w, within, n, start,
tol = sqrt(.Machine$double.eps), maxit = 100,
echo = FALSE)
{
if (echo)
{
cat("Iteration\tBetween variance estimator\n")
expr <- expression(cat(" ", count, "\t\t ", a1 <- a, fill = TRUE))
}
else
expr <- expression(a1 <- a)
a <- start
count <- 0L
repeat
{
eval(expr)
if (maxit < (count <- count + 1L))
{
warning("maximum number of iterations reached before obtaining convergence")
break
}
cred <- 1/(1 + within/(w * a))
x.z <- drop(crossprod(cred, x))/sum(cred)
a <- drop(crossprod(cred, (x - x.z)^2))/(n - 1)
if (abs((a - a1)/a1) < tol)
break
}
a
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.