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

Поэтому мы искали инструмент для решения этих задач, поскольку искусственный интеллект невозможно было обучить на ограниченном количестве необработанных данных. Таким образом, мы обратились к статистическим подходам, а именно к байесовской статистике с помощью пакета Python PyMC. Я объясню теорию, на которой он основан, и опишу ее на примере обнаружения мошенничества с игральными кубиками.

Байесовская статистика

Байесовская статистика — это раздел статистики, который использует теорему Байеса для обновления наших представлений о вероятности гипотезы по мере поступления новых данных. Теорема Байеса гласит, что вероятность гипотезы (H) с учетом некоторых данных (D) равна вероятности данных с учетом гипотезы (D|H), умноженной на априорную вероятность гипотезы (p(H)), деленную на общую вероятность данных (p(D)). Это позволяет нам обновлять наши представления о гипотезе по мере поступления новых данных, а не полагаться только на имеющиеся данные.

Одним из самых популярных пакетов Python для реализации байесовской статистики является PyMC. PyMC — это мощный пакет, который позволяет пользователям легко определять, подбирать и анализировать байесовские модели. Он включает в себя множество встроенных распределений, таких как нормальное, биномиальное и распределение Пуассона, а также множество выборок, таких как Metropolis-Hastings и No-U-Turn Sampler (NUTS). PyMC также включает в себя множество удобных инструментов для диагностики и визуализации результатов вашей модели.

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

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

В байесовской статистике используются термины априорная вероятность и апостериорная вероятность. Априорная вероятность — это распределение вероятностей до того, как были просмотрены какие-либо данные. По сути, он показывает возможный диапазон исходов для всех предполагаемых параметров, полученных путем простого угадывания. Это обозначается как p(H). Апостериорная вероятность, однако, представляет собой распределение с учетом данных, т. е. (D|H), умноженное на p(H).

Бросание поддельного игрального кубика

В качестве примера мы используем PyMC для моделирования бросков игрального кубика. 

Мы хотим выяснить, был ли подделан игральный кубик или его можно использовать. Мы задаем, что вероятность выпадения каждой грани (1-6) моделируется распределением Дирихле с равной вероятностью для хорошего игрального кубика. 

Мы также предполагаем, что наблюдаемые данные, являющиеся результатом броска игрального кубика, следуют категориальному распределению с параметром p, то есть предполагаемой вероятностью каждой грани. 

В отсутствие каких-либо данных это априорная вероятность. Затем мы проводим анализ модели с помощью выборки Марковской цепи Монте-Карло (MCMC) и используем выборки для вывода вероятностей каждого лица, т. е. апостериорной вероятности. Поддельный кубик дает 6 в 7 из 12 бросков — так что это действительно очевидно.

Вот пример кода:

import numpy as np  
import pymc as pm  
from matplotlib import pyplot as plt  
  
# Определение игрального кубика и подготовка данных 
tampered_dice = [1 / 12, 1 / 12, 1 / 12, 1 / 12, 1 / 12, 7 / 12]  
good_dice = [1 / 6] * 6  
num_rolls = 10000  
x = list(range(0, num_rolls, 1))  
  
for idx, dice in enumerate([tampered_dice, good_dice]):  
    
    # генерирование данные о бросках костей 
    p = np.array(dice)  
    dice_rolls = np.random.choice(6, size=num_rolls, p=p)  
  
    # Определение модели игрального кубика
    with pm.Model() as dice_model:  
        p = pm.Dirichlet("p", a=np.ones(6))  
  
        # Определение вероятности  
        face = pm.Categorical("face", p=p, observed=dice_rolls)  
  
        # делаем вывод на основе данных 
        trace = pm.sample(draws=100, tune=100, chains=2)  
  
        # выборочные данные, полученные до и после получения данных 
        prior_predictive = pm.sample_prior_predictive()  
        post_pred = pm.sample_posterior_predictive(trace)  
  
    # представление предварительных прогнозов
    fig, ax = plt.subplots()  
    ax.hist(prior_predictive.observed_data.face)  
    plt.xlabel("Die face")  
    plt.ylabel("Occurences in 10k rolls.")  
    if idx == 0:  
        plt.title("Tampered dice")  
    else:  
        plt.title("Good dice")  
    plt.savefig(f"prior_predictive_{idx}.png", dpi=100)  
    plt.show()  
  
    # представление апостериорных прогнозов
    trace.extend(post_pred)  
  
    fig, ax = plt.subplots()  
    ax.hist(trace.observed_data.face)  
    plt.xlabel("Die face")  
    plt.ylabel("Occurences in 10k rolls.")  
    if idx == 0:  
        plt.title("Tampered dice")  
    else:  
        plt.title("Good dice")  
    plt.savefig(f"posterior_predictive_{idx}.png", dpi=100)  
    plt.show()  
  
    # рассчет ожидаемой вероятности выпадения честного игрального кубика 
    expected_probs = np.ones(6) / 6  
  
    # вычисляем разницу между апостериорными и ожидаемыми вероятностями 
    prob_diff = np.abs(trace.posterior.p - expected_probs)  
  
    # рассчет среднго значения и стандартного отклонения разницы 
    mean_diff = np.mean(prob_diff, axis=0)  
    std_diff = np.std(prob_diff, axis=0)  
  
    # установить порог для разницы 
    threshold = 0.05  
  
    # проверить, превышает ли разница между вычисленными вероятностями и ожидаемыми вероятностями пороговое значение 
    tampered = mean_diff > threshold  
  
    if tampered.any():  
        print("Dice may have been tampered with.")  
    else:  
        print("Dice does not seem to have been tampered with.")

После запуска, программа проверяет, находятся ли грани кубика в пределах 5 % от допустимого отклонения от идеального кубика. 

Вероятно, ваш обычный домашний кубик можно считать подделанным с помощью этого кода, потому что грань №1 тяжелее, чем грань №6. В результате чего грань №6 появляется в среднем чаще, чем грань №1. Для априорной вероятности я выбрал 100 розыгрышей. Розыгрыш — это число угадываний, которые программа делает для получения потенциальных параметров модели. Рекомендуется использовать большие значения, например, 1000, чтобы обеспечить достаточную степень детализации распределения вероятностей.

Почему PyMC?

Итак, каковы преимущества и недостатки PyMC? 

PyMC — это мощный пакет, который позволяет пользователям легко определять, подбирать и анализировать модели. Он предоставляет множество встроенных распределений и выборок, подходящих для широкого спектра моделей. 

PyMC также очень гибок и может работать со сложными моделями. Однако PyMC — это библиотека вероятностного программирования, к которой нужно привыкнуть. Важно понимать концепции распределения вероятностей и байесовской статистики. PyMC может потребовать значительных вычислительных ресурсов, особенно для больших и сложных моделей, и может не подходить для приложений, работающих в режиме реального времени или для больших наборов данных. Тем более, что PyMC построен на языке Python. Байесовские методы являются мощным инструментом для анализа данных, а PyMC позволяет легко реализовать эти методы в Python. Однако PyMC гораздо более громоздкий и не так хорошо документирован, как Tensorflow, но, опять же, Tensorflow является текущим стандартом.

Альтернативами PyMC с другими требованиями и преимуществами являются:

  • Stan: Написано на C++ и поэтому работает быстрее, чем PyMC, для больших и сложных моделей.

  • JAGS: Написано на C++

  • Edward: Построен на основе TensorFlow, что позволяет использовать модели глубокого обучения. Полезно для байесовских задач глубокого обучения.

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

Иногда нейронные сети и глубокое обучение дают результаты, которые появляются как по волшебству. Наиболее яркими примерами на данный момент являются ChatGPT и MidJourney. Как они достигают своих результатов, понятно лишь отчасти. 

Байесовская статистика требует от нас размышлений о модели, лежащей в основе наблюдаемых данных, и, таким образом, более глубоко понять проблему. Хотя вероятностные подходы не так мощны, как искусственный интеллект, они могут помочь нам подготовить данные и установить требования для ИИ. Более глубокое понимание проблемы часто является ключевым преимуществом.

Заключение

PyMC — это интересный инструмент в вашем наборе инструментов. 

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

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

Комментарии (0)