Repository navigation
CALM
calm() (R) / CALM() (Python) combines the parameters of regressions of the first variable of the data on subsets of the other variables. The models are weighted by an information criterion. A variable missing from a model has a zero parameter in it, so the combined parameter is shrunk towards zero according to the importance of the variable.
calm(data, ic=c("AICc","AIC","BIC","BICc"), bruteforce=FALSE, silent=TRUE,
formula=NULL, subset=NULL,
distribution=c("dnorm","dlaplace","ds","dgnorm","dlogis","dt","dalaplace",
"dlnorm","dllaplace","dls","dlgnorm","dbcnorm",
"dinvgauss","dgamma","dexp",
"dfnorm","drectnorm",
"dpois","dnbinom",
"dbeta","dlogitnorm",
"plogis","pnorm"),
parallel=FALSE, ...)def CALM(
data: dict | DataFrame,
ic: Literal["AICc", "AIC", "BIC", "BICc"] = "AICc",
bruteforce: bool = False,
silent: bool = True,
distribution: str = "dnorm",
**kwargs,
) -> CALMResult | ALM: ...-
Candidate models.
-
bruteforce=TRUE: all 2^k models of the k regressors, including the intercept-only one. With more variables than observations, the function switches tobruteforce=FALSEwith a warning; with more than 14 variables it warns that this takes long. -
bruteforce=FALSE(default): stepwise selects the best model first. If it contains the intercept only, that model is returned (analmobject in R, anALMin Python). If it has fewer than 14 parameters, all the subsets of its variables are combined (bruteforce on the selected variables). Otherwise the candidates are the best model, the best model plus each excluded variable, and the best model minus each included variable.
-
-
Weights.
w_i = exp(-0.5 (IC_i - IC_min)) / Σ_j exp(-0.5 (IC_j - IC_min)). - Combination. The parameters are averaged with these weights, with zeros for the variables a model does not include.
- Importance. The importance of a variable is the sum of the weights of the models that include it. The number of parameters of the combined model is the sum of the importances plus one (the scale).
Both languages take the data with the response in the first column, not a list of fitted models.
| Parameter | R | Python | Default | Description |
|---|---|---|---|---|
| Data | data |
data |
— | Data frame / dict / DataFrame: response first, regressors after. Python drops the rows with missing values and expands non-numeric columns into dummies. |
| Information criterion | ic |
ic |
"AICc" |
"AICc", "AIC", "BIC", "BICc". |
| Brute force | bruteforce |
bruteforce |
FALSE / False
|
See How it works. |
| Silent | silent |
silent |
TRUE / True
|
FALSE prints the progress. |
| Formula | formula |
— | NULL |
R only: combine over the variables of the formula, after their transformations. |
| Subset | subset |
— | NULL |
R only: the observations to use. |
| Distribution | distribution |
distribution |
"dnorm" |
Passed to alm() / ALM. R accepts the 23 in the signature; Python also accepts dbinom, dgeom and dchisq. With "dnorm", the models are estimated by least squares. |
| Parallel | parallel |
— | FALSE |
R only: fit the models in parallel (foreach and doMC or doParallel). |
| Other | ... |
**kwargs |
— | Passed to alm() / ALM. |
R returns an object of class c("calm", "alm", "greybox"); Python a CALMResult, or the ALM of stepwise when only the intercept is selected.
| Field | R | Python | Description |
|---|---|---|---|
| Parameters |
coefficients, coef()
|
coefficients |
Combined parameters, intercept first. Python's coef omits the intercept, which is in intercept_. |
| Parameter names | names(coef()) |
coefficient_names |
|
| Covariance matrix | vcov |
vcov() |
Combined covariance matrix. |
| Fitted values | fitted |
fitted |
|
| Residuals | residuals |
residuals |
|
| Location / scale |
mu, scale
|
mu, scale
|
|
| Extra parameter | other |
other_ |
Combined shape, alpha, lambdaBC, nu or size. |
| Distribution | distribution |
distribution, distribution_
|
|
| Loss | loss |
loss_, loss_value
|
Always "likelihood". |
| Log-likelihood | logLik |
log_lik, loglik
|
Combined log-likelihood. |
| Information criterion |
IC, ICType
|
IC, IC_type; aic, aicc, bic, bicc
|
|
| Degrees of freedom |
df, df.residual, rank
|
df_model, df_residual, df_residual_, rank_
|
|
| Importance | importance |
importance |
|
| Combination | combination |
combination, combination_col_names, combination_row_names, weights
|
One row per model: the included variables (0/1), the IC weight and the IC. Python also has the weights as a vector. |
| Data |
data, call, xlevels
|
data, actuals, formula, x_variables, y_variable
|
|
| Time elapsed | timeElapsed |
time_elapsed |
| Method | R | Python |
|---|---|---|
| Summary | summary(model, level=0.95) |
model.summary(level=0.95) |
| Prediction | predict(model, newdata, interval, level, side) |
model.predict(X, interval, level, side): a PredictionResult (see ALM) |
| Confidence intervals | confint(model, parm, level=0.95) |
model.confint(parm, level=0.95) |
| Covariance matrix | vcov(model) |
model.vcov() |
| Number of parameters | nparam(model) |
model.nparam, model.n_param
|
| Score | — |
model.score(X, y, metric): "likelihood", "MSE", "MAE", "R2"
|
The other alm methods (plots, rstandard(), …) apply to R's calm object through its class.
The data are created in R and read by Python from the same file, so both see identical inputs.
library(greybox)
set.seed(42)
x1 <- rnorm(100); x2 <- rnorm(100); x3 <- rnorm(100)
y <- 1 + 2*x1 + 0.5*x2 + 0.2*x3 + rnorm(100)
data <- data.frame(y=y, x1=x1, x2=x2, x3=x3)
write.csv(data, "calm.csv", row.names=FALSE)
result <- calm(data, ic="AICc", bruteforce=TRUE)
summary(result)
# The AICc combined model
# Response variable: y
# Distribution used in the estimation: Normal
# Coefficients:
# Estimate Std. Error Importance Lower 2.5% Upper 97.5%
# (Intercept) 1.0316 0.0671 1.0000 0.8983 1.1649 *
# x1 2.0500 0.0655 1.0000 1.9200 2.1800 *
# x2 0.5134 0.0746 1.0000 0.3654 0.6615 *
# x3 0.1144 0.0796 0.6797 -0.0435 0.2724
#
# Error standard deviation: 0.8916
# Sample size: 100
# Number of estimated parameters: 4.6796
# Number of degrees of freedom: 95.3204
# Approximate combined information criteria:
# AIC AICc BIC BICc
# 266.1985 266.7621 278.3898 279.6875
head(result$combination, 3)
# x1 x2 x3 IC weights ICs
# Model1 0 0 0 1.167341e-42 456.4178
# Model2 1 0 0 3.649225e-06 288.3521
# Model3 0 1 0 6.041710e-42 453.1299
new_data <- data.frame(x1=c(0, 1, 2), x2=c(0, 0, 0), x3=c(0, 0, 0))
predict(result, newdata=new_data, interval="prediction", level=0.95)
# Mean Lower bound (2.5%) Upper bound (97.5%)
# [1,] 1.031598 -0.7433639 2.806560
# [2,] 3.081600 1.3022147 4.860985
# [3,] 5.131602 3.3383525 6.924852import pandas as pd
from greybox import CALM
data = pd.read_csv("calm.csv")
result = CALM(data, ic="AICc", bruteforce=True)
print(result.summary())
# The AICc combined model
# Response variable: y
# Distribution used in the estimation: Normal
# Coefficients:
# Estimate Std. Error Importance Lower 2.5% Upper 97.5%
# (Intercept) 1.0316 0.0671 1.000 0.8983 1.1649 *
# x1 2.0500 0.0655 1.000 1.9200 2.1800 *
# x2 0.5134 0.0746 1.000 0.3654 0.6615 *
# x3 0.1144 0.0796 0.680 -0.0435 0.2724
#
# Error standard deviation: 0.8916
# Sample size: 100
# Number of estimated parameters: 4.680
# Number of degrees of freedom: 95.320
# Approximate combined information criteria:
# AIC AICc BIC BICc
# 266.1985 266.7621 278.3898 279.6875
result.importance # array([1., 1., 1., 0.6797])
result.weights # IC weight of each of the 8 models
new_data = pd.DataFrame({"x1": [0, 1, 2], "x2": [0, 0, 0], "x3": [0, 0, 0]})
result.predict(new_data, interval="prediction", level=0.95)
# mean lower upper
# 0 1.031598 -0.743364 2.806560
# 1 3.081600 1.302215 4.860985
# 2 5.131602 3.338352 6.924852predict() takes the new regressors by name (a DataFrame or dict), or a design matrix, e.g. the one from formula() (its (Intercept) column is ignored, as R's model.frame() does):
from greybox import formula
X = formula("y ~ x1 + x2 + x3", new_data.assign(y=0.0), return_type="X")
result.predict(X, interval="prediction", level=0.95) # the same three rows as aboveWith the default bruteforce=FALSE, stepwise selects all three regressors here, so both languages return the same combination as above.
- Burnham, K.P. and Anderson, D.R. (2002). Model Selection and Multimodel Inference. Springer.
- Svetunkov, I. (2023). Statistics for Business Analytics. https://openforecast.org/sba/