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

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

К концу этого урока вы узнаете следующее:

  • Как визуально проверить, нормально ли распределены ваши данные, с помощью гистограммы

  • Как проверить, соответствуют ли ваши данные распределению Гаусса, используя график Q-Q

  • Как использовать два статистических теста, тест Шапиро-Уилка и тест Д’Агостино К2, чтобы проверить, нормально ли распределяются ваши данные.

Оглавление

Загрузка образца набора данных

Чтобы следовать этому руководству, мы создадим два разных набора данных:

  1. Нормально распределённые данные, позволяющие нам увидеть, как выглядят наши тесты, когда данные следуют нормальному распределению

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

Мы будем использовать пакет scipy для создания обоих этих наборов данных. Посмотрите на приведенный ниже блок кода, который используется для создания двух различных распределений данных.

import math
import numpy as np
from scipy.stats import lognorm, norm
import matplotlib.pyplot as plt
np.random.seed(42)
%config InlineBackend.figure_format='retina'

# Генерация нормального набора данных
normal_data = norm(loc=0, scale=1).rvs(size=500)

# Генерация логнормального набора данных
lognorm_data = lognorm.rvs(s=0.4, scale=math.exp(1), size=500)

Теперь, когда у нас есть два распределения, каждое из которых содержит 500 точек данных, давайте приступим к нашему первому тесту нормальности. Если вы хотите создать эти распределения с помощью NumPy, вы можете ознакомиться с моим руководством по созданию нормальных данных с использованием NumPy

Использование гистограммы для проверки нормального распределения распределения

Один из самых простых способов проверить, следует ли набор данных нормальному распределению, — это построить его с использованием гистограммы. Гистограмма делит набор данных на заданное количество групп, называемых бинами. Затем данные сортируются по каждому бину и визуализируется количество наблюдений.

Если распределение имеет нормальное распределение, то гистограмма создаст колоколообразную структуру.

Мы можем использовать библиотеку Matplotlib для визуализации наших распределений. Это можно сделать с помощью функции hist(), которая позволяет нам передавать массивы данных.

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

# Построение нормального распределения с использованием гистограммы
plt.hist(normal_data, edgecolor='black', bins=25)
plt.title('Нормальное распределение', weight='bold', size=18)
plt.show()

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

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

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

# Построение логнормального распределения с использованием гистограммы
plt.hist(lognorm_data, edgecolor='black', bins=25)
plt.title('Логнормальное распределение', weight='bold', size=18)
plt.show()

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

Это возвращает следующую гистограмму:

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

Использование графика QQ для проверки нормального распределения распределения

Общим графиком для проверки нормальности распределения данных является квантильно-квантильный график (или Q-Q график, сокращенно).

Q-Q график, или Квантиль-квантиль график, это визуальный инструмент в статистике для сравнения двух наборов данных, обычно ваших фактических данных и теоретического распределения, такого как нормальное распределение. Сначала оба набора данных сортируются, и для каждой точки данных вычисляются процентные величины, чтобы определить их положение относительно остальных.

Затем создается QQ-график, отображая процентили ваших фактических данных по оси x и теоретического распределения по оси y. Если точки на графике образуют прямую линию, это говорит о том, что ваши данные близко соответствуют теоретическому распределению; отклонения от линии указывают на различия. Этот график полезен для оценки качества подгонки, обнаружения выбросов и понимания распределения ваших данных.

В Python можно создать Q-Q график, используя функцию qqplot() из библиотеки statsmodel. Функция принимает распределение данных в качестве входных данных и по умолчанию предполагает, что мы хотим сравнить его с нормальным распределением. Мы можем добавить линию сравнения, передав аргумент line='s'.

Давайте взглянем, как мы можем использовать Q-Q график, чтобы оценить нормальность наших данных:

# Создание Q-Q графика для нормальных данных
import statsmodels.api as sm
fig = sm.qqplot(normal_data, line='s')
fig.suptitle('Построение Q-Q графика для нормальных данных', weight='bold')
plt.show()

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

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

Давайте посмотрим, как мы можем построить q-q график для нашего логнормального распределения, чтобы увидеть, как выглядят результаты.

# Создание Q-Q графика для логнормальных данных
import statsmodels.api as sm
fig = sm.qqplot(lognorm_data, line='s')
fig.suptitle('Построение Q-Q графика для логнормальных данных', weight='bold')

plt.show()

Выполнение вышеуказанного блока кода возвращает изображение ниже.

Мы можем увидеть, насколько распределение отклоняется от идеального нормального распределения (красная линия). В связи с этим мы можем с уверенностью сказать, что распределение не является нормальным.

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

Использование теста Шапиро-Уилка для проверки нормального распределения распределения

Тест Шапиро-Уилка — это статистический тест, который помогает проверить, принадлежит ли набор данных нормально распределенной популяции. Он сравнивает вашу выборку с нормальным распределением; если p-значение теста низкое (как правило, менее 0,05), это указывает на значительное отклонение ваших данных от нормального распределения.

В Python мы можем выполнить тест Шапиро-Уилка, используя модуль scipy.stats, с помощью функции shapiro. Функция возвращает как статистику теста, так и p-значение для гипотезы.

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

# Тест Шапиро-Уилка
from scipy.stats import shapiro

# Определение функции для теста Шапиро-Уилка
def shapiro_test(data, alpha=0.05):
    stat, p = shapiro(data)
    if p > alpha:
        print('Данные выглядят как нормальные (гауссовские)')
    else:
        print('Данные не выглядят как нормальные (гауссовские)')

В кодовом блоке выше мы сначала импортировали функцию shapiro. Затем определили новую функцию, которая принимает массив и значение alpha (по умолчанию 0,05). Если оцененное p-значение больше нашего alpha, мы выводим, что распределение нормальное. В противном случае указываем, что распределение ненормальное.

Давайте посмотрим, как это выглядит для нашего обычного набора данных:

# Запуск теста Шапиро-Уилка на нормальных данных
shapiro_test(normal_data)

# Возвращает: 
# Данные выглядят как нормальные (гауссовские)

Мы видим, что при передаче нашего нормального распределения в вновь определённую функцию, функция правильно утверждает, что наше распределение нормальное.

Теперь давайте попробуем это для нашего лог-нормального распределения. Мы можем сделать это, передав наш массив данных в функцию:

shapiro_test(lognorm_data)

# Возвращает:
# Данные не выглядят как нормальные (гауссовские)

Можно видеть, что, как и ожидалось, наша функция указывает на то, что данные не нормальны. Имейте в виду, что мы установили порог 0.05, который может изменить поведение.

Использование теста Д’Агостино K^2 для проверки нормального распределения распределения

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

  • Куртозис используется для количественного определения того, сколько распределения находится в хвосте, что позволяет нам тестировать на нормальность.

  • Скошенность используется для количественной оценки того, насколько распределение смещено влево или вправо, измеряя асимметричность распределения.

Тест D’Agostino K2 объединяет обе эти статистики и возвращает статистику и p-значение, которое указывает на нормальность распределения.

Подобно тесту Шапиро-Уилка, этот тест доступен в пакете SciPy с помощью функции normaltest()

Чтобы сделать результаты функции более понятными, мы можем обернуть функцию в пользовательскую функцию, позволяя нам передавать наше распределение и допустимое значение alpha. Давайте посмотрим, как мы можем создать эту функцию:

# Тест D'Agostino K2
from scipy.stats import normaltest

def dagostino_test(data, alpha=0.05):
    stat, p = normaltest(data)
    if p > alpha:
        print('Данные выглядят как нормальные (гауссовские)')
    else:
        print('Данные не выглядят как нормальные (гауссовские)')

В приведенной выше функции мы создали функцию, которая принимает наше распределение и значение альфа. Затем мы передаем наше распределение в функцию normaltest(). Если возвращаемое значение p больше нашего альфа, то мы предполагаем, что распределение нормальное.

Давайте рассмотрим пример того, как это может работать:

# Использование теста D'Agostino K2 для проверки нормального распределения
dagostino_test(normal_data)

# Возвращает:
# Данные выглядят как нормальные (гауссовские)

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

Теперь давайте посмотрим, как функция работает с нашим логнормальным распределением:

# Использование теста D'Agostino K2 для проверки логнормального распределения
dagostino_test(lognorm_data)

# Возвращает:
# Данные не выглядят как нормальные (гауссовские)

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

Заключение

В этом учебнике мы изучили различные методы оценки нормальности распределений данных, что является важным шагом в статистическом анализе. Сначала мы визуально исследовали данные с помощью гистограмм; колоколообразная кривая указывает на нормальность. Затем мы использовали квантильно-квантильные (Q-Q) графики для сравнения данных с теоретическим нормальным распределением, что помогает в визуальной оценке.

Мы также обсудили два статистических теста: тест Шапиро-Уилка и тест D’Агостино K2. Тест Шапиро-Уилка проверяет отклонение данных от нормального распределения, выдавая p-значение, и мы можем определить нормальность на основе выбранного альфа-порога. Тест D’Агостино K2 учитывает асимметрию и эксцесс, чтобы предоставить статистику и p-значение, позволяя нам делать выводы о нормальности данных.

Применяя эти методы как к нормальным, так и к не нормальным распределениям данных, мы получили представление о том, как их можно использовать на практике. Точная оценка нормальности данных является важной для выбора подходящих статистических тестов и получения надежных выводов в различных областях исследований и анализа.

Чтобы узнать больше о тесте Шапиро-Уилка в SciPy, ознакомьтесь с официальной документацией.

Ссылка на код статьи

Last updated