Вы бы сыграли в пасьянс тысячу раз, чтобы понять, как часто вы будете выигрывать, или вы просто имитируете размеры выборки, используя структуру цикла? Что легче и достижимо? Смогу ли я прожить достаточно долго, чтобы раскладывать пасьянсы сто тысяч раз? Я думаю, что вместо этого я приму вычисления. Однако эта статья будет посвящена не пасьянсу, а маркетинговой кампании.

Ойя, давайте начнем с понимания того, что такое моделирование Монте-Карло.

Моделирование по методу Монте-Карло — это численный метод, основанный на повторной случайной выборке для получения численных результатов, позволяющих понять влияние риска и неопределенности в моделях предсказания и прогнозирования. Он используется для моделирования вероятности результатов в процессах, которые трудно предсказать из-за большого разнообразия сценариев.

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

Давайте теперь перейдем к сделке дня.

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

Для достижения нашей цели мы можем смоделировать маркетинговую кампанию для продаж, используя вероятности продаж для каждого клиента, который у нас есть в наборе данных. Имитационное моделирование позволило бы нам выбрать параметры min_probability и max_probability, которые дают нам список клиентов, с которыми необходимо связаться.

Чтобы улучшить нашу модель, мы можем попытаться вычислить, повысит или уменьшит ли телефонный звонок клиенту вероятность продажи (рост продаж), если у нас есть данные о предыдущих контактах с клиентами. Поскольку у нас его нет, мы бы выбрали простую модель аплифта —  вероятность продажи увеличится на 0,1, если клиенту позвонит представитель клиента.

Функция прибыли от телефонных звонков:

Прибыль = N-продаж * средн.(доход-продажа) - N-контактов * ср.(затраты-контакты)

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

импорт зависимостей

import pandas as pd
import numpy.random as rnd
import numpy as np

чтение данных в среду

data = pd.read_csv(‘sale_probability.csv’)

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

result = []
def monte_carlo_coin(probability):
    r = rnd.uniform()
    return int(r < probability)
def profit(n_sales, n_contacts):
    avg_income_sale = 10.0
    avg_costs_contact = 2.0
    return n_sales*avg_income_sale - n_contacts*avg_costs_contact

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

В этой ячейке выше созданы две функции; (i) monte_carlo_coin и (ii) прибыль.

- Функция monte_carlo_coin должна возвращать логическое значение (True и False), преобразованное в 0 и 1. Функция проверяет и возвращает 1, если вероятность продажи больше, чем сгенерированное случайное число, в противном случае функция возвращает 0.

- Функция прибыли содержит два аргумента n_sales и n_contact, это в основном для расчета прибыли, где средняя стоимость контакта и средний доход от продажи составляют 2 доллара и 10 долларов соответственно.

Вам может быть интересно, для чего они нужны, но подождите. Вы поймете лучше, когда мы их применим.

Теперь давайте сделаем реальную сделку

for min_probability in np.arange(0.0,0.9,0.1):
    for max_probability in np.arange(min_probability+0.1,1.0,0.1):
        # uplift
        target_group = data.probabilities.between(min_probability, max_probability)
        data_after_contact = data.copy()
        data_after_contact.ix[target_group, 'probabilities'] = data.ix[target_group].probabilities + 0.1
        
        prof = 0
        for _ in range(10):
            # simulation
            data_after_contact['sales'] = data_after_contact['probabilities'].apply(monte_carlo_coin)
# results
            sales = data_after_contact['sales'].sum(axis=0)
            calls = target_group.sum(axis=0)
            prof += profit(sales, calls)
        prof /= 10
        result.append((min_probability, max_probability, sales, calls, prof))

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

Каждая из первых двух строк ячейки дает по 45 наборов чисел с общими различиями в каждом цикле. Вы можете запустить запуск первых двух строк в отдельной ячейке, а затем напечатать (min_probability, max_probability), чтобы увидеть, что происходит. На этом основан остальной код.

Давайте двигаться дальше.

Да, давайте создадим таблицу данных, называемую целевой группой, эта таблица предназначена для предоставления нам списка клиентов, с которыми необходимо связаться. Данные о целевой группе воспроизводят данные о вероятности продаж 45 раз. И что происходит каждый раз? Он проверяет, находятся ли вероятности продаж между параметрами min_probability и max_probability, т. е. в первый раз он проверяет, находятся ли все данные вероятности продаж между 0,0 и 0,1, в следующий раз — между 0,0 и 0,2, и продолжает таким образом до конца, возвращая логическое значение в каждом кейс.

Я думаю, это понятно, теперь у нас есть таблица вероятностей продаж в …

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

Затем к следующей строке кода вероятность продаж клиентов, с которыми свяжутся, повышается за счет увеличения их на 0,1 — клиенты в целевой группе, которые имеют значение True — те, у кого значения False, т. е. те, с которыми не связывались, остаются без изменений. Затем эти увеличенные данные сопоставляются с воспроизведенными исходными данными вероятности продаж.

Ага! Это оно. Мы как раз собираемся сделать большую сделку в Маунт-Карло. А не ___ ли нам?

Но прежде чем мы продолжим, давайте попробуем воспользоваться преимуществами случайности, усредненности и изменчивости. Это будет сделано путем воспроизведения наших поднятых результатов определенное количество раз, и ради этого примера мы выберем 10. Имейте в виду, что мы получим среднее значение, разделив наши результаты на 10 в конце. Цикл предназначен только для использования случайности. Как вы знаете, вычисление среднего возраста доступных 50 учеников в классе, скажем, из 60, является лучшим представлением возраста учеников в этом классе, чем вычисление среднего 20. Здесь мы сделали бы только 10.

Ладно, к делу

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

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

Теперь вызывается функция прибыли для расчета прибыли, полученной с использованием количества звонков и количества продаж. Вуаля! Я думаю, что мы крутые сейчас. Но прежде чем мы пойдем, нам нужно взглянуть и получить представление о том, во что мы вложили так много времени.

pd.DataFrame(result, columns=['Minimal probability', 'Maximum probability', 'No of sales', 'No of calls', 'Profit'])

In [10]: best_results = sorted(result, key=lambda x: x[4])
best_results[-1]
Out[10]: (0.5, 0.7999999999999999, 18814, 215, 186950.0)
In [11]: best_results[-3::1]
Out[11]: [(0.5, 0.8999999999999999, 18760, 227, 186785.0),
 (0.7000000000000001, 0.8, 18649, 28, 186926.0),
 (0.5, 0.7999999999999999, 18814, 215, 186950.0)]

В результате мы получаем целевую группу клиентов для контакта. Целевая группа имеет средний диапазон значений вероятности, а именно от 0,5 до 0,8 (наименьшая минимальная_вероятность и наибольшая максимальная_вероятность среди трех лучших результатов), поскольку клиенты с низкими значениями вероятности не купят продукт, даже если им позвонят, в то время как клиенты с высокой вероятностью для продажа уже решила купить товар и звонок не помог.

Эта статья открыта для критики и предложений. Я буду работать над улучшением этой версии.

Наилучшие пожелания.