Introduction

Attribution Modeling is a commonly-used modeling technique in marketing and e-commerce that determines how credit for sales and conversions is assigned to channels or “touchpoints” during the consumer buying process (i.e. conversion paths). The following is a simplified graphical representation of the customer buying process

In this tutorial we will demonstrate a simple example of an attribution model that makes use of Markov Chains.

Markov Chains

A Markov model predicts the probability that a user will transition from point A to point B based on steps that a user takes through a website. The sequence of these contents are determined by the Markov order, which range from \([0, 4]\). A Markov model representation of the customer buying or conversion process might look something like the following

Notice that the outcome of a Markov model is binary; a customer either converts or does not (NULL).

The transition probability (the probability that a customer will go from one Sequence A to Sequence B) is given by

\[ \begin{aligned} w_{ij} = P(X_{t} = s_{j} | X_{t-1} = s_{i}), 0 \leq w_{ij} \leq 1, \sum_{j=1}^{N}w_{ij} = 1 \forall i \end{aligned} \]

An Example

First, let’s fabricate some data with three paths.

df <- data.frame(path = c('c1 > c2 > c3', 'c1', 'c2 > c3'), conv = c(1, 0, 0), conv.null = c(0, 1, 1))

A quick preview of our data frame.

path conv conv.null
c1 > c2 > c3 1 0
c1 0 1
c2 > c3 0 1

Next, let’s develop our Markov model, store the results, and extract the corresponding transition matrix.

library(ChannelAttribution)
library(reshape2)
mod <- markov_model(df, var_path = 'path', var_conv = 'conv', var_null = 'conv.null', out_more = T)
mod.results <- mod$result
df.trans1 <- mod$transition_matrix
df.trans1 <- dcast(df.trans1, channel_from ~ channel_to, value.var = 'transition_probability')

Plotting Our Graph

library(markovchain)
df.trans <- mod$transition_matrix

# Add dummy vars in order to plot graph
df.dummy <- data.frame(
  channel_from = c('(start)', '(conversion)', '(null)'),
  channel_to = c('(start)', '(conversion)', '(null)'),
  transition_probability = c(0, 1, 1)
)
df.trans <- rbind(df.trans, df.dummy)

# ordering channels
df.trans$channel_from <- factor(df.trans$channel_from, 
                                levels = c('(start)', '(conversion)', '(null)', 'c1', 'c2', 'c3'))
df.trans$channel_to <- factor(df.trans$channel_to,
                              levels = c('(start)', '(conversion)', '(null)', 'c1', 'c2', 'c3'))
df.trans <- dcast(df.trans, channel_from ~ channel_to, value.var = 'transition_probability')

# constructing our markov chain
trans.matrix <- matrix(data = as.matrix(df.trans[, -1]),
                       nrow = nrow(df.trans[, -1]), ncol = ncol(df.trans[, -1]),
                       dimnames = list(c(as.character(df.trans[, 1])), c(colnames(df.trans[, -1]))))
trans.matrix[is.na(trans.matrix)] <- 0
trans.matrix.plot <- new("markovchain", transitionMatrix = trans.matrix)
plot(trans.matrix.plot, edge.arrow.size = 0.25)

A graphical representation of the Markov chain, or consumer purchasing journey, can be very useful in many ways, not least of which because it shows the paths that are most likely to drive conversions.