Share This
Связаться со мной
Крути в низ
Categories
//Используем цикл for для вычисления вероятностей

Используем цикл for для вычисления вероятностей

12.07.2021Category : Python

Перевод статьи «Using For Loops in Python: Calculating Probabilities».

Из этой статьи вы узнаете, почему циклы незаменимы в построении статистических моделей. 

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

У многих занимающихся статистикой и дата сайенс, возникает мысль: «А зачем нам все это? Ведь привести наш код в порядок могут программисты!».

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

Вот один из примеров, когда умелое применение for облегчает и улучшает статистический анализ. 

Кумулятивные биномиальные вероятности — краткий экскурс 

Для вычисления вероятности нам необходимы две переменные: N (число наблюдений) и λ (лямбда — количество попаданий в цель/количество благоприятных исходов в серии экспериментов). Кумулятивная биномиальная вероятность означает следующее: с увеличением количества испытаний возрастает шанс возникновения какого-либо события. 

probability = 1-((1-λ)^N)

Пример. Возьмем «честный» шестигранный кубик и вычислим вероятность выпадения 6. Она равна 1/6. Но мы проведем этот эксперимент 10 раз подряд: 

1-((1-0.1667)^10) = 0.8385

Как видите, шанс выпадения 6 увеличивается до 83.85%

Закон больших чисел гласит: увеличиваем количество испытаний — увеличивается шанс возникновения какого-либо события. Это утверждение справедливо даже в том случае, если вероятность события в рамках одного испытания очень низкая. А теперь мы разберем, как увеличивается вероятность события с увеличением количества испытаний.

Модель без циклов

Ниже — скрипт, вычисляющий кумулятивную биномиальную вероятность без циклов:

import numpy as np import pandas as pd  l = 0.02 m = 0.04 n = 0.06  p=np.arange(0, 100, 1)  h = 1 - l j = 1 - m k = 1 - n  q = 1-(h**p) r = 1-(j**p) s = 1-(k**p)
  • l, m и n — вероятности определенных событий. 
  • p — количество испытаний (до 100)
  • q, r и s — кумулятивные биномиальные вероятности. Их значение будет расти вместе с количеством испытаний. 

Вывод:

>>> q array([0., 0.02, 0.0396, 0.058808, 0.07763184, 0.0960792, 0.11415762, 0.13187447, 0.14923698, 0.16625224, ..., 0.8532841, 0.85621842, 0.85909405, 0.86191217, 0.86467392]) >>> r array([0., 0.04, 0.0784, 0.115264, 0.15065344, 0.1846273, 0.21724221, 0.24855252, 0.27861042, 0.307466, ..., 0.97930968, 0.9801373, 0.9809318, 0.98169453, 0.98242675]) >>> s array([0., 0.06, 0.1164, 0.169416, 0.21925104, 0.26609598, 0.31013022, 0.35152241, 0.39043106, 0.4270052, 0.46138489, 0.49370179, 0.52407969, 0.5526349, 0.57947681, ..., 0.99720008, 0.99736807, 0.99752599, 0.99767443, 0.99781396])

Как видим, вероятности q, r и s растут прямо пропорционально количеству испытаний. 

Но у модели без использования циклов есть существенный недостаток — вероятности событий указываются конечным пользователем. А что, если мы захотим перебрать вероятности от 0.01 до 0.99?

Модель с циклами: генераторы списков и двумерные массивы

В этот раз мы рассмотрим другую модель: у нас будет лишь одно событие и его вероятность. Значения будут перебираться от 0.01 до 0.99. Количество испытаний все то же — 100.

import numpy as np import pandas as pd  # генератор списка probability = [x*0.01 for x in range(1,100)] probability = np.array(probability)  h = 1 - probability  # создаем двумерный массив result = 1-h[:, np.newaxis] ** np.arange(1,100) print(result)

Вывод:

>>> probability array([0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, ... 0.96, 0.97, 0.98, 0.99])

Обратите внимание, что использование генератора списков обязательно. Причина проста — функция range() работает только с int, а не с float. 

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

>>> for i in range(1,100,1): >>>     print(1-(h**i)) [0.01 0.02]  [0.0199 0.0396] ... [0.62653572 0.86191217] [0.63027036 0.86467392]

Вместо этого мы бы хотели видеть отсортированный массив: [0.01, 0.0199, …, 0.62653572, 0.63027036] и [0.02, 0.0396, …, 0.86191217, 0.86467392]. 

Что интересно — транспонирование не даст нужного результата, так как h — одномерный массив.

Можно поступить так: вычислить двумерный массив и вывести его в консоль напрямую:

>>> result = 1-h[:, np.newaxis] ** np.arange(1,100) >>> result array([[0.01, 0.0199, 0.029701, ..., 0.62653572, 0.63027036],  [0.02, 0.0396, 0.058808, ..., 0.86191217, 0.86467392],  [0.03, 0.0591, 0.087327, ..., 0.94946061, 0.9509768], ...,  [0.97, 0.9991, 0.999973, ..., 1., 1., 1.],  [0.98, 0.9996, 0.999992, ..., 1., 1., 1.],  [0.99, 0.9999, 0.999999, ..., 1., 1.,1.]])

Как видите, мы только что вычислили кумулятивную биномиальную вероятность для интервала от 0.01 до 0.99.

Также использование цикла for облегчило нам задачу, ведь мы автоматически вычислили нужные нам вероятности — от 0.01 до 0.99! Делать все это вручную — задача сложная и неблагодарная. 

Вывод

Итак, мы научились:

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

ispolzuem cikl for dlja vychislenija verojatnostej c5a7d9b - Используем цикл for для вычисления вероятностей

Кодинг-марафон по Python

Реши 10 задач и выиграй 5500 рублей

Подписаться ×

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2022 / All rights reserved

    Связаться со мной
    Close