Spec-Zone.ru › Python 3.9

statistics — Функции математической статистики

Новая в версии 3.4.

Исходный код: Lib/statistics.py

Этот модуль предоставляет функции для вычисления математической статистики числовых (Real-значных) данных.

Модуль не предназначен для конкуренции с сторонними библиотеками, такими как NumPy, SciPy, или специализированными статистическими пакетами, ориентированными на профессиональных статистиков, такими как Minitab, SAS и Matlab. Он предназначен для использования на уровне графиков и научных калькуляторов.

Если не указано иное, эти функции поддерживают int, float, Decimal и Fraction. Поведение с другими типами (как в числовом ряду, так и нет) в настоящее время не поддерживается. Коллекции со смешанными типами также не определены и зависят от реализации. Если ваши входные данные содержат смешанные типы, вы можете использовать map() для обеспечения согласованного результата, например: map(float, input_data).

Средние значения и показатели центральной тенденции

Эти функции вычисляют среднее значение или типичное значение из генеральной совокупности или выборки.

mean()

Среднее арифметическое (“среднее”) данных.

fmean()

Быстрое среднее арифметическое с плавающей точкой.

geometric_mean()

Среднее геометрическое данных.

harmonic_mean()

Среднее гармоническое данных.

median()

Медиана (среднее значение) данных.

median_low()

Нижняя медиана данных.

median_high()

Верхняя медиана данных.

median_grouped()

Медиана, или 50-й процентиль, сгруппированных данных.

mode()

Единственное модальное значение (наиболее часто встречающееся значение) дискретных или номинальных данных.

multimode()

Список модальных значений (наиболее часто встречающихся значений) дискретных или номинальных данных.

quantiles()

Разделение данных на интервалы с равной вероятностью.

Показатели разброса

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

pstdev()

Стандартное отклонение генеральной совокупности данных.

pvariance()

Дисперсия генеральной совокупности данных.

stdev()

Стандартное отклонение выборки данных.

variance()

Дисперсия выборки данных.

END_OF_DOCUMENT_MARKER

Подробности функций

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

statistics.mean(data)

Возвращает выборочное среднее арифметическое данных, которые могут быть последовательностью или итерируемым объектом.

Среднее арифметическое — это сумма данных, деленная на количество точек данных. Оно обычно называется «средним значением», хотя это лишь одно из многих математических средних. Это мера центральной тенденции данных.

Если данные пустые, будет поднята ошибка StatisticsError.

Примеры использования:

>>> mean([1, 2, 3, 4, 4])
2.8
>>> mean([-1.0, 2.5, 3.25, 5.75])
2.625

>>> from fractions import Fraction as F
>>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)])
Fraction(13, 21)

>>> from decimal import Decimal as D
>>> mean([D("0.5"), D("0.75"), D("0.625"), D("0.375")])
Decimal('0.5625')

Примечание

Среднее значение сильно зависит от выбросов и не обязательно является типичным примером точек данных. Для более устойчивой, хотя и менее эффективной, меры центральной тенденции см. median().

Выборочное среднее дает несмещенную оценку истинного среднего значения генеральной совокупности, так что в среднем по всем возможным выборкам оно сходится к истинному среднему значению всей генеральной совокупности. Если данные представляют собой всю генеральную совокупность, а не выборку, то mean(data) эквивалентно вычислению истинного среднего значения генеральной совокупности μ.

statistics.fmean(data)

Преобразует данные в числа с плавающей точкой и вычисляет среднее арифметическое.

Эта функция работает быстрее, чем функция mean(), и всегда возвращает значение типа float. Данные могут быть последовательностью или итерируемым объектом. Если входной набор данных пустой, возникает ошибка StatisticsError.

>>> fmean([3.5, 4.0, 5.25])
4.25

Новая в версии 3.8.

statistics.geometric_mean(data)

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

Геометрическое среднее показывает центральную тенденцию или типичное значение данных, используя произведение значений (в отличие от среднего арифметического, которое использует их сумму).

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

Не предпринимаются специальные усилия для достижения точных результатов. (Однако это может измениться в будущем.)

>>> round(geometric_mean([54, 24, 36]), 1)
36.0

Новая в версии 3.8.

statistics.harmonic_mean(data)

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

Гармоническое среднее, иногда называемое средним субконтрарным, является обратным среднему арифметическому mean() обратных величин данных. Например, гармоническое среднее трех значений a, b и c будет равно 3/(1/a + 1/b + 1/c). Если одно из значений равно нулю, результат будет равен нулю.

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

Предположим, автомобиль проехал 10 км со скоростью 40 км/ч, а затем еще 10 км со скоростью 60 км/ч. Какова средняя скорость?

>>> harmonic_mean([40, 60])
48.0

Предположим, инвестор покупает равную сумму акций в каждой из трех компаний, с отношением цена/прибыль (P/E) 2,5, 3 и 10. Каково среднее значение P/E для инвестиционного портфеля инвестора?

>>> harmonic_mean([2.5, 3, 10])  # For an equal investment portfolio.
3.6

Возникает ошибка StatisticsError, если данные пусты или какое-либо значение меньше нуля.

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

Новая в версии 3.6.

statistics.median(data)

Возвращает медиану (среднее значение) числовых данных, используя распространенный метод «среднее двух средних». Если данные пусты, возникает ошибка StatisticsError. Данные могут быть последовательностью или итерируемым объектом.

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

>>> median([1, 3, 5])
3

Когда количество точек данных четное, медиана интерполируется путем взятия среднего двух средних значений:

>>> median([1, 3, 5, 7])
4.0

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

Если данные являются порядковыми (поддерживают операции сравнения), но не числовыми (не поддерживают сложение), используйте median_low() или median_high().

statistics.median_low(data)

Возвращает низкую медиану числовых данных. Если данные пусты, возникает ошибка StatisticsError. Данные могут быть последовательностью или итерируемым объектом.

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

>>> median_low([1, 3, 5])
3
>>> median_low([1, 3, 5, 7])
3

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

statistics.median_high(data)

Возвращает высокую медиану данных. Если данные пусты, возникает ошибка StatisticsError. Данные могут быть последовательностью или итерируемым объектом.

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

>>> median_high([1, 3, 5])
3
>>> median_high([1, 3, 5, 7])
5

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

statistics.median_grouped(data, interval=1)

Возвращает медиану сгруппированных непрерывных данных, вычисленную как 50-й процентиль, с использованием интерполяции. Если данные пусты, возникает ошибка StatisticsError. Данные могут быть последовательностью или итерируемым объектом.

>>> median_grouped([52, 52, 53, 54])
52.5

В следующем примере данные округляются, так что каждое значение представляет собой середину классов данных, например, 1 — это середина класса 0,5–1,5, 2 — это середина класса 1,5–2,5, 3 — это середина класса 2,5–3,5 и т. д. При заданных данных среднее значение попадает в класс 3,5–4,5, и для его оценки используется интерполяция:

>>> median_grouped([1, 2, 2, 3, 4, 4, 4, 4, 4, 5])
3.7

Необязательный аргумент interval представляет интервал класса и по умолчанию равен 1. Изменение интервала класса естественным образом повлияет на интерполяцию:

>>> median_grouped([1, 3, 3, 5, 7], interval=1)
3.25
>>> median_grouped([1, 3, 3, 5, 7], interval=2)
3.5

Эта функция не проверяет, находятся ли точки данных как минимум на расстоянии interval друг от друга.

Подробность реализации CPython: В некоторых случаях median_grouped() может привести к преобразованию точек данных в числа с плавающей точкой. Это поведение, вероятно, изменится в будущем.

См. также

  • «Статистика для социальных наук», Фредерик Дж. Грейветтер и Ларри Б. Воллнау (8-е издание).
  • Функция SSMEDIAN в электронных таблицах Gnome Gnumeric, включая данное обсуждение.
statistics.mode(data)

Возвращает наиболее часто встречающуюся точку данных из дискретных или номинальных данных. Мода (если она существует) — это наиболее типичное значение и служит мерой центральной тенденции.

Если существует несколько мод с одинаковой частотой, возвращается первая из встреченных в данных. Если нужно получить минимальную или максимальную из них, используйте min(multimode(data)) или max(multimode(data)). Если входные данные пусты, возникает ошибка StatisticsError.

mode предполагает дискретные данные и возвращает одно значение. Это стандартная обработка моды, как обычно преподают в школах:

>>> mode([1, 1, 2, 3, 3, 3, 3, 4])
3

Мода уникальна тем, что является единственной статистикой в этом пакете, которая также применима к номинальным (не числовым) данным:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
'red'

Изменено в версии 3.8: Теперь обрабатывает многомодальные наборы данных, возвращая первую встретившуюся моду. Раньше при обнаружении более одной моды вызывалась ошибка StatisticsError.

statistics.multimode(data)

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

>>> multimode('aabbbbccddddeeffffgg')
['b', 'd', 'f']
>>> multimode('')
[]

Новая в версии 3.8.

statistics.pstdev(data, mu=None)

Возвращает стандартное отклонение генеральной совокупности (квадратный корень из дисперсии генеральной совокупности). См. pvariance() для аргументов и других деталей.

>>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75])
0.986893273527251
statistics.pvariance(data, mu=None)

Возвращает дисперсию генеральной совокупности data, непустой последовательности или итерируемого объекта действительных чисел. Дисперсия, или второй момент относительно среднего, является мерой изменчивости (разброса или рассеяния) данных. Большая дисперсия указывает на то, что данные разбросаны; малая дисперсия указывает на то, что данные сгруппированы близко вокруг среднего.

Если задан необязательный второй аргумент mu, он обычно является средним значением data. Его также можно использовать для вычисления второго момента относительно точки, которая не является средним. Если он отсутствует или None (по умолчанию), среднее арифметическое вычисляется автоматически.

Используйте эту функцию для вычисления дисперсии всей генеральной совокупности. Для оценки дисперсии из выборки функция variance() обычно является лучшим выбором.

Возвращает StatisticsError, если data пусто.

Примеры:

>>> data = [0.0, 0.25, 0.25, 1.25, 1.5, 1.75, 2.75, 3.25]
>>> pvariance(data)
1.25

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

>>> mu = mean(data)
>>> pvariance(data, mu)
1.25

Поддерживаются десятичные и дробные числа:

>>> from decimal import Decimal as D
>>> pvariance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")])
Decimal('24.815')

>>> from fractions import Fraction as F
>>> pvariance([F(1, 4), F(5, 4), F(1, 2)])
Fraction(13, 72)

Примечание

При вызове с полной генеральной совокупностью это даёт дисперсию генеральной совокупности σ². При вызове с выборкой вместо этого это смещённая дисперсия выборки s², также известная как дисперсия с N степенями свободы.

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

statistics.stdev(data, xbar=None)

Возвращает стандартное отклонение выборки (квадратный корень из дисперсии выборки). См. variance() для аргументов и других деталей.

>>> stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75])
1.0810874155219827
statistics.variance(data, xbar=None)

Возвращает дисперсию выборки data, итерируемого объекта, содержащего как минимум два действительных числа. Дисперсия, или второй момент относительно среднего, является мерой изменчивости (разброса или рассеяния) данных. Большая дисперсия указывает на то, что данные разбросаны; малая дисперсия указывает на то, что данные сгруппированы близко вокруг среднего.

Если задан необязательный второй аргумент xbar, он должен быть средним значением data. Если он отсутствует или None (по умолчанию), среднее значение вычисляется автоматически.

Используйте эту функцию, когда ваши данные являются выборкой из генеральной совокупности. Для вычисления дисперсии из всей генеральной совокупности см. pvariance().

Возвращает StatisticsError, если data имеет меньше двух значений.

Примеры:

>>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
>>> variance(data)
1.3720238095238095

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

>>> m = mean(data)
>>> variance(data, m)
1.3720238095238095

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

Поддерживаются десятичные и дробные значения:

>>> from decimal import Decimal as D
>>> variance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")])
Decimal('31.01875')

>>> from fractions import Fraction as F
>>> variance([F(1, 6), F(1, 2), F(5, 3)])
Fraction(67, 108)

Примечание

Это выборочная дисперсия s² с поправкой Бесселя, также известная как дисперсия с N-1 степенями свободы. При условии, что данные являются репрезентативными (например, независимые и одинаково распределённые), результат должен быть несмещённой оценкой истинной дисперсии генеральной совокупности.

Если вам каким-то образом известно фактическое среднее значение генеральной совокупности μ, вы должны передать его в функцию pvariance() в качестве параметра mu, чтобы получить дисперсию выборки.

statistics.quantiles(data, *, n=4, method='exclusive')

Разделить data на n непрерывных интервалов с равной вероятностью. Возвращает список n - 1 точек разбиения, разделяющих интервалы.

Установите n в 4 для квартилей (по умолчанию). Установите n в 10 для десятилей. Установите n в 100 для перцентилей, что даёт 99 точек разбиения, которые делят data на 100 групп равной размерности. Возвращает StatisticsError, если n меньше 1.

Data может быть любым итерируемым объектом, содержащим данные выборки. Для осмысленных результатов число точек данных в data должно быть больше n. Возвращает StatisticsError, если нет как минимум двух точек данных.

Точки разбиения линейно интерполируются из двух ближайших точек данных. Например, если точка разбиения находится на одной трети расстояния между двумя значениями выборки, 100 и 112, точка разбиения будет равна 104.

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

По умолчанию method равен "исключительному" и используется для данных, взятых из генеральной совокупности, которая может иметь более экстремальные значения, чем те, которые найдены в выборке. Часть генеральной совокупности, которая меньше i-й из m отсортированных точек данных, вычисляется как i / (m + 1). Имея девять значений выборки, метод сортирует их и присваивает следующие перцентили: 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%.

Установка method в "включительному" используется для описания данных генеральной совокупности или для выборок, которые, как известно, включают самые экстремальные значения из генеральной совокупности. Наименьшее значение в data рассматривается как 0-й перцентиль, а наибольшее значение — как 100-й перцентиль. Часть генеральной совокупности, которая меньше i-й из m отсортированных точек данных, вычисляется как (i - 1) / (m - 1). Имея 11 значений выборки, метод сортирует их и присваивает следующие перцентили: 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100%.

# Decile cut points for empirically sampled data
>>> data = [105, 129, 87, 86, 111, 111, 89, 81, 108, 92, 110,
...         100, 75, 105, 103, 109, 76, 119, 99, 91, 103, 129,
...         106, 101, 84, 111, 74, 87, 86, 103, 103, 106, 86,
...         111, 75, 87, 102, 121, 111, 88, 89, 101, 106, 95,
...         103, 107, 101, 81, 109, 104]
>>> [round(q, 1) for q in quantiles(data, n=10)]
[81.0, 86.2, 89.0, 99.4, 102.5, 103.6, 106.0, 109.8, 111.0]

Новое в версии 3.8.

Исключения

Определено одно исключение:

exception statistics.StatisticsError

Подкласс ValueError для исключений, связанных со статистикой.

Объекты NormalDist

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

Нормальные распределения возникают из Центральной предельной теоремы и имеют широкий спектр применений в статистике.

class statistics.NormalDist(mu=0.0, sigma=1.0)

Возвращает новый объект NormalDist, где mu представляет среднее арифметическое, а sigma — стандартное отклонение.

Если sigma отрицательно, возникает StatisticsError.

mean

Только для чтения свойство для среднего арифметического нормального распределения.

median

Только для чтения свойство для медианы нормального распределения.

mode

Только для чтения свойство для моды нормального распределения.

stdev

Только для чтения свойство для стандартного отклонения нормального распределения.

variance

Только для чтения свойство для дисперсии нормального распределения. Равно квадрату стандартного отклонения.

classmethod from_samples(data)

Создаёт экземпляр нормального распределения с параметрами mu и sigma, оценёнными из data с помощью fmean() и stdev().

data может быть любым итерируемым объектом и должен содержать значения, которые можно преобразовать в тип float. Если data не содержит хотя бы двух элементов, возникает StatisticsError, так как для оценки центрального значения требуется хотя бы одна точка, а для оценки дисперсии - по крайней мере две точки.

samples(n, *, seed=None)

Генерирует n случайных выборок для заданного среднего и стандартного отклонения. Возвращает list значений типа float.

Если задан seed, создаёт новый экземпляр генератора случайных чисел. Это полезно для создания воспроизводимых результатов, даже в многопоточном контексте.

pdf(x)

Используя функцию плотности вероятности (pdf), вычислите относительную вероятность того, что случайная величина X будет близка к заданному значению x. Математически это предел отношения P(x <= X < x+dx) / dx при стремлении dx к нулю.

Относительная вероятность вычисляется как вероятность появления выборки в узком интервале, делённая на ширину интервала (отсюда и слово «плотность»). Поскольку вероятность относительна другим точкам, её значение может быть больше 1.0.

cdf(x)

Используя функцию кумулятивного распределения (cdf), вычислите вероятность того, что случайная величина X будет меньше или равна x. Математически это записывается как P(X <= x).

inv_cdf(p)

Вычислите обратную функцию кумулятивного распределения, также известную как функция квантиля или функция процентиля. Математически это записывается как x : P(X <= x) = p.

Находит значение x случайной величины X, такое что вероятность того, что величина будет меньше или равна этому значению, равна заданной вероятности p.

overlap(other)

Измеряет согласованность между двумя нормальными распределениями вероятностей. Возвращает значение от 0,0 до 1,0, представляющее перекрывающуюся площадь для двух функций плотности вероятности.

quantiles(n=4)

Разделяет нормальное распределение на n непрерывных интервалов с равной вероятностью. Возвращает список (n - 1) точек разрыва, разделяющих интервалы.

Установите n в 4 для квартилей (по умолчанию). Установите n в 10 для децилей. Установите n в 100 для перцентилей, что даёт 99 точек разрыва, которые разделяют нормальное распределение на 100 равных групп.

zscore(x)

Вычисляет стандартный балл, описывающий x с точки зрения количества стандартных отклонений выше или ниже среднего значения нормального распределения: (x - mean) / stdev.

Добавлена в версии 3.9.

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

>>> temperature_february = NormalDist(5, 2.5)             # Celsius
>>> temperature_february * (9/5) + 32                     # Fahrenheit
NormalDist(mu=41.0, sigma=4.5)

Деление константы на экземпляр NormalDist не поддерживается, потому что результат не будет нормально распределённым.

Так как нормальные распределения возникают из аддитивных эффектов независимых переменных, можно сложить и вычесть две независимые нормально распределённые случайные величины, представленные как экземпляры NormalDist. Например:

>>> birth_weights = NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5])
>>> drug_effects = NormalDist(0.4, 0.15)
>>> combined = birth_weights + drug_effects
>>> round(combined.mean, 1)
3.1
>>> round(combined.stdev, 1)
0.5

Добавлена в версии 3.8.

NormalDist Примеры и рецепты

NormalDist легко решает классические задачи теории вероятностей.

Например, учитывая исторические данные по экзаменам SAT, показывающие, что баллы распределены нормально со средним значением 1060 и стандартным отклонением 195, определите процент студентов с результатами тестов между 1100 и 1200, округлив до ближайшего целого числа:

>>> sat = NormalDist(1060, 195)
>>> fraction = sat.cdf(1200 + 0.5) - sat.cdf(1100 - 0.5)
>>> round(fraction * 100.0, 1)
18.4

Найдите квартили и децили для баллов SAT:

>>> list(map(round, sat.quantiles()))
[928, 1060, 1192]
>>> list(map(round, sat.quantiles(n=10)))
[810, 896, 958, 1011, 1060, 1109, 1162, 1224, 1310]

Для оценки распределения для модели, которую сложно решить аналитически, NormalDist может генерировать входные образцы для моделирования Монте-Карло:

>>> def model(x, y, z):
...     return (3*x + 7*x*y - 5*y) / (11 * z)
...
>>> n = 100_000
>>> X = NormalDist(10, 2.5).samples(n, seed=3652260728)
>>> Y = NormalDist(15, 1.75).samples(n, seed=4582495471)
>>> Z = NormalDist(50, 1.25).samples(n, seed=6582483453)
>>> quantiles(map(model, X, Y, Z))       
[1.4591308524824727, 1.8035946855390597, 2.175091447274739]

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

Например, на конференции с открытым исходным кодом 750 участников и двумя залами на 500 человек. Есть доклад о Python и другой о Ruby. На предыдущих конференциях 65% участников предпочитали слушать доклады о Python. Предполагая, что предпочтения населения не изменились, какова вероятность того, что зал для Python останется в пределах своих возможностей?

>>> n = 750             # Sample size
>>> p = 0.65            # Preference for Python
>>> q = 1.0 - p         # Preference for Ruby
>>> k = 500             # Room capacity

>>> # Approximation using the cumulative normal distribution
>>> from math import sqrt
>>> round(NormalDist(mu=n*p, sigma=sqrt(n*p*q)).cdf(k + 0.5), 4)
0.8402

>>> # Solution using the cumulative binomial distribution
>>> from math import comb, fsum
>>> round(fsum(comb(n, r) * p**r * q**(n-r) for r in range(k+1)), 4)
0.8402

>>> # Approximation using a simulation
>>> from random import seed, choices
>>> seed(8675309)
>>> def trial():
...     return choices(('Python', 'Ruby'), (p, q), k=n).count('Python')
>>> mean(trial() <= k for i in range(10_000))
0.8398

Нормальные распределения часто встречаются в задачах машинного обучения.

В Википедии есть хороший пример классификатора Байеса-Наива. Задача заключается в прогнозировании пола человека по измерениям нормально распределенных характеристик, включая рост, вес и размер ноги.

У нас есть обучающая выборка с измерениями для восьми человек. Измерения предполагаются нормально распределенными, поэтому мы обобщаем данные с помощью NormalDist:

>>> height_male = NormalDist.from_samples([6, 5.92, 5.58, 5.92])
>>> height_female = NormalDist.from_samples([5, 5.5, 5.42, 5.75])
>>> weight_male = NormalDist.from_samples([180, 190, 170, 165])
>>> weight_female = NormalDist.from_samples([100, 150, 130, 150])
>>> foot_size_male = NormalDist.from_samples([12, 11, 12, 10])
>>> foot_size_female = NormalDist.from_samples([6, 8, 7, 9])

Далее мы встречаем нового человека, чьи измерения характеристик известны, но пол неизвестен:

>>> ht = 6.0        # height
>>> wt = 130        # weight
>>> fs = 8          # foot size

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

>>> prior_male = 0.5
>>> prior_female = 0.5
>>> posterior_male = (prior_male * height_male.pdf(ht) *
...                   weight_male.pdf(wt) * foot_size_male.pdf(fs))

>>> posterior_female = (prior_female * height_female.pdf(ht) *
...                     weight_female.pdf(wt) * foot_size_female.pdf(fs))

Окончательный прогноз идет к наибольшему апостериорному значению. Это известно как максимальное апостериорное или MAP:

>>> 'male' if posterior_male > posterior_female else 'female'
'female'

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/statistics.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API