Проверка нормальности распределения

Проверка нормальности распределения

Загрузим данные - время реакции, с.

D = pd.read_table('d/rt.tsv')
vv=D.v.dropna()
hist(vv); xlabel('время реакции, с');
_images/i_normality_3_0.png

Стандартная проверка - по статистике хи-квадрат, комбинирующей z-тесты асимметрии и куртозиса.

import scipy.stats as stats
stats.normaltest(vv)
NormaltestResult(statistic=19.306090837311295, pvalue=6.422966266742602e-05)

p очень маленькое, значит отвергаем гипотезу о нормальности распределения. Увы, распределение ВР почти всегда скошено вправо.

Более мощный тест (по мнению некоторых источников) - Шапиро-Уилка (Shapiro-Wilk). Подходит для небольших выборок.

stats.shapiro(vv)
ShapiroResult(statistic=0.8942419290542603, pvalue=0.0006301295361481607)

p-value на порядок больше.

Тест Колмогорова-Смирнова может быть применен более широко, чем Шапиро, поскольку он сравнивает любые два распределения друг с другом, а не обязательно с нормальным. Для правильного использования необходимо z-преобразование.

zz=(vv-vv.mean())/vv.std()
stats.kstest(zz, cdf='norm')
KstestResult(statistic=0.1330234060534219, pvalue=0.37054082680262057)

Еще есть тест Андерсона - вариант теста Колмогорова-Смирнова.

stats.anderson(vv)
AndersonResult(statistic=1.0696390939463, critical_values=array([0.535, 0.609, 0.731, 0.853, 1.014]), significance_level=array([15. , 10. ,  5. ,  2.5,  1. ]))

Только последние два теста на 5% уровне значимости показали, что распределение можно считать нормальным.

Попробуем убрать выбросы более .5 с из набора данных.

vv_ = vv[vv<0.5]
print(f'изменение размера {len(vv)} -> {len(vv_)}')
изменение размера 45 -> 40
stats.normaltest(vv_)
NormaltestResult(statistic=2.25019618656403, pvalue=0.3246206226942116)
stats.shapiro(vv_)
ShapiroResult(statistic=0.9592655301094055, pvalue=0.15807799994945526)
stats.kstest((vv_-vv_.mean())/vv_.std(), cdf='norm')
KstestResult(statistic=0.10612495428368313, pvalue=0.7187460361580543)
stats.anderson(vv_)
AndersonResult(statistic=0.47606646495707139, critical_values=array([ 0.531,  0.605,  0.726,  0.847,  1.007]), significance_level=array([ 15. ,  10. ,   5. ,   2.5,   1. ]))

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