В данном ноутбуке рассмотрим простой пример применения одного из подходов прогнозирования uplift в sklearn.pipeline.
Данные для примера взяты из MineThatData E-Mail Analytics And Data Mining Challenge dataset by Kevin Hillstrom. Этот набор данных содержит 64 000 клиентов, которые в последний раз совершали покупки в течение двенадцати месяцев. Среди клиентов была проведена рекламная кампания с помощью email рассылки:
Для каждого клиента из выборки замерили факт перехода по ссылке в письме, факт совершения покупки и сумму трат за две недели, следущими после получения письма.
Полное описание датасета можной найти по ссылке.
Установим необходимые библиотеки:
# pip install scikit-uplift xgboost==1.0.2 category_encoders==2.1.0 -U
Для простоты примера оставим только два сегмента пользователей:
В качестве целевой переменной будем использовать переменную visit
.
import pandas as pd
from sklift.datasets import fetch_hillstrom
%matplotlib inline
bunch = fetch_hillstrom(target_col='visit')
dataset, target, treatment = bunch['data'], bunch['target'], bunch['treatment']
print(f'Размер датасета до обработки: {dataset.shape}')
# Selecting two segments
dataset = dataset[treatment!='Mens E-Mail']
target = target[treatment!='Mens E-Mail']
treatment = treatment[treatment!='Mens E-Mail'].map({
'Womens E-Mail': 1,
'No E-Mail': 0
})
print(f'Размер датасета после обработки: {dataset.shape}')
dataset.head()
Размер датасета до обработки: (64000, 8) Размер датасета после обработки: (42693, 8)
recency | history_segment | history | mens | womens | zip_code | newbie | channel | |
---|---|---|---|---|---|---|---|---|
0 | 10 | 2) $100 - $200 | 142.44 | 1 | 0 | Surburban | 0 | Phone |
1 | 6 | 3) $200 - $350 | 329.08 | 1 | 1 | Rural | 1 | Web |
2 | 7 | 2) $100 - $200 | 180.65 | 0 | 1 | Surburban | 1 | Web |
4 | 2 | 1) $0 - $100 | 45.34 | 1 | 0 | Urban | 0 | Web |
5 | 6 | 2) $100 - $200 | 134.83 | 0 | 1 | Surburban | 0 | Phone |
Разобъем все данные на обучающую и валидационную выборку:
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val, treat_tr, treat_val = train_test_split(
dataset, target, treatment, test_size=0.5, random_state=42
)
Select categorical features:
cat_cols = X_tr.select_dtypes(include='object').columns.tolist()
print(cat_cols)
['history_segment', 'zip_code', 'channel']
Создадим нужные объекты и объединим их в pipieline.
from sklearn.pipeline import Pipeline
from category_encoders import CatBoostEncoder
from sklift.models import ClassTransformation
from xgboost import XGBClassifier
encoder = CatBoostEncoder(cols=cat_cols)
estimator = XGBClassifier(max_depth=2, random_state=42)
ct = ClassTransformation(estimator=estimator)
my_pipeline = Pipeline([
('encoder', encoder),
('model', ct)
])
Обучать pipeline будем как обычно, но колонку treatment добавим как параметр шага model: model__treatment
.
my_pipeline = my_pipeline.fit(
X=X_tr,
y=y_tr,
model__treatment=treat_tr
)
/Users/Maksim/Library/Python/3.6/lib/python/site-packages/sklearn/pipeline.py:354: UserWarning: It is recommended to use this approach on treatment balanced data. Current sample size is unbalanced. self._final_estimator.fit(Xt, y, **fit_params)
Предскажем uplift и посчитаем uplift@30%
from sklift.metrics import uplift_at_k
uplift_predictions = my_pipeline.predict(X_val)
uplift_30 = uplift_at_k(y_val, uplift_predictions, treat_val, strategy='overall')
print(f'uplift@30%: {uplift_30:.4f}')
uplift@30%: 0.0661