1. Введение в “Uplift” моделирование

Uplift моделирование – прогнозный метод машинного обучения, служащий для определения величины эффекта воздействия на потребителя. Uplift моделирование применяется при:

  • планировании промо акций (с целью увеличения вероятности совершения покупки)
  • планировании акций, направленных на снижение оттока клиентов
  • определении ценовой эластичности клиента
  • определении оптимального канала маркетинговых коммуникаций
  • upselling & cross-selling (продажа дополнительных продуктов существующим клиентам)

Uplift моделирование позволяет сегментировать потребителей, что приводит к увеличению ROI маркетинговой кампании:

  • посредством таргетирования группы клиентов, наиболее восприимчивой к промо-акции (“persuadables”)
  • посредством исключения из маркетинговой кампании групп клиентов, отрицательно сказывающихся на ROI, а именно:
    • клиентов, которые уже приняли решение и произведут необходимое действие (покупку, возобновление подписки и т.д.) в любом случае, безотносительно к участию в промо-акции (“sure thing”)
    • клиентов, которые не произведут необходимое действие, несмотря ни на какие дополнительные скидки (“lost causes”)
    • клиентов, которые прекратят подписку на сервис/прекратят быть клиентами компании, вследствие промо-акции (“sleeping dogs”).

Пояснить необходимость учета специфики отклика разных групп потребителей при планировании маркетинговых акций поможет следующий график:

Вероятность отклика потребителя в зависимости от участия в промо-акции
(синий – участвовал, черный – нет)

title

  • левый красный эллипс (“lost causes”): что бы ни делалось, клиент всё равно не совершит покупку или уйдет к другому провайдеру
  • правый красный эллипс (“sure thing”): клиент совершит покупку и без промо акции. Скидки/купоны/затраты на промо “выброшены на ветер”
  • зеленая зона в середине (“persuadables”): промо-акция приводит к увеличению частоты совершения покупки.

Классическим примером неудачного планирования промо-акции, без учета уже сформировавшегося желания или нежелания сделать приобретение, является следующий реальный пример:

Мы разработали модель отклика клиентов на промо-акцию и сделали рассылку каталогов по топ-30% клиентов. В результате, с учетом затрат на печать и рассылку, ROI был даже хуже, чем в контрольной группе, где мы не делали ничего.

Почему?!

Ответ:

Скорее всего, большая часть из этой рассылки сделала бы покупку и без участия в промо-акции (“sure thing”).

2. Методология “Uplift” моделирования

Uplift моделирование сегментирует потребителей и анализирует разницу отклика в 2-ух выборках:

  • контрольной, где промо-акция отсутствовала
  • в промо-группе

С математической точки зрения “uplift” (“аплифт”) определяется как изменение вероятности совершения желаемого события (покупка, клик, возобновление подписки) в ответ на акцию:

P(Y=1| i, a=1) — P(Y=1| i, a=0)

  • где первый член – это условная вероятность совершения покупки конкретным индивидуумом “i” при условии участия в акции (a=1)
  • а второй – условная вероятность совершения того-же самого действия, но “если бы” этот же индивидуум “i” находился в контрольной группе, где акция не проводилась (a=0).

Уже на этапе определения uplift становится понятной нетривиальность поиска решения такой задачи, т.к. uplift не может быть непосредственно измерен: клиент не может одновременно находится и в промо- и в контрольной группе.

Для решения этой задачи существует несколько подходов, которые условно можно разделить на 2 группы:

  • Прямые

    • Метод двух моделей. Независимо разрабатываются 2 модели: одна для контрольной группы, другая для промо. Аплифт для каждого потенциального участника промо-акции вычисляется как разница между прогнозами вероятности покупки, выдаваемыми этими моделями.
    • Метод фиктивных переменных (“dummy variables”). Количество переменных удваивается: для каждой переменной, входщей в базовую модель, добавляется переменная, помноженная на фиктивную переменную с значением 0/1:
      • 0, в случае если это клиент из контрольной группы
      • 1, в случае если клиент участвовал в промо акцию.

        Аплифт, как и в первом случае, вычисляется как разница между вероятностью совершения покупки данным клиентом в контрольной и промо группах.
  • Непрямые

    • Данные методы непосредственно учитывают тот факт, что клиент не может одновременно входить и в контрольную и в промо группу. Они определяют аплифт посредством разбиения всего множества клиентов на подмножества, где клиенты или похожи друг на друга (KNN кластеризация) или к похожести добавлятся дополнительные условия по максимизации разницы отклика на промо в обеих группах (Random Forest).

      После определения оптимальных подмножеств, для членов этого подмножества вычисляется аплифт как разница между вероятностью наступления благоприятного события в промо и контрольной группах.

И в том и в другом случае после анализа тестовой (пробной) промо-акции впоследствии таргетируются только группы клиентов, с макимально прогнозируемым аплифтом.

Прямые методы просты в реализации и интуитивно понятны, но, как правило, отличаются невысокой точностью. Непрямые методы являются “черными ящиками”, но отличаются более высокой точностью.

3. Примеры успешных реализаций*

Кейс 1. Telenor.

  • Задача: Снижение оттока
  • Алгоритм: Оптимизация таргетирования при помощи аплифт моделирования
  • Результат:
    • Увеличение ROI маркетинговой кампании в 11 раз
    • Снижение оттока на 36%
    • Снижение стоимости кампании на 40%
  • Источник: Vittal (2008), Patrick Surry ( Pitney Bowes Business Insight)

Кейс 2. Charles Schwab.

  • Задача: Direct mail промо акция по продаже финансового продукта
  • Алгоритм: Оптимизация таргетирования при помощи аплифт моделирования
  • Результат:
    • Увеличение ROI маркетинговой кампании в 20 раз
    • Увеличение конверсии на 0.02% ÷ 0.43%
  • источник: Kim Larsen

4. Исследование данных

4.1 Что такое R

R – это объектно-ориентированный, скриптовый язык статистической обработки данных. R – это де-факто стандарт статистического моделирования в академическом мире. Большинство передовых статистических алгоритмов вначале реализуются в R (Random Forest, Lasso, Ridge Regression etc), а затем мигрируют в коммерческие пакеты. Причиной популярности R являются:

  • открытый код, предполагающий бесплатное распространение
  • большое и постоянно растущее количество реализованных алгоритмов
  • высококачественная графика печатного качества
  • дружественное сообщество пользователей, с громадной базой Q&A на stackoverflow.com (~ 140 тыс. вопросов и ответов), где можно найти ответ практически на любой вопрос.

R имеет реализованные функции для моделирования аплифт в двух пакетах:

  • uplift (by Leo Guelman): пакет имеет функции для генерация данных, тренировки и валидации моделей (CCIF, RF, KNN), а также функции для презентации и визуализации результатов моделирования.

  • Information (by Kim Larsen): пакет реализует несколько алгоритмов (Net WOE, Net IV) для выбора оптимального набора параметров при аплифт моделировании. Кроме того, пакет содержит реальную базу данных маркетинговой кампании, которая будет использоваться в данном примере.

4.2 “Базовый” аплифт

Для начала, загрузим необходимые пакеты:

library("uplift") # библиотека моделирования
## Loading required package: RItools
## Loading required package: MASS
## Loading required package: coin
## Loading required package: survival
## Loading required package: tables
## Loading required package: Hmisc
## Loading required package: lattice
## Loading required package: Formula
## Loading required package: ggplot2
## 
## Attaching package: 'Hmisc'
## The following objects are masked from 'package:base':
## 
##     format.pval, round.POSIXt, trunc.POSIXt, units
## Loading required package: penalized
## Welcome to penalized. For extended examples, see vignette("penalized").
library("Information") # данные
## 
## Attaching package: 'Information'
## The following object is masked from 'package:penalized':
## 
##     penalty

Пакет Information содержит интересующие нас данные в виде двух объектов:

  • train — данные, которые мы будем использовать для тренировки модели
  • valid — данные, которые будут использоваться для валидации модели

которые мы для начала объединим в один большой датасет:

train <- as.data.frame(train)
valid <- as.data.frame(valid)
data <- rbind(train,valid)
dim(data) # 20'000 рядов (кейсов), 70 переменных
## [1] 20000    70
sum(is.na(data)) # нет пропущенных данных
## [1] 0
table(sapply(data, mode)) # все данные представлены в виде чисел
## 
## numeric 
##      70

Датасет состоит из 20'000 строчек (кейсов), с 70 численными переменными, которые описывают профайл клиентов компании. Ларсен не раскрывает смысл, стоящий за той или иной переменной (data book отсутствует), однако для нас важны 3 переменные:

  • TREATMENT – входит данный клиент в промо группу или нет (0/1)
  • PURCHASE – произвел данный клиент покупку или нет (0/1)
  • UNIQUE_ID – идентификатор клиента

Определим количество сделавших покупки в контрольной и в промо группах и назовем разницу “базовым” аплифтом. Эта величина будет являться бенчмарком, который мы будем пытаться усовершенствовать в результате моделирования:

tb <- table(data$TREATMENT, data$PURCHASE, dnn = c('TREATMENT','PURCHASE'))
prop.table(tb, margin =1)
##          PURCHASE
## TREATMENT         0         1
##         0 0.8004615 0.1995385
##         1 0.7986443 0.2013557

Графическое отображение вероятности совершения покупки в контрольной и промо группах:

library("ggplot2") # библиотека для построения графиков
options(repr.plot.width = 4, repr.plot.height=4) # размер графика

dat <- as.data.frame(prop.table(tb, margin=1))
dat <- dat[dat$PURCHASE==1,]
(ggplot(data=dat, aes(x=factor(TREATMENT), y=Freq)) 
 + geom_bar(stat="identity", width=.5)
 + xlab("Treatment")
 + ylab("Frequency")
 + ggtitle("Probability of Purchase")
 + coord_cartesian(ylim=c(.18,.21)))

plot of chunk unnamed-chunk-7

4.3 Является ли аплифт в 0.2% статистически значимым?

Т.к. мы имеем дело со сравнительной небольшой выборкой в 20'000 кейсов, а 20.14% и 19.95% отличаются всего лишь на 0.2%, интересно было бы ответить на вопрос:

является ли такое отличие статистически значимым? Иначе говоря, при повторном проведении промо акции, всегда ли мы гарантированно получим более высокую частоту покупок в промо группе, пусть даже на 0.2%?

Для начала, попробуем визуализировать следующий мысленный эксперимент:

сделаем из нашей тестовой выборки в 20'000 кейсов 10 случайных выборок меньшего размера (например 15'000 кейсов), и посмотрим на распределение частоты совершения покупок в контрольной и промо группах.

library(data.table)
## data.table 1.9.6  For help type ?data.table or https://github.com/Rdatatable/data.table/wiki
## The fastest way to learn (by data.table authors): https://www.datacamp.com/courses/data-analysis-the-data-table-way
data_tb <- as.data.table(data)
set.seed(1)
data_ <- list()

for (i in 1:10) {
    data_[[i]] <- data_tb[sample(.N,15000)][,.(mean(PURCHASE)),by=TREATMENT]
}

train_stats <- rbindlist(data_)
train_stats <- as.data.frame(train_stats)
train_stats <- cbind(train_stats, id = 1:20)

(ggplot(data=train_stats, aes(factor(TREATMENT), V1, group=factor(id)))
    + geom_bar(stat="identity", width=.2, position=position_dodge(.5))
    + xlab("Treatment")
    + ylab("Frequency")
    + ggtitle("Probability of Purchase")
    + coord_cartesian(ylim=c(.18,.21)))

plot of chunk unnamed-chunk-8

Обратите внимание на 1-ю пару результатов справа (и многие другие !!!), где частота совершения покупок в контрольной группе (Treatment=0) выше, чем в промо (Treatment=1).

Для того чтобы окончательно убедиться в отсутствии статистической значимости увеличения частоты покупок в данной выборке, проведем формальный тест на разницу в частоте покупок в контрольной и промо группах:

prop.test(tb[ , c(2, 1)])
## 
##  2-sample test for equality of proportions with continuity
##  correction
## 
## data:  tb[, c(2, 1)]
## X-squared = 0.091986, df = 1, p-value = 0.7617
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.013013622  0.009379345
## sample estimates:
##    prop 1    prop 2 
## 0.1995385 0.2013557

Т.к. доверительный интервал включает в себя 0, то при текущем планировании промо-акции мы не можем исключить того, что на некоторых выборках частота покупок в контрольной группе будет выше чем в промо группе (в чем мы уже убедились на случайных выборках в начале этого раздела).

5. Моделирование

План моделирования:

  • Поделим весь имеющийся в нашем распоряжении датасет data случайным образом на:
    • 80%, где мы будем пробовать разные модели и настраивать параметры. Оптимальный набор параметров будет определяться с помощью 5-fold Cross Validation. Этот датасет мы назовем full.
    • 20%, которые мы “откладываем в сейф”. На этом тестовом датасете, который мы так и назовем – safe – мы будем проверять качество созданной модели.
  • Используемый алгоритм: ccif из пакета uplift (Causal Conditional Inference Forest), который априори показывает результат не хуже, чем другие методы. Параметры для тюнинга модели:
    • глубина деревьев (глубина взаимодействия между различными аттрибутами клиента)
    • количество “полезных” аттрибутов (определяется посредством расчета показателя NIV из пакета Information для всех переменных)
library(caTools)
set.seed(123) # фиксируем повторяемость результата
idx <- sample.split(data$TREATMENT, .8)
full <- data[idx,]
safe <- data[!idx,]

Небольшая проверка, чтобы убедиться, что структура данных сохранилась:

prop.table(table(full$TREATMENT, full$PURCHASE, dnn = c('TREATMENT','PURCHASE')),1)
##          PURCHASE
## TREATMENT         0         1
##         0 0.7983446 0.2016554
##         1 0.8012709 0.1987291
prop.table(table(safe$TREATMENT, safe$PURCHASE, dnn = c('TREATMENT','PURCHASE')),1)
##          PURCHASE
## TREATMENT         0         1
##         0 0.8089268 0.1910732
##         1 0.7881356 0.2118644

Для того, чтобы у нас была возможность сравнивать качество различных моделей, кросс-валидацию будем проводить на 5-ти фиксированных выборках:

library(caret)
## 
## Attaching package: 'caret'
## The following object is masked from 'package:survival':
## 
##     cluster
set.seed(123) # фиксируем повторяемость результата
idx_valid <- createFolds(full$TREATMENT, k=5)

Кросс валидация происходит следующим образом:

  • сначала мы задаем глубину взаимодействия между атрибутами (d, от 1 до 10)
  • затем мы фиксируем выборку (1/5 от full), где модель будет валидироваться (проверяться результативность предсказаний)
  • на оставшихся 4/5 модель тренируетдся и затем делается подсчет фактического аплифта на валидирующем сегменте
  • процесс повторяется 5 раз (full разделен на 5 равных выборок): меняется валидирующий сегмент –> автоматически меняется выборка, где модель тренируется
  • в заключение набор полученных аплифтов усредняется по 5-ти прогнозам и получается средний аплифт и дисперсия для каждого дециля
  • процесс повторяется для следующей глубины взаимодействия

Таким образом, в конце мы имеем 10 пар средних и дисперсий для аплифта в 10 децилях (в данном случае 200 пар значений mean и sd для 10 глубин и 10 децилей)

# form <- as.formula(paste0('PURCHASE ~ trt(TREATMENT)+',
#                           paste0(setdiff(colnames(full),
#                                          c('PURCHASE','TREATMENT','UNIQUE_ID')),
#                                  collapse='+')))

# out <- list()
# for (d in 1:10) {
#     uplift <- list()
#     for (i in 1:5) {
#         valid <- idx_valid[[i]]
#         train <- setdiff(1:nrow(full),valid)
#         set.seed(123)
#         mod <- ccif(formula=form,
#                     data=full[train,],
#                     ntree=100,
#                     interaction.depth = d,
#                     split_method='Int',
#                     verbose=F)
#         preds_valid <- predict(mod, full[valid,])
#         uplift[[i]] <- performance(preds_valid[,1],
#                                    preds_valid[,2],
#                                    full[valid,'PURCHASE'],
#                                    full[valid,'TREATMENT'],
#                                    direction=1)[,'uplift']
#     }
#     upl <- do.call(rbind,uplift)
#     out[[d]] <- list(mn=apply(upl, 2, 'mean'), std=apply(upl, 2, 'sd'))
# }
# saveRDS(out, 'outInt.RDS')

data <- readRDS('outInt.RDS')
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:Hmisc':
## 
##     combine
options(repr.plot.width = 8, repr.plot.height=4) # размер графика
p <- list()
for (n in 1:10) {
    df = as.data.frame(data[[n]])
    p[[n]] <- ggplot(data=df, aes(x=1:nrow(df),y=mn)) +
        geom_line(col='blue',size=2) +
        geom_errorbar(aes(ymin=mn-std, ymax=mn+std)) +
        ggtitle(paste('All features, tree depth,', n)) +
        scale_x_continuous(name='Decile', breaks=1:10) +
        scale_y_continuous(name='Uplift', limit=c(-.35,.35)) +
        geom_text(aes(label=round(mn,2), y=mn+std + .03))
}

grid.arrange(p[[7]],p[[9]],ncol=2) # две оптимально подобранные модели

plot of chunk unnamed-chunk-15

Таким образом мы видим, что при использовании всех доступных аттрибутов:

  • при глубине взаимодействия 7, аплифт в первом дециле составляет 13%, во втором 6%, и в третьем 4%
  • при глубине взаимодействия 9, аплифт составляет 13, 4 и 2 процентов

Внимание: аплифты не аддитивны и не усредняются (см. пример расчета аплифта для нескольких децилей ниже)

Поробуем проверить поведение этих моделей (все аттрибуты, глубина взаимодействия 7 и 9) на “боевой” выборке safe, которую мы отложили в самом начале:

form <- as.formula(paste0('PURCHASE ~ trt(TREATMENT)+',
                          paste0(setdiff(colnames(train),
                                         c('PURCHASE','TREATMENT','UNIQUE_ID')),
                                 collapse='+')))

p_safe <- list()
for (d in c(7,9)) {
set.seed(123)
mod <- ccif(formula=form,
            data=full, # тренируем на всем датасете, на всех аттрибутах
            ntree=100,
            interaction.depth=d, # тренируем для двух глубин взаимодействия: 7 и 9.
            split_method="Int",
            verbose=F)

preds_safe <- predict(mod, safe) # предсказываем для safe

perf_safe <- performance(preds_safe[,1],
                         preds_safe[,2],
                         safe$PURCHASE,
                         safe$TREATMENT,
                         direction=1)

p_safe[[d]] <- p[[d]] + geom_line(data=NULL, aes(x=perf_safe[,1], y=perf_safe[,8]),color='green')
}
grid.arrange(p_safe[[7]],p_safe[[9]], ncol=2)

plot of chunk unnamed-chunk-16

Фактический аплифт на датасете, который был в “сейфе” (модель не “видела” этих данных), достаточно близок к усредненному аплифту на тренинговом датасете, и в большинстве случаев даже лучше, чем прогнозируемый аплифт.

Посмотрим цифры поближе:

perf_safe
##       group n.ct1 n.ct0 n.y1_ct1 n.y1_ct0 r.y1_ct1 r.y1_ct0    uplift
##  [1,]     1   209   191       71       43 0.339713 0.225131  0.114582
##  [2,]     2   194   206       53       42 0.273196 0.203883  0.069312
##  [3,]     3   205   195       42       23 0.204878 0.117949  0.086929
##  [4,]     4   197   203       21       17 0.106599 0.083744  0.022855
##  [5,]     5   191   209       28       15 0.146597 0.071770  0.074827
##  [6,]     6   215   185       12        6 0.055814 0.032432  0.023382
##  [7,]     7   195   205        4       10 0.020513 0.048780 -0.028268
##  [8,]     8   199   201       60       42 0.301508 0.208955  0.092552
##  [9,]     9   201   199       68       70 0.338308 0.351759 -0.013450
## [10,]    10   200   200       66      113 0.330000 0.565000 -0.235000
## attr(,"class")
## [1] "performance"
  • n.ct1 и n.ct0 – количество клиентов в каждом сегменте для промо и контрольных групп соответственно (итого 400 в обоих выборках, 4'000 всего в 10 группах)
  • n.y1_ct1 и n.y1_ct0 – количество клиентов, сделавших покупки в промо и
    контрольных группах соответственно.

Пример расчета кумулятивного аплифта для нескольких децилей

Если глядя на синие графики, полученные на тренинговых сетах, мы бы спланировали акцию в топ-3 децилях (с учетом дисперсии) при помощи модели с глубиной взаимодействия 9:

  • в контрольной группе процент покупок был бы (43+42+23)/(191+206+195 = 18.24%
  • а в промо группе процент покупок был бы (71+53+42)/(209+194+205) = 27.3%

    что означало бы аплифт в ~ 50% (или, говоря простым языком, увеличение отклика клиентов на 50%)

Посмотрим, сможем ли мы улучшить результат путем сортировки аттрибутов по показателю NIV (кросс-валидация результатов показала,что оптимальным будет набор из топ 30 аттрибутов). Кросс-валидируем глубину взаимодействия на 30 топовых фичах:

# out_30 <- list()
# for (d in 1:10) {
#     uplift <- list()
#     for (i in 1:5) {
#         valid <- idx_valid[[i]]
#         train <- setdiff(1:nrow(full),valid)
#         NIV <- create_infotables(full[train,], y='PURCHASE', trt='TREATMENT')
#         top30_names <- c('PURCHASE','TREATMENT', NIV$Summary[1:30,'Variable'])
#         full_ <- full[,top30_names]
#         form <- as.formula(paste0('PURCHASE ~ trt(TREATMENT)+',
#                                   paste0(setdiff(colnames(full_),
#                                                  c('PURCHASE','TREATMENT','UNIQUE_ID')),
#                                          collapse='+')))
#         set.seed(123)
#         mod <- ccif(formula=form,
#                     data=full_[train,],
#                     ntree=100,
#                     interaction.depth = d,
#                     split_method='Int',
#                     verbose=F)
#         preds_valid <- predict(mod, full_[valid,])
#         uplift[[i]] <- performance(preds_valid[,1],
#                                    preds_valid[,2],
#                                    full_[valid,'PURCHASE'],
#                                    full_[valid,'TREATMENT'],
#                                    direction=1)[,'uplift']

#     }
#     upl <- do.call(rbind,uplift)
#     out_30[[d]] <- list(mn=apply(upl, 2, 'mean'), std=apply(upl, 2, 'sd'))
# }
# saveRDS(out_30, 'outInt_30.RDS')

data <- readRDS('outInt_30.RDS')
p <- list()
for (n in 1:10) {
    df = as.data.frame(data[[n]])
    p[[n]] <- ggplot(data=df, aes(x=1:nrow(df),y=mn)) +
        geom_line(col='blue',size=2) +
        geom_errorbar(aes(ymin=mn-std, ymax=mn+std)) +
        ggtitle(paste('Top30 features, tree depth,', n)) +
        scale_x_continuous(name='Decile', breaks=1:10) +
        scale_y_continuous(name='Uplift', limit=c(-.35,.35)) +
        geom_text(aes(label=round(mn,2), y=mn+std + .03))
}

grid.arrange(p[[7]],p[[10]],ncol=2)
## Warning: Removed 1 rows containing missing values (geom_errorbar).
## Warning: Removed 1 rows containing missing values (geom_text).

plot of chunk unnamed-chunk-19

Посмотрим, какой аплифт нам бы дало применение этих моделей на “боевой” выборке:

NIV <- create_infotables(data=full,
                         y='PURCHASE',
                         trt = 'TREATMENT')

top30 <- c(NIV$Summary[1:30,'Variable'],'PURCHASE','TREATMENT')

full_ <- full[,top30]

form <- as.formula(paste0('PURCHASE ~ trt(TREATMENT)+',
                          paste0(setdiff(colnames(full_),
                                         c('PURCHASE','TREATMENT','UNIQUE_ID')),
                                 collapse='+')))
p_safe <- list()
for (d in c(7,10)) {
    set.seed(123)
    mod <- ccif(formula=form,
                data=full_,
                ntree=100,
                interaction.depth=d,
                split_method="Int",
                verbose=F)

    preds_safe <- predict(mod, safe)

    perf_safe <- performance(preds_safe[,1],
                             preds_safe[,2],
                             safe$PURCHASE,
                             safe$TREATMENT,
                             direction=1)

    p_safe[[d]] <- p[[d]] + geom_line(data=NULL,
                                      aes(x=perf_safe[,1], y=perf_safe[,8]),
                                      color='green')
    }
grid.arrange(p_safe[[7]],p_safe[[10]],ncol=2)
## Warning: Removed 1 rows containing missing values (geom_errorbar).
## Warning: Removed 1 rows containing missing values (geom_text).

plot of chunk unnamed-chunk-20

Посмотрим повнимательнее на модель, построенную на Top30 аттрибутах (отфильтрованных при помощи функции NIV из пакета Information), глубина взаимодействия 10:

perf_safe
##       group n.ct1 n.ct0 n.y1_ct1 n.y1_ct0 r.y1_ct1 r.y1_ct0    uplift
##  [1,]     1   195   205       65       47 0.333333 0.229268  0.104065
##  [2,]     2   198   202       50       34 0.252525 0.168317  0.084208
##  [3,]     3   208   192       45       21 0.216346 0.109375  0.106971
##  [4,]     4   198   204       22       23 0.111111 0.112745 -0.001634
##  [5,]     5   198   202       28       17 0.141414 0.084158  0.057256
##  [6,]     6   322   332        6        6 0.018634 0.018072  0.000561
##  [7,]     7    82    63       11        5 0.134146 0.079365  0.054781
##  [8,]     8   202   197       62       48 0.306931 0.243655  0.063276
##  [9,]     9   193   207       69       79 0.357513 0.381643 -0.024130
## [10,]    10   210   190       67      101 0.319048 0.531579 -0.212531
## attr(,"class")
## [1] "performance"

Для топ-3 децилей (которые мы бы определили исходя из поведения нашей модели на тренинговом сете, с учетом дисперсии прогнозов):

  • отклик для контрольной группы: (47+34+21)/(205+202+192)= 17%
  • отклик для промо группы: (65+50+45)/(195+198+208) = 26.6%

что составляет ~ 56% аплифт

Заключение

Планирование промо-акций должно учитывать не вероятность отклика клиента (купит/не купит), а маржинальный эффект промо акции на решение индивидуума:

  • клиент уже принял решение купить, маржинальный эффект ноль – такого клиента нет смысла включать в промо акцию.
  • вне зависимости от характера промо-предложения клиент не сделает покупку (или затраты на промо на данного клиента превысят возможные выгоды от принятия клиентом предложения). Маржинальный эффект нулевой или отрицательный. Такого клиента также нет смыслы включать в промо акцию.
  • и наконец, сравнив невыгодность “промо” предложения с другими доступными опциями, клиент может разорвать контракт с компанией. Маржинальный эффект отрицательный.

Наиболее оптимальным клиентом для промо акции является индиивидуум, у которого веротяность совершения покупки, вследствие участия в промо, возрастет (“persuadables”).

R, программная среда статистической обработки и анализа данных, предоставляет несколько инструментов для аплифт моделирования, которые позволяют спланировать промо акции оптимальным образом, увеличивая вероятность отклика клиента на 50 и более процентов.

Помимо увеличения процента отклика в промо акциях, аплифт моделирование используется для оптимизации и увеличения ROI маркетинговых кампаний в таких отраслях как:

  • заказы по каталогам
  • снижение оттока клиентов
  • определение ценовой эластичности клиента
  • upselling and cross-selling
Write a comment:

*

Your email address will not be published.

© 2014 In R we trust.
Top
Follow us: