О чём эта серия статей?
Добро пожаловать в мою серию статей о причинно-следственном искусственном интеллекте, где мы рассмотрим интеграцию причинно-следственных рассуждений в модели машинного обучения. Ожидайте изучения ряда практических приложений в различных бизнес-контекстах.
В последней статье мы рассмотрели оптимизацию нелинейных эффектов лечения в ценообразовании и продвижении. На этот раз мы рассмотрим измерение внутреннего причинного влияния ваших маркетинговых кампаний.
Если вы пропустили последнюю статью о нелинейных эффектах лечения в ценообразовании и продвижении, ознакомьтесь с ней здесь:
Оптимизация нелинейных эффектов лечения в ценообразовании и продвижении
Введение
В этой статье я помогу вам понять, как можно измерить внутреннее причинное влияние ваших маркетинговых кампаний.
Будут рассмотрены следующие аспекты:
- Каковы проблемы, связанные с измерением маркетинга?
- Что такое внутреннее причинное влияние и как оно работает?
- Практический пример в Python, показывающий, как мы можем использовать внутреннее причинное влияние, чтобы отдать должное маркетинговым кампаниям.
Полную записную книжку можно найти здесь:
causal_ai/notebooks/понимание внутреннего причинного влияния ваших маркетинговых кампаний.ipynb…
Каковы проблемы, связанные с измерением маркетинга?
Какие существуют типы маркетинговых кампаний?
Организации используют маркетинг для развития бизнеса, привлекая новых клиентов и удерживая существующих. Маркетинговые кампании часто делятся на 3 основные категории:
- Бренды;
- Производительность;
- Удержание.
У каждой из них есть свои уникальные проблемы, связанные с измерением — понимание этих проблем имеет решающее значение.
Бренды
Цель брендовых кампаний — повысить узнаваемость вашего бренда среди новой аудитории. Они часто проводятся на телевидении и в социальных сетях, причём последние часто в формате видео. У них обычно нет прямого призыва к действию, например, «наш продукт прослужит вам всю жизнь».
Проблема с измерением телевидения очевидна — мы не можем отследить, кто видел телевизионную рекламу! Но у нас есть аналогичные проблемы и с социальными сетями — если я смотрю видео в VK, а затем органически захожу на сайт и покупаю продукт на следующий день, очень маловероятно, что мы сможем связать эти два события.
Существует также вторичная проблема отсроченного эффекта. При повышении осведомлённости среди новой аудитории может потребоваться несколько дней/недель/месяцев, чтобы они дошли до момента, когда начнут рассматривать возможность покупки вашего продукта.
Существует спорный аргумент, что брендовые кампании выполняют всю тяжёлую работу — однако, когда дело доходит до измерения маркетинга, они часто недооцениваются из-за некоторых проблем, которые мы выделили выше.
Кампании по производительности
В целом кампании по производительности нацелены на клиентов, заинтересованных в вашем продукте. Они проводятся через платные поисковые системы, социальные сети и партнёрские каналы. У них обычно есть призыв к действию, например, «нажмите сейчас, чтобы получить скидку 5% на вашу первую покупку».
Когда дело доходит до кампаний по производительности, не сразу очевидно, почему их сложно измерить. Вполне вероятно, что мы сможем связать событие, когда клиент нажимает на кампанию по производительности, и покупку этого клиента в тот же день.
Но нажал бы он, если бы не был знаком с брендом? Как он познакомился с брендом? Купили бы они органически, если бы мы не показали им кампанию? На эти вопросы сложно ответить с точки зрения науки о данных!
Кампании по удержанию
Другая категория кампаний — удержание. Это маркетинг, направленный на удержание существующих клиентов. Мы обычно проводим A/B-тесты для измерения этих кампаний.
График приобретения маркетинга
Обычно брендовые и производительные кампании называют маркетингом для привлечения клиентов. Как я уже упоминал ранее, сложно измерить брендовые и производительные кампании — мы часто недооцениваем брендовые кампании и переоцениваем производительные.
График ниже является мотивирующим (но упрощённым) примером того, как работает маркетинг для привлечения клиентов:
[Изображение]
Как мы можем (справедливо) оценить, какой вклад внёс каждый узел в доход? Здесь в игру вступает внутреннее причинное влияние — давайте разберёмся, что это такое в следующем разделе!
Что такое внутреннее причинное влияние и как оно работает?
Откуда взялась концепция?
Концепция была первоначально предложена в статье в 2020 году, с обновлением в этом году:
Количественная оценка внутренних причинных вкладов посредством структурных вмешательств, сохраняющих структуру
Она реализована в модуле GCM в рамках пакета Python DoWhy:
Количественная оценка внутреннего причинного влияния — документация DoWhy
Я лично обнаружил, что эту концепцию поначалу было довольно сложно понять, поэтому в следующем разделе давайте разберём её шаг за шагом.
Краткий обзор о причинных графах
Прежде чем мы попытаемся понять внутреннее причинное влияние, важно иметь представление о причинных графах, структурных причинных моделях (SCM) и аддитивных шумовых моделях (ANM). Моя статья ранее в этой серии должна помочь вам ознакомиться с ними:
Использование причинных графов для ответа на причинные вопросы
Каждый узел в причинном графе можно рассматривать как цель в модели, где его прямые родители используются в качестве признаков. Обычно для каждого неукоренившегося узла используется аддитивная шумовая модель:
[Изображение]
Что на самом деле представляет собой внутреннее причинное влияние?
Теперь, когда мы повторили основные моменты о причинных графах, давайте начнём разбираться, что такое внутреннее причинное влияние…
Словарное определение слова «внутренний» — «принадлежит естественно». В моей голове я думаю о воронке, и то, что находится наверху воронки, выполняет большую часть работы — мы хотим приписать им ту причинную связь, которую они заслуживают.
Давайте рассмотрим пример ниже, чтобы помочь нам разобраться во внутреннем причинном влиянии:
[Изображение]
- A, B и C — корневые узлы.
- D — неукоренившийся узел, который мы можем смоделировать, используя его прямых родителей (A, B, C) и шумовой термин.
- E — неукоренившийся узел, который, как и D, мы можем смоделировать, используя его прямых родителей (A, B, C) и шумовой термин.
- F — целевой узел, который мы можем смоделировать, используя его прямых родителей (D, E) и шумовой термин.
Давайте сосредоточимся на узле D. Он наследует часть своего влияния на узел F от узлов A, B и C. Внутренняя часть его влияния на узел F, та часть, которая не была просто «унаследована» от A, B и C, исходит от шумового термина. Поэтому мы говорим, что каждый шумовой термин узла может быть использован для оценки внутреннего причинного влияния на целевой узел. Стоит отметить, что корневые узлы состоят только из шума.
В кейсе мы углубимся в то, как именно рассчитать внутреннее причинное влияние.
Как это может помочь нам измерить наши маркетинговые кампании?
Надеюсь, вы уже видите связь между примером маркетинга для привлечения клиентов и внутренним причинным влиянием — может ли внутреннее причинное влияние помочь нам перестать недооценивать брендовые кампании и перестать переоценивать производительные кампании? Давайте узнаем в примере!
Пример
Предыстория
Приближается конец года, и директор по маркетингу находится под давлением со стороны финансового отдела, который требует объяснить, зачем тратить столько денег на маркетинг в следующем году. Финансовый отдел использует модель последнего клика, в которой выручка приписывается последнему просмотренному клиентом элементу. Они задаются вопросом, зачем вообще тратить деньги на телевидение, когда все приходят через органические или социальные каналы!
Перед командой Data Science поставлена задача оценить внутреннее причинное влияние каждого маркетингового канала.
Настройка графа (DAG)
Мы начинаем с настройки DAG, используя экспертные знания в предметной области, повторно используя пример маркетинга для привлечения клиентов, который мы рассматривали ранее:
node_lookup = {0: 'Спрос',
1: 'ТВ-расходы',
2: 'Социальные расходы',
3: 'Органические клики',
4: 'Социальные клики',
5: 'Выручка'
}
total_nodes = len(node_lookup)
graph_actual = np.zeros((total_nodes, total_nodes))
graph_actual[0, 3] = 1.0
graph_actual[0, 4] = 1.0
graph_actual[1, 3] = 1.0
graph_actual[2, 3] = 1.0
graph_actual[1, 4] = 1.0
graph_actual[2, 4] = 1.0
graph_actual[3, 5] = 1.0
graph_actual[4, 5] = 1.0
По сути, модель последнего клика, которую использует финансовый отдел, использует только прямых родителей выручки для измерения маркетинга.
[Изображение]
Процесс генерации данных
Мы создаём несколько выборок данных, следуя процессу генерации данных DAG:
3 корневых узла, состоящих из шумовых терминов; спрос, расходы на бренд и социальные расходы.
2 неукоренившихся узла, наследующие влияние от 3 корневых узлов плюс некоторые шумовые термины; органические клики, социальные клики.
1 целевой узел, наследующий влияние от 2 неукоренившихся узлов плюс шумовой термин; выручка.
df = pd.DataFrame(columns=node_lookup.values())
df[node_lookup[0]] = np.random.normal(100000, 25000, size=(20000)) df[node_lookup[1]] = np.random.normal(100000, 20000, size=(20000)) df[node_lookup[2]] = np.random.normal(100000, 25000, size=(20000)) df[node_lookup[3]] = 0.75 * df[node_lookup[0]] + 0.50 * df[node_lookup[1]] + 0.25 * df[node_lookup[2]] + np.random.normal(loc=0, scale=2000, size=20000) df[node_lookup[4]] = 0.30 * df[node_lookup[0]] + 0.50 * df[node_lookup[1]] + 0.70 * df[node_lookup[2]] + np.random.normal(100000, 25000, size=(20000)) df[node_lookup[5]] = df[node_lookup[3]] + df[node_lookup[4]] + np.random.normal(loc=0, scale=2000, size=20000)
Обучение SCM
Теперь мы можем обучить SCM, используя модуль GCM из пакета Python DoWhy. Мы настраиваем процесс генерации данных с линейными отношениями, поэтому мы можем использовать гребневую регрессию в качестве причинного механизма для каждого неукоренившегося узла:
graph = nx.from_numpy_array(graph_actual, create_using=nx.DiGraph)
graph = nx.relabel_nodes(graph, node_lookup)
causal_model = gcm.InvertibleStructuralCausalModel(graph)
causal_model.set_causal_mechanism('Demand', gcm.EmpiricalDistribution())
causal_model.set_causal_mechanism('TV spend', gcm.EmpiricalDistribution())
causal_model.set_causal_mechanism('Social spend', gcm.EmpiricalDistribution())
causal_model.set_causal_mechanism('Organic clicks', gcm.AdditiveNoiseModel(gcm.ml.create_ridge_regressor()))
causal_model.set_causal_mechanism('Social clicks', gcm.AdditiveNoiseModel(gcm.ml.create_ridge_regressor()))
causal_model.set_causal_mechanism('Revenue', gcm.AdditiveNoiseModel(gcm.ml.create_ridge_regressor()))
gcm.fit(causal_model, df)
Альтернативно мы можем использовать функцию auto_assignment для автоматического назначения моделей (вместо их ручного определения).
Я пропущу оценку модели, так как это не в центре внимания моей статьи. Однако мы можем оценить причинную модель, используя GCM:
Оценка GCM — документация DoWhy
Внутреннее причинное влияние
Мы можем легко вычислить внутреннее причинное влияние, используя модуль GCM. Мы делаем это и преобразуем вклады в проценты:
ici = gcm.intrinsic_causal_influence(causal_model, target_node='Revenue')
def convert_to_percentage(value_dictionary):
total_absolute_sum = np.sum([abs(v) for v in value_dictionary.values()])
return {k: round(abs(v) / total_absolute_sum * 100, 1) for k, v in value_dictionary.items()}
convert_to_percentage(ici)
[Изображение]
Давайте покажем это на гистограмме:
df = pd.DataFrame(list(ici.items()), columns=['Node', 'Внутреннее причинное влияние'])
plt.figure(figsize=(10, 6))
sns.barplot(x='Node', y='Внутреннее причинное влияние', data=df)
plt.xticks(rotation=45)
plt.title('Гистограмма из данных словаря')
plt.show()
[Изображение]
Являются ли наши результаты интуитивно понятными? Если вы посмотрите на код, генерирующий данные, вы увидите, что они такие! Обратите внимание на то, что наследуется каждым неукоренившимся узлом и какой дополнительный шум добавляется.
Модуль внутреннего причинного влияния действительно прост в использовании, но он не помогает нам понять метод, лежащий в его основе — чтобы закончить, давайте разберёмся, как работает внутреннее причинное влияние!
Внутреннее причинное влияние — как это работает?
Мы хотим оценить, какой вклад вносит шумовой термин каждого узла в целевой узел:
- Стоит помнить, что корневые узлы состоят только из шумового термина.
- В неукоренившихся узлах мы отделяем шумовой термин от того, что было унаследовано от родителей.
- Мы также включаем шумовой термин из целевого узла — это можно интерпретировать как вклад ненаблюдаемых конфаундеров или невидимых факторов, влияющих на выручку, но не на узлы выше по течению (хотя это также может быть связано с неправильной спецификацией модели).
- Шумовые термины затем используются для объяснения дисперсии в целевом узле — это можно увидеть как модель с шумовыми терминами в качестве признаков и целевым узлом в качестве результата.
- Модель используется для оценки условного распределения целевого узла при заданных подмножествах шумовых переменных.
- Затем используется Shapley для оценки вклада каждого шумового термина — если изменение шумового термина мало влияет на цель, то внутреннее причинное влияние будет очень маленьким.
Заключительные мысли
Сегодня мы рассмотрели, как можно оценить внутреннее причинное влияние ваших маркетинговых кампаний. Вот несколько заключительных мыслей:
- Внутреннее причинное влияние — это мощная концепция, которую можно применять в разных случаях использования, а не только в маркетинге.
- Понимание внутренней работы поможет вам применять его более эффективно.
- Выявление DAG и точная оценка графика являются ключом к получению разумных оценок внутреннего причинного влияния.
- В примере с маркетингом для привлечения клиентов вы можете подумать о добавлении запаздывающих эффектов для брендового маркетинга.
Подписывайтесь на меня, если хотите продолжить это путешествие в мир причинно-следственного искусственного интеллекта — в следующей статье мы рассмотрим, как можно проверить и откалибровать наши причинные модели, используя синтетический контроль.
Ссылки
- Dominik Janzing, Patrick Blöbaum, Atalanti A Mastakouri, Philipp M Faller, Lenon Minorics, Kailash Budhathoki. “Quantifying intrinsic causal contributions via structure preserving interventions”; Proceedings of The 27th International Conference on Artificial Intelligence and Statistics, PMLR 238:2188–2196: https://proceedings.mlr.press/v238/janzing24a.html
- Patrick Blöbaum, Peter Götz, Kailash Budhathoki, Atalanti A. Mastakouri, Dominik Janzing. “DoWhy-GCM: An Extension of DoWhy for Causal Inference in Graphical Causal Models”; Journal of Machine Learning Research, MLOSS 25(147):1−7, 2024: https://jmlr.org/papers/v25/22-1258.html
