В своей предыдущей статье я говорил о статистических проверках гипотез. Они имеют решающее значение в статистике и науке о данных, поскольку нас всегда просят обобщить огромное количество данных, которые мы хотим проанализировать, на выборках.
После получения выборок, которые можно упорядочить с помощью различных методов, таких как выборка начальной загрузки, общая цель состоит в том, чтобы сделать выводы о реальных параметрах, принадлежащих исходным популяциям, путем вычисления так называемой статистики или оценок из нашей выборки.
Однако нам нужна какая-то «страховка», чтобы наши оценки были близки к реальности. Вот почему мы используем проверку гипотез.
В этой статье я собираюсь предоставить практический пример с Python со случайно сгенерированными данными, чтобы вы могли легко визуализировать все потенциальные результаты теста.
Итак, начнем с создания наших данных:
import numpy as np
mu, sigma = 3, 2
s = np.random.normal(mu, sigma, 10000)
import matplotlib.pyplot as plt
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (bins - mu)**2 / (2 * sigma**2) ),linewidth=2, color='r')
plt.show()
Как видите, я вручную сгенерировал нормально распределенные данные со средним значением = 3 и стандартным отклонением = 2. Теперь идея состоит в том, чтобы извлечь выборку из этой совокупности и проверить, действительно ли она была извлечена из совокупности со средним значением = 3. Для этой цели, поскольку я хочу, чтобы визуализация была четкой, я создам другое ручное распределение, все еще нормальное, но с другим средним значением (представьте, что оно было взято из популяции).
import numpy as np
sample_mean, sample_sigma = 1.5, 2
sample = np.random.normal(sample_mean, sample_sigma, 200)
Поскольку я вручную создал подвыборку этой популяции со средним заведомо меньше 3 (фактически 1,5), наши гипотезы будут такими:
Во-первых, давайте посмотрим на распределение:
count, bins, ignored = plt.hist(s, 30, alpha=0.1, density=True)
sample_count, sample_bins, sample_ignored = plt.hist(sample, 30, alpha=0.1, color='r',density=True)
plt.plot(sample_bins,1/(sample_sigma * np.sqrt(2 * np.pi)) *np.exp( - (sample_bins - sample_mean)**2 / (2 * sample_sigma**2) ),linewidth=2, color='r')
plt.plot(bins,1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (bins - mu)**2 / (2 * sigma**2) ),linewidth=2, color='b')
plt.show()
Таким образом, красным цветом обозначено наше выборочное распределение, а синим - реальное распределение населения. В этом случае мы уже знаем ответ на нашу проблему: наша выборка не возникает из популяции с синим распределением, и это очевидно, поскольку я не извлекал эту выборку из нашей генеральной совокупности. Однако что, если вам не предоставлено реальное распределение населения? Нам нужно узнать о вероятности того, что среднее значение нашей выборки будет равно среднему значению для нашей генеральной совокупности.
Следовательно, давайте вычислим доверительный интервал нашей выборки. Напомним, что доверительный интервал x% выражает, что для данной генеральной совокупности и набора выборок из них в 95% этих выборок среднее значение выборки (или любой другой параметр, о котором вы спрашиваете) будет включен в этот интервал.
Мы можем легко вычислить интервал с уверенностью = 95% с помощью инструмента scipy:
import scipy
ci = scipy.stats.norm.interval(0.95, loc=1.5, scale=2)
count, bins, ignored = plt.hist(s, 30, alpha=0.1, density=True)
sample_count, sample_bins, sample_ignored = plt.hist(sample, 30, alpha=0.1, color='r',density=True)
plt.plot(sample_bins,1/(sample_sigma * np.sqrt(2 * np.pi)) *np.exp( - (sample_bins - sample_mean)**2 / (2 * sample_sigma**2) ),linewidth=2, color='r')
plt.plot(bins,1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (bins - mu)**2 / (2 * sigma**2) ),linewidth=2, color='b')
plt.axvline(ci[0],color='g')
plt.axvline(ci[1],color='g')
plt.show()
Теперь давайте узнаем о возможных результатах нашего теста:
count, bins, ignored = plt.hist(s, 30, alpha=0.1, density=True)
sample_count, sample_bins, sample_ignored = plt.hist(sample, 30, alpha=0.1, color='r',density=True)
plt.plot(sample_bins,1/(sample_sigma * np.sqrt(2 * np.pi)) *np.exp( - (sample_bins - sample_mean)**2 / (2 * sample_sigma**2) ),linewidth=2, color='r')
plt.plot(bins,1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (bins - mu)**2 / (2 * sigma**2) ),linewidth=2, color='b')
plt.axvline(ci[0],color='g')
plt.axvline(ci[1],color='g')
plt.fill_between(x=np.arange(-4,ci[0],0.01),
y1= scipy.stats.norm.pdf(np.arange(-4,ci[0],0.01),loc=1.5,scale=2) ,
facecolor='red',
alpha=0.35)
plt.fill_between(x=np.arange(ci[1],7.5,0.01),
y1= scipy.stats.norm.pdf(np.arange(ci[1],7.5,0.01),loc=1.5,scale=2) ,
facecolor='red',
alpha=0.5)
plt.fill_between(x=np.arange(ci[0],ci[1],0.01),
y1= scipy.stats.norm.pdf(np.arange(ci[0],ci[1],0.01),loc=3, scale=2) ,
facecolor='blue',
alpha=0.5)
plt.text(x=0, y=0.18, s= "Null Hypothesis")
plt.text(x=6, y=0.05, s= "Alternative")
plt.text(x=-4, y=0.01, s= "Type 1 Error")
plt.text(x=6.2, y=0.01, s= "Type 1 Error")
plt.text(x=2, y=0.02, s= "Type 2 Error")
plt.show()
Как видите, пример среднего (1.5) включен в область ошибки типа 2 (это означает, что мы не отклоняем значение null, если оно ложно). Чтобы перепроверить, давайте вычислим p-значение, имея в виду, что наш уровень достоверности составляет 5% (следовательно, мы не отклоняем ноль, если p-значение больше 5%).
z_score=(sample_mean-mu)/sigma
p_value = scipy.stats.norm.sf(abs(z_score))
print('P-value= {}'.format(p_value))
if p_value<0.05:
print('P-value<alpha: reject H0')
else:
print('P-value>alpha: do not reject H0')
Как видите, наш тест подтвердил то, что показано на рисунке выше: мы можем сказать с 95% уверенностью, что наша выборка была извлечена из генеральной совокупности со средним значением = 1,5. Конечно, мы знаем, что это неправда, поскольку реальное население имеет среднее значение = 3. Итак, как мы можем справиться с этим несоответствием? Ответ в том, что мы не можем. Я имею в виду, что мы могли бы сократить наш доверительный интервал, но имейте в виду, что это может привести к ошибке 1-го типа (отклонение нуля, если оно истинно).
Итак, идея состоит в том, чтобы сбалансировать размер вашего доверительного интервала в зависимости от типа задачи, с которой вы сталкиваетесь. А именно, если отклонение нулевого значения, когда оно истинно, означало бы огромную потерю доходов, вы бы предпочли сохранить свой доверительный интервал достаточно большим, чтобы только действительно экстремальные значения приводили к отклонению вашего нулевого значения.
Первоначально опубликовано на http://datasciencechalktalk.com 2 сентября 2019 г.