Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion R/clv_template_controlflow_predict.R
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ clv.controlflow.predict.add.uncertainty.estimates <- function(clv.fitted, dt.pre
dt.boots[, Id := sub("_BOOTSTRAP_ID_[0-9]+$", "", Id)]

# quantiles for each predicted quantity: select only the existing ones
cols.predictions <- c("PAlive", "CET", "DERT", "DECT", "predicted.mean.spending", "predicted.total.spending", "predicted.CLV")
cols.predictions <- c("PAlive", "CET", "DERT", "DECT", "predicted.mean.spending", "predicted.period.spending", "predicted.CLV")
cols.predictions <- cols.predictions[cols.predictions %in% colnames(dt.boots)]

# Long-format for easier handling of different prediction columns
Expand Down
28 changes: 14 additions & 14 deletions R/f_generics_clvfittedtransactions.R
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,15 @@ setMethod("clv.controlflow.predict.get.has.actuals", signature(clv.fitted="clv.f
# .clv.controlflow.predict.add.actuals ---------------------------------------------------------------------------------
setMethod("clv.controlflow.predict.add.actuals", signature(clv.fitted="clv.fitted.transactions"), definition = function(clv.fitted, dt.predictions, has.actuals, verbose, ...){

actual.total.spending <- i.actual.total.spending <- Price <- Date <- period.first <- period.last <- actual.x <- i.actual.x <- NULL
actual.period.spending <- i.actual.period.spending <- Price <- Date <- period.first <- period.last <- actual.x <- i.actual.x <- NULL

# Only if:
# - there is a holdout
# - the prediction is not beyond holdout
#
# Data until prediction end
# actual.x: number of transactions
# actual.total.spending: total spending
# actual.x: number of transactions
# actual.period.spending: total spending

timepoint.prediction.first <- dt.predictions[1, period.first]
timepoint.prediction.last <- dt.predictions[1, period.last]
Expand All @@ -184,8 +184,8 @@ setMethod("clv.controlflow.predict.add.actuals", signature(clv.fitted="clv.fitte
incbounds = TRUE)]

if(clv.data.has.spending(clv.fitted@clv.data)){
dt.actuals <- dt.actuals.transactions[, list(actual.x = .N,
actual.total.spending = sum(Price)),
dt.actuals <- dt.actuals.transactions[, list(actual.x = .N,
actual.period.spending = sum(Price)),
keyby="Id"]
}else{
dt.actuals <- dt.actuals.transactions[, list(actual.x = .N), keyby="Id"]
Expand All @@ -195,8 +195,8 @@ setMethod("clv.controlflow.predict.add.actuals", signature(clv.fitted="clv.fitte
dt.predictions[is.na(actual.x), actual.x := 0]

if(clv.data.has.spending(clv.fitted@clv.data)){
dt.predictions[dt.actuals, actual.total.spending := i.actual.total.spending, on="Id"]
dt.predictions[is.na(actual.total.spending), actual.total.spending := 0]
dt.predictions[dt.actuals, actual.period.spending := i.actual.period.spending, on="Id"]
dt.predictions[is.na(actual.period.spending), actual.period.spending := 0]
}
return(dt.predictions)
}
Expand All @@ -205,7 +205,7 @@ setMethod("clv.controlflow.predict.add.actuals", signature(clv.fitted="clv.fitte

# .clv.controlflow.predict.post.process.prediction.table ------------------------------------------------------------------------------
setMethod("clv.controlflow.predict.post.process.prediction.table", signature = signature(clv.fitted="clv.fitted.transactions"), function(clv.fitted, dt.predictions, has.actuals, verbose, predict.spending, ...){
predicted.mean.spending <- i.predicted.mean.spending <- actual.total.spending <- i.actual.total.spending <- predicted.total.spending <- NULL
predicted.mean.spending <- i.predicted.mean.spending <- actual.period.spending <- i.actual.period.spending <- predicted.period.spending <- NULL
predicted.CLV <- CET <- DECT <- DERT <- NULL

# Predict spending ---------------------------------------------------------------------------------------
Expand All @@ -224,7 +224,7 @@ setMethod("clv.controlflow.predict.post.process.prediction.table", signature = s
dt.predictions[dt.spending, predicted.mean.spending := i.predicted.mean.spending, on = "Id"]

# The actual.mean.spending from dt.spending is not added anymore
# actual.total.spending is already in prediction table
# actual.period.spending is already in prediction table

return(dt.predictions)
}
Expand Down Expand Up @@ -291,8 +291,8 @@ setMethod("clv.controlflow.predict.post.process.prediction.table", signature = s
if("DECT" %in% colnames(dt.predictions))
dt.predictions[, predicted.CLV := DECT * predicted.mean.spending]

# If spending is predicted, also add predicted.total.spending
dt.predictions[, predicted.total.spending := predicted.mean.spending * CET]
# If spending is predicted, also add predicted.period.spending
dt.predictions[, predicted.period.spending := predicted.mean.spending * CET]
}

# Present cols in desired order ------------------------------------------------------------
Expand All @@ -302,8 +302,8 @@ setMethod("clv.controlflow.predict.post.process.prediction.table", signature = s
cols <- c(cols, "actual.x")

# cannot determine otherwise alone from has.actuals
if("actual.total.spending" %in% colnames(dt.predictions))
cols <- c(cols, "actual.total.spending")
if("actual.period.spending" %in% colnames(dt.predictions))
cols <- c(cols, "actual.period.spending")
}

if("DERT" %in% colnames(dt.predictions))
Expand All @@ -312,7 +312,7 @@ setMethod("clv.controlflow.predict.post.process.prediction.table", signature = s
cols <- c(cols, "PAlive", "CET", "DECT")

if(do.predict.spending)
cols <- c(cols, c("predicted.mean.spending", "predicted.total.spending"))
cols <- c(cols, c("predicted.mean.spending", "predicted.period.spending"))

if("predicted.CLV" %in% colnames(dt.predictions))
cols <- c(cols, "predicted.CLV")
Expand Down
4 changes: 2 additions & 2 deletions R/f_interface_predict_clvfittedtransactions.R
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@
#' \item{CET}{The Conditional Expected Transactions: The number of transactions expected until prediction.end.}
#' \item{DERT or DECT}{Discounted Expected Residual Transactions or Discounted Expected Conditional Transactions for dynamic covariates models}
#' \item{actual.x}{Actual number of transactions until prediction.end. Only if there is a holdout period and the prediction ends in it, otherwise not reported.}
#' \item{actual.total.spending}{Actual total spending until prediction.end. Only if there is a holdout period and the prediction ends in it, otherwise not reported.}
#' \item{actual.period.spending}{Actual total spending until prediction.end. Only if there is a holdout period and the prediction ends in it, otherwise not reported.}
#' \item{predicted.mean.spending}{The mean spending per transactions as predicted by the spending model.}
#' \item{predicted.total.spending}{The predicted total spending until prediction.end (\code{CET*predicted.mean.spending}).}
#' \item{predicted.period.spending}{The predicted total spending until prediction.end (\code{CET*predicted.mean.spending}).}
#' \item{predicted.CLV}{Customer Lifetime Value based on \code{DERT/DECT} and \code{predicted.mean.spending}.}
#'
#' If predicting for new customers (using \code{newcustomer()}), a numeric scalar indicating the expected
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ results <- predict(est.pnbd)
#> Starting estimation...
#> Estimation finished!
print(results)
#> Id period.first period.last period.length actual.x actual.total.spending
#> Id period.first period.last period.length actual.x actual.period.spending
#> 1: 1 2005-10-11 2006-07-16 39.85714 0 0.00
#> 2: 10 2005-10-11 2006-07-16 39.85714 0 0.00
#> 3: 100 2005-10-11 2006-07-16 39.85714 23 737.53
Expand Down
4 changes: 2 additions & 2 deletions man/predict.clv.fitted.transactions.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions tests/testthat/helper_s3_fitted_predict.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ fct.testthat.runability.clvfittedtransactions.predict <- function(fitted.transac
expect_true(c("actual.x" %in% colnames(dt.pred)))

if(clv.data.has.spending(fitted.transactions@clv.data)){
expect_true(c("actual.total.spending" %in% colnames(dt.pred)))
expect_true(c("actual.period.spending" %in% colnames(dt.pred)))
}else{
expect_false(c("actual.total.spending" %in% colnames(dt.pred)))
expect_false(c("actual.period.spending" %in% colnames(dt.pred)))
}
})
}

# Test
# Sum of actual.total.spending same as sum based on data
# Sum of actual.period.spending same as sum based on data
# sum of actual.x same as sum based on data
# actual.total.spending all > 0
# actual.period.spending all > 0
# actual.transactions all > 0
# predicted CLV is = X*Y
if(clv.data.has.spending(fitted.transactions@clv.data)){
Expand Down Expand Up @@ -113,14 +113,14 @@ fct.testthat.runability.clvfittedtransactions.predict <- function(fitted.transac
expect_true(dt.pred[, is.numeric(actual.x)])

if(clv.data.has.spending(fitted.transactions@clv.data)){
expect_true("actual.total.spending" %in% colnames(dt.pred))
expect_true(dt.pred[, is.numeric(actual.total.spending)])
expect_true("actual.period.spending" %in% colnames(dt.pred))
expect_true(dt.pred[, is.numeric(actual.period.spending)])
}else{
expect_false("actual.total.spending" %in% colnames(dt.pred))
expect_false("actual.period.spending" %in% colnames(dt.pred))
}
}else{
expect_false("actual.x" %in% colnames(dt.pred))
expect_false("actual.total.spending" %in% colnames(dt.pred))
expect_false("actual.period.spending" %in% colnames(dt.pred))
}
})

Expand Down
2 changes: 1 addition & 1 deletion vignettes/CLVTools.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ If spending information was provided when initializing the `clvdata`-object, `CL
* predicted mean spending estimated by a Gamma/Gamma model [@Colombo1999; @Fader2005c] and
* the customer lifetime value (CLV). CLV is calculated as the product of DERT and predicted spending.

If a holdout period is available additionally the true numbers of transactions ("actual.x") and true spending ("actual.total.spending") during the holdout period are reported.
If a holdout period is available additionally the true numbers of transactions ("actual.x") and true spending ("actual.period.spending") during the holdout period are reported.

To use the parameter estimates on new data (e.g., an other customer cohort), the argument `newdata` optionally allows to provide a new `clvdata` object.

Expand Down
Loading