Fit latent attrition models for transaction with a formula interface

latentAttrition(formula, data, cov, optimx.args = list(), verbose = TRUE)

Arguments

formula

Formula specifying the model to be fit. See Details.

data

Either a clv.data object or a data.frame containing transaction data on which the model specified in formula will be fit.

cov

Optional data.frame or data.table of covariate data for the lifetime and transaction process. See Details.

optimx.args

Additional arguments to control the optimization which are forwarded to optimx::optimx. If multiple optimization methods are specified, only the result of the last method is further processed.

verbose

Show details about the running of the function.

Details

Formula

A multi-part formula describing how to prepare data and fit the model.

Formula left hand side (LHS) specifies the data preparation which depends on the provided argument data.

  • If data is clvdata: Nothing, LHS is required to be empty.

  • If data is a data.frame: Data preparation using formula special clvdata(time.unit, date.format, split). The formula is required to have a LHS.

Formula right hand side (RHS) specifies the model fitting and follows a multi-part notation.

  • 1st part (required): The model to fit. One of either pnbd, bgnbd, or ggomnbd. Depending on the model additional arguments may be given. See the respective model functions for details.

If the model is fit with covariates, further parts separated by | are required:

  • 2nd part (required): Which covariates to include for the lifetime process, potentially transforming them and adding interactions. The dot ('.') refers to all columns in the data except the identifier variables.

  • 3rd part (required): Which covariates to include for the transaction process, potentially transforming them and adding interactions. The dot ('.') refers to all columns in the data except the identifier variables.

  • 4th part (optional): Formula special regularization(trans=, life=) to specify the lambdas for regularization and constraint(...) to specify parameters to be equal on both processes. Both specials separated by + may be given.

See the example section for illustrations on how to specify the formula parameter.

Covariate Data

For time-invariant covariates the data contains exactly one single row of covariate data for every customer appearing in the transaction data. Requires a column Id of customer identifiers. See SetStaticCovariates for details.

For time-varying covariates the data contains exactly 1 row for every combination of timepoint and customer. Requires a column Id of customer identifiers and a column Cov.Date of dates. For each customer appearing in the transaction data there needs to be covariate data at every timepoint that marks the start of a period as defined by time.unit. It has to range from the start of the estimation sample (timepoint.estimation.start) until the end of the period in which the end of the holdout sample (timepoint.holdout.end) falls. Covariates of class character or factor are converted to k-1 numeric dummies. See SetDynamicCovariates and the the provided dataset apparelDynCov for illustration.

See also

Models for inputs to: pnbd, ggomnbd, bgnbd.

spending to fit spending models with a formula interface

Examples

# \donttest{

data("apparelTrans")
data("apparelStaticCov")

clv.nocov <-
    clvdata(apparelTrans, time.unit="w", date.format="ymd")

# Create static covariate data with 2 covariates
clv.staticcov  <-
  SetStaticCovariates(clv.nocov,
                      data.cov.life  = apparelStaticCov,
                      names.cov.life = c("Gender", "Channel"),
                      data.cov.trans = apparelStaticCov,
                      names.cov.trans = c("Gender", "Channel"))

# Fit pnbd without covariates
latentAttrition(~pnbd(), data=clv.nocov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd(), data = clv.nocov)
#> 
#> Coefficients:
#>       r    alpha        s     beta  
#>  0.7579   4.7419   0.5432  22.1892  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
# Fit bgnbd without covariates
latentAttrition(~bgnbd(), data=clv.nocov)
#> Starting estimation...
#> Estimation finished!
#> BG/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = ~bgnbd(), data = clv.nocov)
#> 
#> Coefficients:
#>      r   alpha       a       b  
#> 0.4367  2.6269  0.3801  3.3979  
#> KKT1: TRUE 
#> KKT2: TRUE 
# Fit ggomnbd without covariates
latentAttrition(~ggomnbd(), data=clv.nocov)
#> Starting estimation...
#> Estimation finished!
#> GGompertz/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = ~ggomnbd(), data = clv.nocov)
#> 
#> Coefficients:
#>       r    alpha        b        s     beta  
#> 0.77456  4.79844  0.02793  0.23295  0.21064  
#> KKT1: TRUE 
#> KKT2: TRUE 

# Fit pnbd with start parameters and correlation
latentAttrition(~pnbd(start.params.model=c(r=1, alpha=10, s=2, beta=8),
                      use.cor=TRUE),
                data=clv.nocov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd(start.params.model = c(r = 1, 
#>     alpha = 10, s = 2, beta = 8), use.cor = TRUE), data = clv.nocov)
#> 
#> Coefficients:
#>               r            alpha                s             beta  
#>        0.757581         4.745652         0.546166        22.394441  
#> Cor(life,trans)  
#>       -0.001608  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     TRUE 

# Fit pnbd with all present covariates
latentAttrition(~pnbd()|.|., clv.staticcov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd() | . | ., data = clv.staticcov)
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>        1.3176        26.8792         0.4049        13.9521         1.2432  
#>  life.Channel   trans.Gender  trans.Channel  
#>       -1.4584         1.3079         0.3760  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Fit pnbd with selected covariates
latentAttrition(~pnbd()|Gender|Channel+Gender, data=clv.staticcov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd() | Gender | Channel + Gender, 
#>     data = clv.staticcov)
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>        1.1258        25.5648         0.4908        40.8459         1.1311  
#> trans.Channel   trans.Gender  
#>        0.4928         1.3153  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Fit pnbd with start parameters for covariates
latentAttrition(~pnbd(start.params.life = c(Gender = 0.6, Channel = 0.4),
                      start.params.trans = c(Gender = 0.6, Channel = 0.4))|.|., data=clv.staticcov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd(start.params.life = c(Gender = 0.6, 
#>     Channel = 0.4), start.params.trans = c(Gender = 0.6, Channel = 0.4)) | 
#>     . | ., data = clv.staticcov)
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>        1.3177        26.8937         0.4055        14.0370         1.2453  
#>  life.Channel   trans.Gender  trans.Channel  
#>       -1.4570         1.3082         0.3761  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Fit pnbd with transformed covariate data
latentAttrition(~pnbd()|Gender|I(log(Channel+2)), data=clv.staticcov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd() | Gender | I(log(Channel + 
#>     2)), data = clv.staticcov)
#> 
#> Coefficients:
#>                         r                      alpha  
#>                    0.7601                    16.5791  
#>                         s                       beta  
#>                    0.6302                    42.8796  
#>               life.Gender  trans.I.log.Channel...2..  
#>                    0.5049                     1.3829  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Fit pnbd with all covs and regularization
latentAttrition(~pnbd()|.|.|regularization(life=3, trans=8), clv.staticcov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd() | . | . | regularization(life = 3, 
#>     trans = 8), data = clv.staticcov)
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>      0.762708       4.812390       0.545289      22.240876       0.001950  
#>  life.Channel   trans.Gender  trans.Channel  
#>     -0.006225       0.006822       0.005044  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  TRUE 

# Fit pnbd with all covs and constraint parameters for Channel
latentAttrition(~pnbd()|.|.|constraint(Channel), clv.staticcov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = ~pnbd() | . | . | constraint(Channel), 
#>     data = clv.staticcov)
#> 
#> Coefficients:
#>              r           alpha               s            beta     life.Gender  
#>         1.1228         22.7635          0.4395         37.8905          1.1426  
#>   trans.Gender  constr.Channel  
#>         1.3174          0.2596  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     TRUE 
#> Regularization:  FALSE 

# Fit pnbd on given data.frame, no split
latentAttrition(data()~pnbd(), data=apparelTrans)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = data() ~ pnbd(), data = apparelTrans)
#> 
#> Coefficients:
#>       r    alpha        s     beta  
#>  0.7579   4.7419   0.5432  22.1892  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 

# Fit pnbd, split data after 39 periods
latentAttrition(data(split=39)~pnbd(), data=apparelTrans)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = data(split = 39) ~ pnbd(), data = apparelTrans)
#> 
#> Coefficients:
#>       r    alpha        s     beta  
#>  0.7844   5.3718   0.4067  14.2884  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
# Same but also give date format and period definition
latentAttrition(data(split=39, format=ymd, unit=w)~pnbd(), data=apparelTrans)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> latentAttrition(formula = data(split = 39, format = ymd, unit = w) ~ 
#>     pnbd(), data = apparelTrans)
#> 
#> Coefficients:
#>       r    alpha        s     beta  
#>  0.7844   5.3718   0.4067  14.2884  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 

# Fit pnbd on given data.frames w/ all covariates
latentAttrition(data()~pnbd()|.|., data=apparelTrans, cov=apparelStaticCov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = data() ~ pnbd() | . | ., data = apparelTrans, 
#>     cov = apparelStaticCov)
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>        1.3176        26.8792         0.4049        13.9521         1.2432  
#>  life.Channel   trans.Gender  trans.Channel  
#>       -1.4584         1.3079         0.3760  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Fit pnbd on given data.frames w/ selected covariates
latentAttrition(data()~pnbd()|Channel+Gender|Gender,
                data=apparelTrans, cov=apparelStaticCov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> latentAttrition(formula = data() ~ pnbd() | Channel + Gender | 
#>     Gender, data = apparelTrans, cov = apparelStaticCov)
#> 
#> Coefficients:
#>            r         alpha             s          beta  life.Channel  
#>       1.3315       22.1327        0.3738       10.4036       -1.6995  
#>  life.Gender  trans.Gender  
#>       1.2700        1.3075  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# }