Fits Pareto/NBD models on transactional data with and without covariates.

# S4 method for class 'clv.data'
pnbd(
  clv.data,
  start.params.model = c(),
  use.cor = FALSE,
  start.param.cor = c(),
  optimx.args = list(),
  verbose = TRUE,
  ...
)

# S4 method for class 'clv.data.static.covariates'
pnbd(
  clv.data,
  start.params.model = c(),
  use.cor = FALSE,
  start.param.cor = c(),
  optimx.args = list(),
  verbose = TRUE,
  names.cov.life = c(),
  names.cov.trans = c(),
  start.params.life = c(),
  start.params.trans = c(),
  names.cov.constr = c(),
  start.params.constr = c(),
  reg.lambdas = c(),
  ...
)

# S4 method for class 'clv.data.dynamic.covariates'
pnbd(
  clv.data,
  start.params.model = c(),
  use.cor = FALSE,
  start.param.cor = c(),
  optimx.args = list(),
  verbose = TRUE,
  names.cov.life = c(),
  names.cov.trans = c(),
  start.params.life = c(),
  start.params.trans = c(),
  names.cov.constr = c(),
  start.params.constr = c(),
  reg.lambdas = c(),
  ...
)

Arguments

clv.data

The data object on which the model is fitted.

start.params.model

Named start parameters containing the optimization start parameters for the model without covariates.

use.cor

Whether the correlation between the transaction and lifetime process should be estimated.

start.param.cor

Start parameter for the optimization of the correlation.

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.

...

Ignored

names.cov.life

Which of the set Lifetime covariates should be used. Missing parameter indicates all covariates shall be used.

names.cov.trans

Which of the set Transaction covariates should be used. Missing parameter indicates all covariates shall be used.

start.params.life

Named start parameters containing the optimization start parameters for all lifetime covariates.

start.params.trans

Named start parameters containing the optimization start parameters for all transaction covariates.

names.cov.constr

Which covariates should be forced to use the same parameters for the lifetime and transaction process. The covariates need to be present as both, lifetime and transaction covariates.

start.params.constr

Named start parameters containing the optimization start parameters for the constraint covariates.

reg.lambdas

Named lambda parameters used for the L2 regularization of the lifetime and the transaction covariate parameters. Lambdas have to be >= 0.

Value

Depending on the data object on which the model was fit, pnbd returns either an object of class clv.pnbd, clv.pnbd.static.cov, or clv.pnbd.dynamic.cov.

The function summary can be used to obtain and print a summary of the results. The generic accessor functions coefficients, vcov, fitted, logLik, AIC, BIC, and nobs are available.

Details

Model parameters for the Pareto/NBD model are r, alpha, s, and beta.
s: shape parameter of the Gamma distribution for the lifetime process. The smaller s, the stronger the heterogeneity of customer lifetimes.
beta: rate parameter for the Gamma distribution for the lifetime process.
r: shape parameter of the Gamma distribution of the purchase process. The smaller r, the stronger the heterogeneity of the purchase process.
alpha: rate parameter of the Gamma distribution of the purchase process.

Based on these parameters, the average purchase rate while customers are active is r/alpha and the average dropout rate is s/beta.

Ideally, the starting parameters for r and s represent your best guess concerning the heterogeneity of customers in their buy and die rate. If covariates are included into the model additionally parameters for the covariates affecting the attrition and the purchase process are part of the model.

If no start parameters are given, r=0.5, alpha=15, s=0.5, beta=10 is used for all model parameters and 0.1 for covariate parameters. The model start parameters are required to be > 0.

The Pareto/NBD model

The Pareto/NBD is the first model addressing the issue of modeling customer purchases and attrition simultaneously for non-contractual settings. The model uses a Pareto distribution, a combination of an Exponential and a Gamma distribution, to explicitly model customers' (unobserved) attrition behavior in addition to customers' purchase process.
In general, the Pareto/NBD model consist of two parts. A first process models the purchase behavior of customers as long as the customers are active. A second process models customers' attrition. Customers live (and buy) for a certain unknown time until they become inactive and "die". Customer attrition is unobserved. Inactive customers may not be reactivated. For technical details we refer to the original paper by Schmittlein, Morrison and Colombo (1987) and the detailed technical note of Fader and Hardie (2005).

Pareto/NBD model with static covariates

The standard Pareto/NBD model captures heterogeneity was solely using Gamma distributions. However, often exogenous knowledge, such as for example customer demographics, is available. The supplementary knowledge may explain part of the heterogeneity among the customers and therefore increase the predictive accuracy of the model. In addition, we can rely on these parameter estimates for inference, i.e. identify and quantify effects of contextual factors on the two underlying purchase and attrition processes. For technical details we refer to the technical note by Fader and Hardie (2007).

Pareto/NBD model with dynamic covariates

In many real-world applications customer purchase and attrition behavior may be influenced by covariates that vary over time. In consequence, the timing of a purchase and the corresponding value of at covariate a that time becomes relevant. Time-varying covariates can affect customer on aggregated level as well as on an individual level: In the first case, all customers are affected simultaneously, in the latter case a covariate is only relevant for a particular customer. For technical details we refer to the paper by Bachmann, Meierer and Näf (2020).

Note

The Pareto/NBD model with dynamic covariates can currently not be fit with data that has a temporal resolution of less than one day (data that was built with time unit hours).

References

Schmittlein DC, Morrison DG, Colombo R (1987). “Counting Your Customers: Who-Are They and What Will They Do Next?” Management Science, 33(1), 1-24.

Bachmann P, Meierer M, Naef, J (2021). “The Role of Time-Varying Contextual Factors in Latent Attrition Models for Customer Base Analysis” Marketing Science 40(4). 783-809.

Fader PS, Hardie BGS (2005). “A Note on Deriving the Pareto/NBD Model and Related Expressions.” URL http://www.brucehardie.com/notes/009/pareto_nbd_derivations_2005-11-05.pdf.

Fader PS, Hardie BGS (2007). “Incorporating time-invariant covariates into the Pareto/NBD and BG/NBD models.” URL http://www.brucehardie.com/notes/019/time_invariant_covariates.pdf.

Fader PS, Hardie BGS (2020). “Deriving an Expression for P(X(t)=x) Under the Pareto/NBD Model.” URL https://www.brucehardie.com/notes/012/pareto_NBD_pmf_derivation_rev.pdf

See also

clvdata to create a clv data object, SetStaticCovariates to add static covariates to an existing clv data object.

gg to fit customer's average spending per transaction with the Gamma-Gamma model

predict to predict expected transactions, probability of being alive, and customer lifetime value for every customer

plot to plot the unconditional expectation as predicted by the fitted model

pmf for the probability to make exactly x transactions in the estimation period, given by the probability mass function (PMF).

newcustomer to predict the expected number of transactions for an average new customer.

The generic functions vcov, summary, fitted.

SetDynamicCovariates to add dynamic covariates on which the pnbd model can be fit.

Examples

# \donttest{
data("apparelTrans")
clv.data.apparel <- clvdata(apparelTrans, date.format = "ymd",
                            time.unit = "w", estimation.split = 52)

# Fit standard pnbd model
pnbd(clv.data.apparel)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.apparel)
#> 
#> Coefficients:
#>       r    alpha        s     beta  
#>  1.3080  46.3352   0.4794  70.2292  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 

# Give initial guesses for the model parameters
pnbd(clv.data.apparel,
     start.params.model = c(r=0.5, alpha=15, s=0.5, beta=10))
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.apparel, start.params.model = c(r = 0.5, 
#>     alpha = 15, s = 0.5, beta = 10))
#> 
#> Coefficients:
#>       r    alpha        s     beta  
#>  1.3080  46.3352   0.4794  70.2292  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 


# pass additional parameters to the optimizer (optimx)
#    Use Nelder-Mead as optimization method and print
#    detailed information about the optimization process
apparel.pnbd <- pnbd(clv.data.apparel,
                     optimx.args = list(method="Nelder-Mead",
                                        control=list(trace=6)))
#> Starting estimation...
#> fn is  fn1 
#> Looking for method =  Nelder-Mead 
#> Methods to be used:[1] "Nelder-Mead"
#> optcfg:$fname
#> [1] "fn1"
#> 
#> $npar
#> [1] 4
#> 
#> $ctrl
#> $ctrl$follow.on
#> [1] FALSE
#> 
#> $ctrl$save.failures
#> [1] TRUE
#> 
#> $ctrl$trace
#> [1] 6
#> 
#> $ctrl$kkt
#> [1] TRUE
#> 
#> $ctrl$all.methods
#> [1] FALSE
#> 
#> $ctrl$starttests
#> [1] FALSE
#> 
#> $ctrl$maximize
#> [1] FALSE
#> 
#> $ctrl$dowarn
#> [1] TRUE
#> 
#> $ctrl$usenumDeriv
#> [1] FALSE
#> 
#> $ctrl$kkttol
#> [1] 0.001
#> 
#> $ctrl$kkt2tol
#> [1] 1e-06
#> 
#> $ctrl$badval
#> [1] 8.988466e+307
#> 
#> $ctrl$scaletol
#> [1] 3
#> 
#> $ctrl$have.bounds
#> [1] FALSE
#> 
#> 
#> $usenumDeriv
#> [1] FALSE
#> 
#> $ufn
#> function (par) 
#> fn(par, ...)
#> <bytecode: 0x11dce02d8>
#> <environment: 0x12952b610>
#> 
#> $have.bounds
#> [1] FALSE
#> 
#> $method
#> [1] "Nelder-Mead"
#> 
#> Method:  Nelder-Mead 
#>   Nelder-Mead direct search function minimizer
#> function value for initial parameters = 3577.490724
#>   Scaled convergence tolerance is 5.33088e-05
#> Stepsize computed as 0.270805
#> BUILD              5 3618.102926 3557.499818
#> EXTENSION          7 3588.766454 3515.206187
#> LO-REDUCTION       9 3577.490724 3515.206187
#> LO-REDUCTION      11 3560.629019 3515.206187
#> LO-REDUCTION      13 3557.499818 3515.206187
#> EXTENSION         15 3538.949426 3502.124657
#> EXTENSION         17 3522.301702 3491.315153
#> LO-REDUCTION      19 3520.130144 3491.315153
#> LO-REDUCTION      21 3515.206187 3491.315153
#> EXTENSION         23 3502.124657 3487.029141
#> LO-REDUCTION      25 3494.722953 3487.029141
#> REFLECTION        27 3493.410647 3485.989378
#> LO-REDUCTION      29 3491.315153 3485.989378
#> HI-REDUCTION      31 3487.841273 3485.989378
#> HI-REDUCTION      33 3487.231847 3485.989378
#> HI-REDUCTION      35 3487.029141 3485.989378
#> EXTENSION         37 3486.635771 3484.509002
#> LO-REDUCTION      39 3486.256159 3484.509002
#> LO-REDUCTION      41 3486.135308 3484.509002
#> LO-REDUCTION      43 3485.989378 3484.509002
#> LO-REDUCTION      45 3485.602665 3484.509002
#> REFLECTION        47 3485.131743 3484.022296
#> LO-REDUCTION      49 3485.094658 3484.022296
#> REFLECTION        51 3484.734465 3483.944565
#> EXTENSION         53 3484.509002 3483.051738
#> HI-REDUCTION      55 3484.390375 3483.051738
#> EXTENSION         57 3484.022296 3482.672127
#> LO-REDUCTION      59 3483.944565 3482.672127
#> LO-REDUCTION      61 3483.885871 3482.672127
#> HI-REDUCTION      63 3483.183497 3482.672127
#> LO-REDUCTION      65 3483.051738 3482.605147
#> LO-REDUCTION      67 3482.869919 3482.605147
#> HI-REDUCTION      69 3482.678491 3482.605147
#> LO-REDUCTION      71 3482.677209 3482.586838
#> HI-REDUCTION      73 3482.672127 3482.586838
#> LO-REDUCTION      75 3482.626645 3482.586838
#> HI-REDUCTION      77 3482.606469 3482.584373
#> REFLECTION        79 3482.605147 3482.570883
#> HI-REDUCTION      81 3482.591298 3482.570883
#> HI-REDUCTION      83 3482.586838 3482.570883
#> REFLECTION        85 3482.584373 3482.562448
#> HI-REDUCTION      87 3482.578339 3482.562448
#> LO-REDUCTION      89 3482.574087 3482.562448
#> EXTENSION         91 3482.570883 3482.546872
#> HI-REDUCTION      93 3482.569656 3482.546872
#> LO-REDUCTION      95 3482.564846 3482.546872
#> REFLECTION        97 3482.562448 3482.545725
#> HI-REDUCTION      99 3482.559624 3482.545725
#> EXTENSION        101 3482.552132 3482.529225
#> LO-REDUCTION     103 3482.548141 3482.529225
#> LO-REDUCTION     105 3482.546872 3482.529225
#> EXTENSION        107 3482.545725 3482.524888
#> REFLECTION       109 3482.539489 3482.523911
#> EXTENSION        111 3482.532682 3482.508336
#> LO-REDUCTION     113 3482.529225 3482.508336
#> LO-REDUCTION     115 3482.524888 3482.508336
#> LO-REDUCTION     117 3482.523911 3482.508336
#> LO-REDUCTION     119 3482.518928 3482.508336
#> LO-REDUCTION     121 3482.518699 3482.508336
#> EXTENSION        123 3482.516119 3482.501974
#> EXTENSION        125 3482.511347 3482.491345
#> LO-REDUCTION     127 3482.509855 3482.491345
#> EXTENSION        129 3482.508336 3482.479883
#> LO-REDUCTION     131 3482.501974 3482.479883
#> EXTENSION        133 3482.491895 3482.451710
#> LO-REDUCTION     135 3482.491345 3482.451710
#> LO-REDUCTION     137 3482.485097 3482.451710
#> EXTENSION        139 3482.479883 3482.426861
#> LO-REDUCTION     141 3482.467825 3482.426861
#> EXTENSION        143 3482.464402 3482.392452
#> EXTENSION        145 3482.451710 3482.362389
#> EXTENSION        147 3482.434120 3482.326554
#> LO-REDUCTION     149 3482.426861 3482.326554
#> EXTENSION        151 3482.392452 3482.234085
#> LO-REDUCTION     153 3482.362389 3482.234085
#> LO-REDUCTION     155 3482.333002 3482.234085
#> LO-REDUCTION     157 3482.326554 3482.234085
#> LO-REDUCTION     159 3482.270427 3482.228485
#> EXTENSION        161 3482.249626 3482.187145
#> LO-REDUCTION     163 3482.243048 3482.187145
#> EXTENSION        165 3482.234085 3482.143757
#> LO-REDUCTION     167 3482.228485 3482.143757
#> EXTENSION        169 3482.187150 3482.076034
#> LO-REDUCTION     171 3482.187145 3482.076034
#> EXTENSION        173 3482.168268 3482.051621
#> LO-REDUCTION     175 3482.143757 3482.051621
#> REFLECTION       177 3482.100647 3482.024184
#> REFLECTION       179 3482.076034 3482.022426
#> HI-REDUCTION     181 3482.051696 3482.022426
#> REFLECTION       183 3482.051621 3481.999804
#> LO-REDUCTION     185 3482.030557 3481.999804
#> LO-REDUCTION     187 3482.024184 3481.999804
#> LO-REDUCTION     189 3482.022426 3481.999429
#> HI-REDUCTION     191 3482.014260 3481.999429
#> LO-REDUCTION     193 3482.005517 3481.998573
#> LO-REDUCTION     195 3482.005327 3481.998573
#> REFLECTION       197 3481.999804 3481.992755
#> HI-REDUCTION     199 3481.999429 3481.992755
#> LO-REDUCTION     201 3481.999171 3481.992755
#> REFLECTION       203 3481.998573 3481.992659
#> HI-REDUCTION     205 3481.996090 3481.992659
#> EXTENSION        207 3481.995202 3481.989353
#> EXTENSION        209 3481.994861 3481.987456
#> LO-REDUCTION     211 3481.992755 3481.987456
#> REFLECTION       213 3481.992659 3481.986721
#> EXTENSION        215 3481.989353 3481.980449
#> LO-REDUCTION     217 3481.987760 3481.980449
#> LO-REDUCTION     219 3481.987456 3481.980449
#> LO-REDUCTION     221 3481.986721 3481.980449
#> EXTENSION        223 3481.984187 3481.978655
#> LO-REDUCTION     225 3481.983425 3481.978655
#> LO-REDUCTION     227 3481.981552 3481.978655
#> REFLECTION       229 3481.980449 3481.978351
#> LO-REDUCTION     231 3481.979349 3481.978351
#> LO-REDUCTION     233 3481.978943 3481.978351
#> HI-REDUCTION     235 3481.978704 3481.978351
#> REFLECTION       237 3481.978655 3481.978253
#> LO-REDUCTION     239 3481.978629 3481.978253
#> LO-REDUCTION     241 3481.978532 3481.978253
#> HI-REDUCTION     243 3481.978351 3481.978253
#> HI-REDUCTION     245 3481.978345 3481.978253
#> LO-REDUCTION     247 3481.978321 3481.978252
#> LO-REDUCTION     249 3481.978295 3481.978236
#> Exiting from Nelder Mead minimizer
#>     251 function evaluations used
#> Post processing for method  Nelder-Mead 
#> Successful convergence! 
#> Compute Hessian approximation at finish of  Nelder-Mead 
#> Compute gradient approximation at finish of  Nelder-Mead 
#> Save results from method  Nelder-Mead 
#> $par
#>      log.r  log.alpha      log.s   log.beta 
#>  0.2678451  3.8353761 -0.7332306  4.2554487 
#> 
#> $value
#> [1] 3481.978
#> 
#> $message
#> NULL
#> 
#> $convcode
#> [1] 0
#> 
#> $fevals
#> function 
#>      251 
#> 
#> $gevals
#> gradient 
#>       NA 
#> 
#> $nitns
#> [1] NA
#> 
#> $kkt1
#> [1] TRUE
#> 
#> $kkt2
#> [1] TRUE
#> 
#> $xtimes
#> user.self 
#>     0.047 
#> 
#> Assemble the answers
#> Estimation finished!

# estimated coefs
coef(apparel.pnbd)
#>          r      alpha          s       beta 
#>  1.3071447 46.3108420  0.4803547 70.4884348 

# summary of the fitted model
summary(apparel.pnbd)
#> Pareto/NBD Standard  Model 
#> 
#> Call:
#> pnbd(clv.data = clv.data.apparel, optimx.args = list(method = "Nelder-Mead", 
#>     control = list(trace = 6)))
#> 
#> Fitting period:                               
#> Estimation start  2005-01-02   
#> Estimation end    2006-01-01   
#> Estimation length 52.0000 Weeks
#> 
#> Coefficients:
#>       Estimate Std. Error z-val Pr(>|z|)    
#> r       1.3071     0.2123 6.157 7.42e-10 ***
#> alpha  46.3108     7.5368 6.145 8.01e-10 ***
#> s       0.4804     1.0819 0.444    0.657    
#> beta   70.4884   203.3985 0.347    0.729    
#> ---
#> Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#> 
#> Optimization info:                  
#> LL     -3481.9782 
#> AIC    6971.9565  
#> BIC    6989.5442  
#> KKT 1  TRUE       
#> KKT 2  TRUE       
#> fevals 251.0000   
#> Method Nelder-Mead
#> 
#> Used Options:                 
#> Correlation FALSE

# predict CLV etc for holdout period
predict(apparel.pnbd)
#> Predicting from 2006-01-02 until (incl.) 2010-12-20 (259.14 Weeks).
#> Estimating gg model to predict spending...
#> Starting estimation...
#> Estimation finished!
#> Key: <Id>
#>          Id period.first period.last period.length actual.x
#>      <char>       <Date>      <Date>         <num>    <int>
#>   1:      1   2006-01-02  2010-12-20      259.1429        5
#>   2:     10   2006-01-02  2010-12-20      259.1429        2
#>   3:    100   2006-01-02  2010-12-20      259.1429        9
#>   4:    101   2006-01-02  2010-12-20      259.1429        0
#>   5:    102   2006-01-02  2010-12-20      259.1429        0
#>  ---                                                       
#> 596:     95   2006-01-02  2010-12-20      259.1429        5
#> 597:     96   2006-01-02  2010-12-20      259.1429        3
#> 598:     97   2006-01-02  2010-12-20      259.1429        0
#> 599:     98   2006-01-02  2010-12-20      259.1429        0
#> 600:     99   2006-01-02  2010-12-20      259.1429        1
#>      actual.total.spending    PAlive      CET       DERT
#>                      <num>     <num>    <num>      <num>
#>   1:                524.10 0.9163171 4.080260 0.21731960
#>   2:                 63.31 0.8411806 3.745685 0.19949974
#>   3:                333.35 0.6578365 1.659621 0.08839341
#>   4:                  0.00 0.8946531 3.983793 0.21218163
#>   5:                  0.00 0.6578365 1.659621 0.08839341
#>  ---                                                    
#> 596:                113.80 0.9400910 4.186123 0.22295799
#> 597:                253.61 0.6578365 1.659621 0.08839341
#> 598:                  0.00 0.6578365 1.659621 0.08839341
#> 599:                  0.00 0.9655447 4.299465 0.22899475
#> 600:                 13.99 0.9384998 5.990383 0.31905509
#>      predicted.mean.spending predicted.total.spending predicted.CLV
#>                        <num>                    <num>         <num>
#>   1:                63.77959                260.23732     13.860556
#>   2:                38.10316                142.72242      7.601570
#>   3:                37.12434                 61.61231      3.281547
#>   4:                33.08404                131.79995      7.019826
#>   5:                37.12434                 61.61231      3.281547
#>  ---                                                               
#> 596:                28.29614                118.45113      6.308851
#> 597:                37.12434                 61.61231      3.281547
#> 598:                37.12434                 61.61231      3.281547
#> 599:                34.87739                149.95411      7.986738
#> 600:                16.11315                 96.52392      5.140981

# predict CLV etc for the next 15 periods
predict(apparel.pnbd, prediction.end = 15)
#> Predicting from 2006-01-02 until (incl.) 2006-04-16 (15 Weeks).
#> Estimating gg model to predict spending...
#> Starting estimation...
#> Estimation finished!
#> Key: <Id>
#>          Id period.first period.last period.length actual.x
#>      <char>       <Date>      <Date>         <int>    <int>
#>   1:      1   2006-01-02  2006-04-16            15        2
#>   2:     10   2006-01-02  2006-04-16            15        0
#>   3:    100   2006-01-02  2006-04-16            15        0
#>   4:    101   2006-01-02  2006-04-16            15        0
#>   5:    102   2006-01-02  2006-04-16            15        0
#>  ---                                                       
#> 596:     95   2006-01-02  2006-04-16            15        0
#> 597:     96   2006-01-02  2006-04-16            15        0
#> 598:     97   2006-01-02  2006-04-16            15        0
#> 599:     98   2006-01-02  2006-04-16            15        0
#> 600:     99   2006-01-02  2006-04-16            15        0
#>      actual.total.spending    PAlive       CET       DERT
#>                      <num>     <num>     <num>      <num>
#>   1:                 217.5 0.9163171 0.3136059 0.21731960
#>   2:                   0.0 0.8411806 0.2878907 0.19949974
#>   3:                   0.0 0.6578365 0.1275573 0.08839341
#>   4:                   0.0 0.8946531 0.3061915 0.21218163
#>   5:                   0.0 0.6578365 0.1275573 0.08839341
#>  ---                                                     
#> 596:                   0.0 0.9400910 0.3217425 0.22295799
#> 597:                   0.0 0.6578365 0.1275573 0.08839341
#> 598:                   0.0 0.6578365 0.1275573 0.08839341
#> 599:                   0.0 0.9655447 0.3304539 0.22899475
#> 600:                   0.0 0.9384998 0.4604166 0.31905509
#>      predicted.mean.spending predicted.total.spending predicted.CLV
#>                        <num>                    <num>         <num>
#>   1:                63.77959                20.001658     13.860556
#>   2:                38.10316                10.969545      7.601570
#>   3:                37.12434                 4.735479      3.281547
#>   4:                33.08404                10.130052      7.019826
#>   5:                37.12434                 4.735479      3.281547
#>  ---                                                               
#> 596:                28.29614                 9.104071      6.308851
#> 597:                37.12434                 4.735479      3.281547
#> 598:                37.12434                 4.735479      3.281547
#> 599:                34.87739                11.525368      7.986738
#> 600:                16.11315                 7.418761      5.140981
# }
# \donttest{
# Estimate correlation as well
pnbd(clv.data.apparel, use.cor = TRUE)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD Standard Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.apparel, use.cor = TRUE)
#> 
#> Coefficients:
#>               r            alpha                s             beta  
#>       1.308e+00        4.635e+01        4.812e-01        7.070e+01  
#> Cor(life,trans)  
#>       1.337e-04  
#> KKT1: TRUE 
#> KKT2: FALSE 
#> 
#> Used Options:
#> Correlation:     TRUE 
# }
# \donttest{
# To estimate the pnbd model with static covariates,
#   add static covariates to the data
data("apparelStaticCov")
clv.data.static.cov <-
 SetStaticCovariates(clv.data.apparel,
                     data.cov.life = apparelStaticCov,
                     names.cov.life = c("Gender", "Channel"),
                     data.cov.trans = apparelStaticCov,
                     names.cov.trans = c("Gender", "Channel"))

# Fit pnbd with static covariates
pnbd(clv.data.static.cov)
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.static.cov)
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>       1.64611      103.81807        0.37820      308.80294       -0.01539  
#>  life.Channel   trans.Gender  trans.Channel  
#>       2.75180        0.47034        0.73633  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Give initial guesses for both covariate parameters
pnbd(clv.data.static.cov, start.params.trans = c(Gender=0.75, Channel=0.7),
                   start.params.life  = c(Gender=0.5, Channel=0.5))
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.static.cov, start.params.life = c(Gender = 0.5, 
#>     Channel = 0.5), start.params.trans = c(Gender = 0.75, Channel = 0.7))
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>       1.64557      103.94063        0.37849      324.01338       -0.01451  
#>  life.Channel   trans.Gender  trans.Channel  
#>       2.79911        0.47025        0.73813  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 

# Use regularization
pnbd(clv.data.static.cov, reg.lambdas = c(trans = 5, life=5))
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.static.cov, reg.lambdas = c(trans = 5, 
#>     life = 5))
#> 
#> Coefficients:
#>             r          alpha              s           beta    life.Gender  
#>     1.317e+00      4.693e+01      4.769e-01      6.951e+01     -7.733e-04  
#>  life.Channel   trans.Gender  trans.Channel  
#>    -6.011e-05      6.173e-03      6.701e-03  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  TRUE 

# Force the same coefficient to be used for both covariates
pnbd(clv.data.static.cov, names.cov.constr = "Gender",
                   start.params.constr = c(Gender=0.5))
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.static.cov, names.cov.constr = "Gender", 
#>     start.params.constr = c(Gender = 0.5))
#> 
#> Coefficients:
#>             r          alpha              s           beta   life.Channel  
#>        1.6171       104.1847         0.3552       563.3726         3.1050  
#> trans.Channel  constr.Gender  
#>        0.7324         0.4923  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     TRUE 
#> Regularization:  FALSE 

# Fit model only with the Channel covariate for life but
# keep all trans covariates as is
pnbd(clv.data.static.cov, names.cov.life = c("Channel"))
#> Starting estimation...
#> Estimation finished!
#> Pareto/NBD with Static Covariates Model
#> 
#> Call:
#> pnbd(clv.data = clv.data.static.cov, names.cov.life = c("Channel"))
#> 
#> Coefficients:
#>             r          alpha              s           beta   life.Channel  
#>        1.6470       103.9005         0.3775       309.2000         2.7485  
#>  trans.Gender  trans.Channel  
#>        0.4710         0.7364  
#> KKT1: TRUE 
#> KKT2: TRUE 
#> 
#> Used Options:
#> Correlation:     FALSE 
#> Constraints:     FALSE 
#> Regularization:  FALSE 
# }
# Add dynamic covariates data to the data object
#   add dynamic covariates to the data
# \donttest{
if (FALSE) { # \dontrun{
data("apparelDynCov")
clv.data.dyn.cov <-
  SetDynamicCovariates(clv.data = clv.data.apparel,
                       data.cov.life = apparelDynCov,
                       data.cov.trans = apparelDynCov,
                       names.cov.life = c("High.Season", "Gender", "Channel"),
                       names.cov.trans = c("High.Season", "Gender", "Channel"),
                       name.date = "Cov.Date")


# Fit PNBD with dynamic covariates
pnbd(clv.data.dyn.cov)

# The same fitting options as for the
#  static covariate are available
pnbd(clv.data.dyn.cov, reg.lambdas = c(trans=10, life=2))
} # }
# }