In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as sts
%matplotlib inline

Нормальное распределение

Вот так можно сгенерировать выборку из нормально распределённой случайной величины с параметрами $\mu=2.0$ и $\sigma=0.5$:


In [2]:
mu = 2.0
sigma = 0.5

# зададим нормально распределенную случайную величину
norm_rv = sts.norm(loc=mu, scale=sigma)

# сгенерируем 10 значений
norm_rv.rvs(size=10)


Out[2]:
array([ 2.42471807,  2.89001427,  1.5406754 ,  2.218372  ,  2.48622369,
        2.82460422,  2.06469003,  2.46941758,  1.7389734 ,  1.17062459])

Параметр loc задаёт $\mu$, scale — среднеквадратичное отклонение $\sigma$, size — размер выборки. Имя параметра size при вызове функции rvs можно не писать.

Следующая функция возвращает значение функции распределения нормальной случайной величины в точке, соответствующей её аргументу:


In [3]:
norm_rv.cdf(3)


Out[3]:
0.97724986805182079

Построим график функции распределения:


In [4]:
x = np.linspace(0,4,100)
cdf = norm_rv.cdf(x) # функция может принимать и вектор (x)
plt.plot(x, cdf)
plt.ylabel('$F(x)$')
plt.xlabel('$x$')


Out[4]:
<matplotlib.text.Text at 0xa058a20>

А так можно вычислить значение функции плотности вероятности нормального распределения в заданной точке:


In [5]:
norm_rv.pdf(3)


Out[5]:
0.10798193302637613

Построим график функции плотности вероятности:


In [6]:
x = np.linspace(0,4,100)
pdf = norm_rv.pdf(x)
plt.plot(x, pdf)

plt.ylabel('$f(x)$')
plt.xlabel('$x$')


Out[6]:
<matplotlib.text.Text at 0xa2c91d0>

Равномерное распределение на отрезке

Вот так можно сгенерировать выборку из случайной величины, имеющей равномерное распределение на отрезке $[a,b]$:


In [7]:
a = 1
b = 4

# обратите внимание, что в этой функции задается левая граница и масштаб, а не левая и правая границы:
uniform_rv = sts.uniform(a, b-a)

uniform_rv.rvs(10)


Out[7]:
array([ 2.90068986,  1.30900927,  2.61667386,  1.82853085,  1.11278354,
        1.67101276,  1.48848226,  1.74478797,  1.5155652 ,  2.54059151])

А так — вычислять значения функций распределения и плотностей:


In [8]:
x = np.linspace(0,5,100)
cdf = uniform_rv.cdf(x)
plt.plot(x, cdf)

plt.ylabel('$F(x)$')
plt.xlabel('$x$')


Out[8]:
<matplotlib.text.Text at 0xa2f0048>

In [9]:
x = np.linspace(0,5,1000)
pdf = uniform_rv.pdf(x)
plt.plot(x, pdf)

plt.ylabel('$f(x)$')
plt.xlabel('$x$')


Out[9]:
<matplotlib.text.Text at 0xa8dd320>

Распределение Бернулли

Генерация выборок из распределения Бернулли с заданным параметром $p$:


In [10]:
bernoulli_rv = sts.bernoulli(0.7)

bernoulli_rv.rvs(10)


Out[10]:
array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1])

Биномиальное распределение

Генерация выборок из биномиального распределения:


In [11]:
binomial_rv = sts.binom(20, 0.7)
binomial_rv.rvs(10)


Out[11]:
array([13, 11, 13, 15, 13, 14, 12, 16, 14, 16])

Первый аргумент функции binom — значение параметра $n$, второй — параметра $p$.

Функция распределения:


In [12]:
x = np.linspace(0,20,21)
cdf = binomial_rv.cdf(x)
plt.step(x, cdf)

plt.ylabel('$F(x)$')
plt.xlabel('$x$')


Out[12]:
<matplotlib.text.Text at 0xae11390>

Функция вероятности pmf для дискретных случайных величин заменяет функцию плотности pdf:


In [13]:
x = np.linspace(0,20,21)
pmf = binomial_rv.pmf(x)
plt.plot(x, pmf, 'o')

plt.ylabel('$P(X=x)$')
plt.xlabel('$x$')


Out[13]:
<matplotlib.text.Text at 0xae1d780>

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


In [14]:
x = np.linspace(0,45,46)
for N in [20, 30]:
    for p in [0.2, 0.7]:
        rv = sts.binom(N, p)
        cdf = rv.cdf(x)
        plt.step(x, cdf, label="$N=%s, p=%s$" % (N,p))
plt.legend()
plt.title("CDF (binomial)")

plt.ylabel('$F(X)$')
plt.xlabel('$x$')


Out[14]:
<matplotlib.text.Text at 0xb35f278>

In [15]:
x = np.linspace(0,45,46)
symbols = iter(['o', 's', '^', '+'])
for N in [20, 30]:
    for p in [0.2, 0.8]:
        rv = sts.binom(N, p)
        pmf = rv.pmf(x)
        plt.plot(x, pmf, next(symbols), label="$N=%s, p=%s$" % (N,p))
plt.legend()
plt.title("PMF (binomial)")

plt.ylabel('$P(X=x)$')
plt.xlabel('$x$')


Out[15]:
<matplotlib.text.Text at 0xb34b438>

Распределение Пуассона

Генерация выборок из распределения Пуассона с параметром $\lambda$:


In [16]:
poisson_rv = sts.poisson(5)
poisson_rv.rvs(10)


Out[16]:
array([ 6, 10,  4,  4,  4,  3,  8,  4,  3,  6])

In [17]:
x = np.linspace(0,30,31)
for l in [1, 5, 10, 15]:
    rv = sts.poisson(l)
    cdf = rv.cdf(x)
    plt.step(x, cdf, label="$\lambda=%s$" % l)
plt.legend()
plt.title("CDF (poisson)")

plt.ylabel('$F(x)$')
plt.xlabel('$x$')


Out[17]:
<matplotlib.text.Text at 0xb597d68>

In [18]:
x = np.linspace(0,30,31)

symbols = iter(['o', 's', '^', '+'])
for l in [1, 5, 10, 15]:
    rv = sts.poisson(l)
    pmf = rv.pmf(x)
    plt.plot(x, pmf, next(symbols), label="$\lambda=%s$" % l)
plt.legend()
plt.title("PMF (poisson)")

plt.ylabel('$P(X=x)$')
plt.xlabel('$x$')


Out[18]:
<matplotlib.text.Text at 0xb9586a0>

Дискретное распределение общего вида

Чтобы сгенерировать дискретную случайную величину общего вида, нужно задать множество её значений и соответствующих вероятностей и использовать функцию numpy.random.choice:


In [19]:
elements = np.array([1, 5, 12])
probabilities = [0.05, 0.7, 0.25]
np.random.choice(elements, 10, p=probabilities)


Out[19]:
array([ 5, 12, 12, 12,  5, 12,  5,  5,  5,  5])

Другие распределения

Существует большое количество других стандартных семейств распределений, многие из которых также можно генерировать в Питоне. Например, распределение хи-квадрат $\chi^2_k$, имеющее наутральный параметр $k$, который называется числом степеней свободы:


In [20]:
x = np.linspace(0,30,100)
for k in [1, 2, 3, 4, 6, 9]:
    rv = sts.chi2(k)
    cdf = rv.cdf(x)
    plt.plot(x, cdf, label="$k=%s$" % k)
plt.legend()
plt.title("CDF ($\chi^2_k$)")


Out[20]:
<matplotlib.text.Text at 0xbbb8898>

In [21]:
x = np.linspace(0,30,100)
for k in [1, 2, 3, 4, 6, 9]:
    rv = sts.chi2(k)
    pdf = rv.pdf(x)
    plt.plot(x, pdf, label="$k=%s$" % k)
plt.legend()
plt.title("PDF ($\chi^2_k$)")


Out[21]:
<matplotlib.text.Text at 0xbf24160>

Полный список функций SciPy для работы со всеми распределениями можно найти тут: http://docs.scipy.org/doc/scipy-0.14.0/reference/stats.html