Как маркетологу рассчитать доверительный интервал? И зачем?

Правильный ответ "маркетологу ничего расчитывать не нужно. Он все будет делать субъективно и принимать решения основываясь на интуиции, а не на данных." Маркетолог вообще должен работать, так как ему удобно, а не эффективно.

Если, вы все же решили посчитать этот confidence interval, то есть нюансы. Возьмем данные из live-demo, которое показывает посещаемость страницы metrica.yandex.com/promo/product. Просто скачаем данные по прямой ссылке (нужно иметь аккаунт в Яндексе).

Как скачать данные для расчета доверительного интервала
Как скачать данные для расчета доверительного интервала

Предположим, я маркетолог, скачал данные за 7 дней и получил конверсию:
"Для любых целей" - 16.68%
"Для избранных целей" - 8.79%

Самое простое решение которое приходит в голову, это использовать онлайн калькулятор (как учат на курсах по маркетингу). Куда тут это надо подставлять:

Пример калькулятора дововерительного интервала с нашего любимого сайта
Пример калькулятора дововерительного интервала с нашего любимого сайта

Ну в "Оценка конверсии" надо вставить среднюю конверсию за период. Я ее только что подсчитал, а вот что такое "Пользователей в выборке"? Это типа "выборка из генеральной совокупности"?Пользователей вообще в рекламе не считают. Может это визиты или сессии (если это Гугл)? Но у нас есть подсказка - N (большая). Ага! Обычно n маленькой записывают число наблюдений в выборке. А их у меня было 7.

Размышляя таким образом, я получу доверительные интервалы:

-10.94% – 44.30% "Для любых целей" и

-12.19% – 29.77% "Для избранных целей"

Интервалы получились довольно широкие, т.к. наблюдений в выборке всего 7.

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

lower_bound = mean - z * standard_error upper_bound = mean + z * standard_error

где,

z = norm.ppf(1 - (1 - confidence) / 2) # для степени значимости 0.95 (определяется по табличке)

Загрузим данные:

import pandas as pd df = pd.read_excel('названиефайла.xlsx', skiprows=5) df = df.drop(index=0) # удалил первую строку с суммой df['Дата визита'] = pd.to_datetime(df['Дата визита']) df = df.set_index('Дата визита') df['CR1'] = df['Достижения любой цели'] / df['Визиты'] df['CR2'] = df['Достижения избранных целей'] / df['Визиты']
В Метрике по 2м осям график строить нельзя, а в Питоне можно.
В Метрике по 2м осям график строить нельзя, а в Питоне можно.

Выполним расчеты:

from scipy.stats import norm def normal_confidence_interval(data, confidence=0.95): mean = data.mean() std_dev = data.std() n = len(data) # Z-значение для заданного уровня доверия z = norm.ppf(1 - (1 - confidence) / 2) # Стандартная ошибка standard_error = std_dev / (n ** 0.5) # Вычисление границ доверительного интервала lower_bound = mean - z * standard_error upper_bound = mean + z * standard_error return lower_bound, upper_bound cr_data = df[:7]['CR1'].values # Извлекаем столбец CR (для Всех целей) за 7 последних дней # Рассчитываем доверительный интервал для нормального распределения lower, upper = normal_confidence_interval(cr_data) print(f'Доверительный интервал для CR (нормальное распределение): {lower:.4%} - {upper:.4%}')
cr_data = df[:7]['CR2'].values # Извлекаем столбец CR (для Избранных целей) за 7 последних дней # Рассчитываем доверительный интервал для нормального распределения lower, upper = normal_confidence_interval(cr_data) print(f'Доверительный интервал для CR (нормальное распределение): {lower:.4%} - {upper:.4%}')

Получатся интервалы:

14.3525% - 19.0226% для "Для любых целей" и

7.6046% - 9.9917% для "Для избранных целей"

Результат сильно отличается от расчетов на калькуляторе.

Но начальник может мне сказать "Т.к. данные всего за 7 дней, доверительный интервал должен получится очень широкий". И в чем-то будет прав. Поэтому, я скачал данные за 1277 дней и давайте немного модифицируем код:

cr_data = df['CR1'].values # Извлекаем столбец CR полностью cr_data = df['CR2'].values # По аналогии

Получились интервалы:

18.9746% - 19.5771% для "Для любых целей" и

10.7067% - 11.0474% для "Для избранных целей"

Действительно, интервалы стали уже, но не такими уже и узкими.

Подставлю те же данные в онлайн калькулятор.

Данные надо вводить в формате ХХ.YY почему-то.
Данные надо вводить в формате ХХ.YY почему-то.

Результат:

17.06% – 21.48% для "Для любых целей"

9.16% – 12.58% для "Для избранных целей"

Интервал получился уже, но отличается от Питона. Сколько ж ему наблюдений надо, чтобы стало совсем узко?

Но, начальник скажет: "Ты рассчитал доверительный интервал для нормального распределения, а данные по конверсии не распределены нормально". Откуда он это знает? Он что тест Колмогорова-Смирнова на нормальность сделал? А в учебнике написано "Важно: рассчитать доверительный интервал можно только для нормально распределённых данных." Обратите на это внимание!!!

Взглянем на гистограмму данных:

K-S statistic: 0.0355644035434876
P-value: 0.07720119905342071
Распределение похоже на нормальное (не отвергаем гипотезу о нормальности).
K-S statistic: 0.0355644035434876 P-value: 0.07720119905342071 Распределение похоже на нормальное (не отвергаем гипотезу о нормальности).

Давайте Q-Q диаграмму я строить не буду. Оставим это для факультативного изучения. Ну, p-value 0.07 такое себе, все равно очень маленькое, так что скорее всего начальник прав, т.к. видно несколько центров данных. Обычно данные по конверсии сильно разрежены, и получается сверхтяжелый хвост около нуля (возможно, данные для примера я не самые удачные взял).

И надо использовать метод бутстрэппинга, код на Питоне будет вот такой:

import pandas as pd def bootstrap_interval_pandas(data, num_bootstrap=10000, confidence=0.95): bootstrap_means = [] # Выполняем бутстрэппинг num_bootstrap раз for _ in range(num_bootstrap): # Делаем выборку с возвращением и считаем среднее bootstrap_sample = data.sample(frac=1, replace=True) bootstrap_means.append(bootstrap_sample.mean()) # Преобразуем результаты в Series для удобной обработки bootstrap_means = pd.Series(bootstrap_means) # Находим нижнюю и верхнюю границы доверительного интервала lower_bound = bootstrap_means.quantile((1 - confidence) / 2) upper_bound = bootstrap_means.quantile(1 - (1 - confidence) / 2) return lower_bound, upper_bound cr_data = df['CR1'] # Извлекаем столбец CR1 и CR2 по аналогии # Тесты с разным количеством бутстрэппинг-выборок num_bootstraps = [100, 10000, 100000] for num in num_bootstraps: lower, upper = bootstrap_interval_pandas(cr_data, num_bootstrap=num) print(f'Доверительный интервал для CR при {num} выборках (бутстрэппинг): {lower:.4%} - {upper:.4%}')

И получаем результат для "Всех целей":

Доверительный интервал для CR при 100 выборках (бутстрэппинг): 18.9441% - 19.5777%

Доверительный интервал для CR при 10000 выборках (бутстрэппинг): 18.9707% - 19.5781%

Доверительный интервал для CR при 100000 выборках (бутстрэппинг): 18.9748% - 19.5754%

И для "Избранных целей":

Доверительный интервал для CR при 100 выборках (бутстрэппинг): 10.6679% - 11.0312%

Доверительный интервал для CR при 10000 выборках (бутстрэппинг): 10.7074% - 11.0477%

Доверительный интервал для CR при 100000 выборках (бутстрэппинг): 10.7055% - 11.0471%

Т.е. я сделал 100, 10 тыс. и 100 тыс. выборок из данных, и результаты получились аналогичные с методом для нормального распределения. Т.е. больше 10 тыс. выборок можно было и не делать.

Так что же я только что посчитал? Я же должен был объяснить в начале статьи зачем доверительные интервалы расчитывать.

Доверительный интервал нужен, для того чтобы:

1. Оценить истинный диапазон значений.

2. Указать на надежность оценки измерения.

Если мы загрузили данные за 7 дней, это много или мало? Конверсия же может отклонятся от средней в ту или иную сторону. Насколько надежная такая оценка? Именно на эти вопросы и отвечает доверительный интервал. Если этот интервал "широкий", значит такая оценка не очень надежна. Если же "узкий", то наоборот.

Выводы:

В этой статье я рассмотрел вопрос, почему не стоит использовать всякие непонятные онлайн калькуляторы на сайтах. Т.к. вы не знаете, какие программисты и по каким формулам их писали.

Все доверительные интервалы рассчитанные разными способами получились примерно одинаковыми. Тем не менее, вопрос "Как именно дисперсия влияет на ширину доверительного интервала?" остается открытым.

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

Если вы хотите, чтобы я написал статью по расчету доверительного интервала в Excel, напишите мне в комментариях об этом.

33
2 комментария

Хорошая подача инфомарции, о проблемах насущих, +1 лайк за стаью!

1
Ответить

Занимательно! Тема важная и нужная, теперь жду статью про расчёт в Эксцеле👏

1
Ответить