Title: | NBD-Dirichlet Model of Consumer Buying Behavior for Marketing Research |
---|---|
Description: | The Dirichlet (aka NBD-Dirichlet) model describes the purchase incidence and brand choice of consumer products. We estimate the model and summarize various theoretical quantities of interest to marketing researchers. Also provides functions for making tables that compare observed and theoretical statistics. |
Authors: | Feiming Chen |
Maintainer: | Feiming Chen <[email protected]> |
License: | GPL (>= 3) |
Version: | 1.4 |
Built: | 2025-02-28 05:16:35 UTC |
Source: | https://github.com/cran/NBDdirichlet |
The Dirichlet (aka NBD-Dirichlet) model describes the probability distributions of the consumer purchase incidences and brand choices. We estimate the model and calculate various theoretical quantities of interest to marketing researchers.
Feiming Chen
The Dirichlet: A Comprehensive Model of Buying Behavior. G.J. Goodhardt, A.S.C. Ehrenberg, C. Chatfield. Journal of the Royal Statistical Society. Series A (General), Vol. 147, No. 5 (1984), pp. 621-655
Repeat-Buying:Facts,Theory and Applications, 2nd edn. A.S.C. Ehrenberg, 1988, London, Charles Griffin, ISBN 0 85264 287 3
Book Review: Repeat-Buying:Facts,Theory and Applications by A.S.C. Ehrenberg. Norman Pigden. The Statistician, Vol. 40, No. 3, Special Issue (1991), pp. 349-350
dirichlet
,
print.dirichlet
, summary.dirichlet
,
plot.dirichlet
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) print(dobj) summary(dobj) # plot(dobj)
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) print(dobj) summary(dobj) # plot(dobj)
Given consumer purchase summary data, it estimates the parameters of the Dirichlet model, which describes the consumer repeat-buying behavior of branded products. It also returns with several probability functions for users to calculate various theoretical quantities.
dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name = NA, cat.pur.var = NA, nstar = 50, max.S = 30, max.K = 30, check = F)
dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name = NA, cat.pur.var = NA, nstar = 50, max.S = 30, max.K = 30, check = F)
cat.pen |
Product category penetration, which is the observed proportion of category buyers over a specific time period. |
cat.buyrate |
Category buyers' average purchase rate in a given period. This is derived as the total number of category purchase occasions divided by the total number of category buyers during a time period. |
brand.share |
A vector of brand market share. We typically define it as the proportions of purchase occasions that belong to different brands during the time period. |
brand.pen.obs |
A vector of observed brand penetration, which is the proportion of buyers for each brand during the time period. |
brand.name |
A character vector of the brand names. If not given (default), use "B1", "B2", etc. |
cat.pur.var |
The observed variance of category purchase rates across individuals. It is used for the method of moment estimation of the parameter K in the Dirichlet model. If it is not given (default), then estimate K by "mean and zeros"(see reference). |
nstar |
Maximum number of category purchases in the time period considered in the calculation. Any number larger than |
max.S |
Upper bound for the model parameter S in the optimization procedure to solve for S. Default to 30. |
max.K |
Upper bound for the model parameter K in the optimization procedure to solve for K. Default to 30. |
check |
A logical value. If T, print some diagnostic information. Defaul to F. |
The Dirichlet model and its estimation can be found in the reference paper. It is found to fit and reproduce the patterns of repeat buying of branded products quite well. Specifically, the dirichlet model is a mixture of distributions at four levels:
Each consumer's purchase incidences in a product category follow the Poisson process.
The purchase rates of the category by different consumers follow a Gamma distribution.
Each consumer's choices among the available brands follow a multinomial distribution, and
These brand choice probabilities follow a multivariate Beta or "Dirichlet" distribution across different consumers.
There are three structural parameters to be estimated:
Mean purchase rate of the category.
Measures the diversity of the overal category purchase frequency across consumers (smaller K implies more diversity).
Measures the diversity of the brand purchase propensity across consumers (smaller S implies more diversity).
To estimate M and K, we use the observed category penetration
(cat.pen
) and purchase rate (cat.buyrate
). To estimate S,
we use additionally the observed brand penetrations
(brand.pen.obs
) and brand market shares (brand.share
).
Note however once these three parameters are estimated, only the brand
market shares are needed by the Dirichlet model to compute various
repeat-buying theoretical statistics.
The estimated parameters, along with several probability functions that can access
the object data, are passed back in a list, which is assigned a
"dirichlet" class attribute. The result can be used by the print.dirichlet
,
summary.dirichlet
, and plot.dirichlet
method.
The study period (where we report the model result) is assumed to be 4
times of the observation period (input data). So if we use quarterly
data, the model output is annulized. This multiple (4) can be changed
using the member function period.set
.
A list with the following components:
M |
Estimated Dirichlet model parameter: mean purchase rate of the category. |
K |
Estimated Dirichlet model parameter: it measures the diversity of the overal category purchase frequency (smaller K implies more diversity). |
S |
Estimated Dirichlet model parameter: it measures the diversity of the brand purchase propensity (smaller S implies more diversity). |
nbrand |
Number of brands being considered in the produt category. |
nstar |
Input parameter: Maximum number of category purchases considered. |
cat.pen |
Input parameter: Category penetration in a given time period. |
cat.buyrate |
Input parameter: Category buyers' average purchase rate in a given time period. |
brand.share |
Input parameter: A vector of brand market share. |
brand.pen.obs |
Input parameter: A vector of observed brand penetration. |
brand.name |
Input parameter: A character vector of the brand names. |
check |
A logical flag that indicates whether to print the intermediate information in the model estimation. Default to F. |
error |
A logical flag that indicates if |
period.set |
A member function of the "dirichlet" class object with
one required parameter |
period.print |
A member function of the "dirichlet" class object
with no parameter. It indicates the current time period by printing the
multiple |
p.rj.n |
A member function of the "dirichlet" class object with
three required parameters |
Pn |
A member function of the "dirichlet" class object with one
required parameter |
brand.pen |
A member function of the "dirichlet" class object with
one required and one optional parameter ( |
brand.buyrate |
A member function of the "dirichlet" class object
with one required and one optional parameter |
wp |
A member function of the "dirichlet" class object with one
required and one optional parameter |
Feiming Chen
The Dirichlet: A Comprehensive Model of Buying Behavior. G.J. Goodhardt, A.S.C. Ehrenberg, C. Chatfield. Journal of the Royal Statistical Society. Series A (General), Vol. 147, No. 5 (1984), pp. 621-655
print.dirichlet
, summary.dirichlet
,
plot.dirichlet
, NBDdirichlet-package
# The following data comes from the example in section 3 of # the reference paper. They are Toothpaste purchase data in UK # in 1st quarter of 1973 from the AGB panel (5240 static panelists). cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) print(dobj)
# The following data comes from the example in section 3 of # the reference paper. They are Toothpaste purchase data in UK # in 1st quarter of 1973 from the AGB panel (5240 static panelists). cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) print(dobj)
This function plots a 'dirichlet' object. It is a method for the
generic function plot
for objects of the class
'dirichlet'. It plots the theoretical penetration growth and buying rate
growth across multiple brands according to the Dirichlet model over a specified time sequence.
## S3 method for class 'dirichlet' plot(x, t = 4, brand = 1:x$nbrand, incr = 1, result = NULL,...)
## S3 method for class 'dirichlet' plot(x, t = 4, brand = 1:x$nbrand, incr = 1, result = NULL,...)
x |
An object of "dirichlet" class. |
t |
Maximum of the projection time period, which is specified as
a multiple of the base time period. For example, if the base
time period is quarterly, then |
brand |
A vector specifying the subset of brands to be ploted. |
incr |
Increment for the time sequence that starts at 0. Its unit is one base time period. Can be a fractional number such as 0.1. |
result |
A list returned from the previous run of the
|
... |
Other parameters passing to the generic function. |
A time sequence will be made from 0 up to t
with increment
incr
, against each component of which the theoretical penetration and
brand buying rate will be plotted. Each plotted point represents the
cumulated penetration or buying rate from time 0 to its current
time point (expressed as the multiple of the base time period).
A list with two components:
pen |
A matrix with the penetration values. Its number of rows is the number of brands, and its number of columns is the length of the time sequence used for plotting the X coordinates of the points. |
buy |
A matrix with the buying rate values. Its dimension is
the same as that of |
Feiming Chen
The Dirichlet: A Comprehensive Model of Buying Behavior. G.J. Goodhardt, A.S.C. Ehrenberg, C. Chatfield. Journal of the Royal Statistical Society. Series A (General), Vol. 147, No. 5 (1984), pp. 621-655
dirichlet
, summary.dirichlet
,
print.dirichlet
, NBDdirichlet-package
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) plot(dobj)
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) plot(dobj)
This function prints a 'dirichlet' object. It is a method for the
generic function print
of class 'dirichlet'. It prints
descriptive information on the product category, brand, and the
estimated Dirichlet model parameters.
## S3 method for class 'dirichlet' print(x,...)
## S3 method for class 'dirichlet' print(x,...)
x |
An object of "dirichlet" class. |
... |
Other parameters passing to the generic function |
The following information is printed:
Number of brands in the category
Brand list
Brands' market shares.
Brands' penetrations.
The multiple of the base time period that indicates the study time period, and the corresponding M value.
Category penetration and category buying rate.
Estimated dirichlet model parameters: M (for base period), K, and S.
NULL
Feiming Chen
The Dirichlet: A Comprehensive Model of Buying Behavior. G.J. Goodhardt, A.S.C. Ehrenberg, C. Chatfield. Journal of the Royal Statistical Society. Series A (General), Vol. 147, No. 5 (1984), pp. 621-655
dirichlet
, summary.dirichlet
,
plot.dirichlet
, NBDdirichlet-package
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) print(dobj) # YOU WILL SEE THE FOLLOWING: # Number of Brands in the Category = 8 # Brand List : Colgate DC : Macleans : Close Up : Signal : ultrabrite : # Gibbs SR : Boots Priv. Label : Sainsbury Priv. Lab. # Brands' Market Shares: 0.25 0.19 0.1 0.1 0.09 0.08 0.03 0.02 # Brands' Penetration: 0.2 0.17 0.09 0.08 0.08 0.07 0.03 0.02 # Multiple of Base Time Period: 1 , Current M = 1.456 # Channel Penetration = 0.56 , with Shopping Rate = 2.6 # Estimated Dirichlet Model Parameters: # NBD: M = 1.46 , K = 0.78 ; Dirichlet: S = 1.55
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) print(dobj) # YOU WILL SEE THE FOLLOWING: # Number of Brands in the Category = 8 # Brand List : Colgate DC : Macleans : Close Up : Signal : ultrabrite : # Gibbs SR : Boots Priv. Label : Sainsbury Priv. Lab. # Brands' Market Shares: 0.25 0.19 0.1 0.1 0.09 0.08 0.03 0.02 # Brands' Penetration: 0.2 0.17 0.09 0.08 0.08 0.07 0.03 0.02 # Multiple of Base Time Period: 1 , Current M = 1.456 # Channel Penetration = 0.56 , with Shopping Rate = 2.6 # Estimated Dirichlet Model Parameters: # NBD: M = 1.46 , K = 0.78 ; Dirichlet: S = 1.55
This function summarizes a 'dirichlet' object. It is a method for the
generic function summary
of class 'dirichlet'. It
calculate four types of theoretical summary statistics, which can be
compared with the corresponding observed statistics.
## S3 method for class 'dirichlet' summary(object, t = 1, type = c("buy", "freq", "heavy", "dup"), digits = 2, freq.cutoff = 5, heavy.limit = 1:6, dup.brand = 1, ...)
## S3 method for class 'dirichlet' summary(object, t = 1, type = c("buy", "freq", "heavy", "dup"), digits = 2, freq.cutoff = 5, heavy.limit = 1:6, dup.brand = 1, ...)
object |
An object of "dirichlet" class. |
t |
Multiple of the base time period. For example, if the assumed
base time period is quarterly, then |
type |
A character vector that specifies which types of
theoretical statistics (during the time period indicated by
|
digits |
Number of decimal digits to control the rounding precision of the reported statistics. Default to 2. |
freq.cutoff |
For the |
heavy.limit |
For the |
dup.brand |
For the |
... |
Other parameters passing to the generic function. |
The output corresponds to the theoretical portion of the Table 3, 4, 5, 6 in the reference paper. We also have another set of functions (available upon request) that put observed and theoretical statistics together for making tables that resemble those in the reference.
Let be the probability of a consumer buying the product
category
times. Then
has a Negative Binomial
Distribution (NBD). Let
be the probability of making
purchases of brand
, gien that
purchases
of the category having been make (
). Then
has a Beta-Binomial distribution.
The theoretical brand penetration is then
The theoretical brand buying rate is
and the category buying rate per brand buyer is
The brand purchase frequency distribution is
The brand penetration given a specific category purchase frequency range
is
The brand buying rate given a specific category purchase frequency range
is
To calculate the brand duplication measure, we first get the penetration
of the "composite" brand of two brands
and
as:
Then the theoretical proportion of the population buying both brands at
least once is:
and the brand duplication (where brand
is the focal
brand) is:
A list with those components that are specified by the input
type
parameter.
buy |
A data frame with three components: |
freq |
A matrix that lists the distribution of brand purchases. The number of rows is the number of brands. |
heavy |
A matrix with two columns. The first column
( |
dup |
A vector with dimension as the number of brands. It reports
the brand duplication (proportion of buyers of a particular brand
also buying other brand) of the focal brand ( |
Feiming Chen
The Dirichlet: A Comprehensive Model of Buying Behavior. G.J. Goodhardt, A.S.C. Ehrenberg, C. Chatfield. Journal of the Royal Statistical Society. Series A (General), Vol. 147, No. 5 (1984), pp. 621-655
dirichlet
, print.dirichlet
,
plot.dirichlet
, NBDdirichlet-package
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) ## Not run: summary(dobj) summary(dobj, t=4, type="freq") summary(dobj, t=4, type="heavy", heavy.limit=c(7:50)) summary(dobj, t=1, type="dup", dup.brand=2)
cat.pen <- 0.56 # Category Penetration cat.buyrate <- 2.6 # Category Buyer's Average Purchase Rate in a given period. brand.share <- c(0.25, 0.19, 0.1, 0.1, 0.09, 0.08, 0.03, 0.02) # Brands' Market Share brand.pen.obs <- c(0.2,0.17,0.09,0.08,0.08,0.07,0.03,0.02) # Brand Penetration brand.name <- c("Colgate DC", "Macleans","Close Up","Signal","ultrabrite", "Gibbs SR","Boots Priv. Label","Sainsbury Priv. Lab.") dobj <- dirichlet(cat.pen, cat.buyrate, brand.share, brand.pen.obs, brand.name) ## Not run: summary(dobj) summary(dobj, t=4, type="freq") summary(dobj, t=4, type="heavy", heavy.limit=c(7:50)) summary(dobj, t=1, type="dup", dup.brand=2)