Рубрики
Без рубрики

Статистический анализ гипотез в Python с корреляцией Anova, Хи-квадрат и Пирсона

Мы будем заниматься статистическим анализом гипотез с помощью Python с корреляцией Anova, Хи-квадрат и Пирсона на наборе данных Gapminder.

Автор оригинала: Dan Nelson.

Вступление

Python-невероятно универсальный язык, полезный для решения самых разнообразных задач в самых разных дисциплинах. Одной из таких дисциплин является статистический анализ наборов данных, и наряду с SPSS Python является одним из наиболее распространенных инструментов для статистики.

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

Знакомство С Библиотекой statsmodels В Python

Библиотека statsmodels – это модуль для Python, который дает легкий доступ к различным статистическим инструментам для проведения статистических тестов и изучения данных. Существует ряд статистических тестов и функций, к которым библиотека предоставляет доступ, включая обычные регрессии наименьших квадратов (OLS), обобщенные линейные модели, логит-модели, Анализ главных компонент (PCA) и Авторегрессионные интегрированные скользящие средние (ARIMA) модели.

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

Выбор Набора Данных

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

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

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

Отправной точкой для нашего статистического анализа набора данных Gapminder является исследовательский анализ данных. Мы будем использовать некоторые графические и графические функции из Matplotlib и Seaborn, чтобы визуализировать некоторые интересные отношения и получить представление о том, какие переменные отношения мы, возможно, захотим исследовать.

Исследовательский анализ и предварительная обработка данных

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

Мы импортируем эти две и любые другие библиотеки, которые будем использовать здесь:

import statsmodels.formula.api as smf
import statsmodels.stats.multicomp as multi
import scipy
from scipy.stats import pearsonr
import pandas as pd
from seaborn import regplot
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

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

# Check for missing data
def check_missing_values(df, cols):

    for col in cols:
       print("Column {} is missing:".format(col))
       print((df[col].values == ' ').sum())
       print()

# Convert to numeric
def convert_numeric(dataframe, cols):

    for col in cols:
        dataframe[col] = pd.to_numeric(dataframe[col], errors='coerce')

df = pd.read_csv("gapminder.csv")

print("Null values:")
print(df.isnull().values.any())

cols = ['lifeexpectancy', 'breastcancerper100th', 'suicideper100th']
norm_cols = ['internetuserate', 'employrate']

df2 = df.copy()

check_missing_values(df, cols)
check_missing_values(df, norm_cols)

convert_numeric(df2, cols)
convert_numeric(df2, norm_cols)

Вот результаты:

Null values:
Column lifeexpectancy is missing:
22

Column breastcancerper100th is missing:
40

Column suicideper100th is missing:
22

Column internetuserate is missing:
21

Column employrate is missing:
35

Есть несколько пропущенных значений, но наше числовое преобразование должно превратить их в значения NaN , что позволит провести исследовательский анализ данных в наборе данных.

В частности, мы могли бы попытаться проанализировать взаимосвязь между уровнем использования Интернета и ожидаемой продолжительностью жизни или между уровнем использования Интернета и уровнем занятости. Давайте попробуем сделать отдельные графики некоторых из этих отношений с помощью Seaborn и Matplotlib:

sns.lmplot(x="internetuserate", y="breastcancerper100th", data=df2, fit_reg=False)
plt.title("Internet Use Rate and Breast Cancer Per 100k")
plt.show()

sns.lmplot(x="internetuserate", y="lifeexpectancy", data=df2, fit_reg=False)
plt.title("Internet Use Rate and Life Expectancy")
plt.show()

sns.lmplot(x="internetuserate", y="employrate", data=df2, fit_reg=False)
plt.title("Internet Use Rate and Employment Rate")
plt.show()

Вот результаты графиков:

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

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

Существует также довольно сильная, хотя и менее линейная зависимость между ожидаемой продолжительностью жизни и уровнем использования Интернета.

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

Выбор Подходящей Гипотезы

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

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

  • АНОВАс
  • Тесты Хи-Квадрат
  • Регрессии.

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

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

Мы будем проводить различные виды проверки гипотез на базе данных. Тип проверки гипотез, который мы используем, зависит от природы наших объясняющих и ответных переменных. Различные комбинации объясняющих и ответных переменных требуют различных статистических тестов. Например, если одна переменная является категориальной, а другая-количественной, то требуется дисперсионный анализ.

Дисперсионный анализ (ANOVA)

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

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

Чтобы выполнить ANOVA на наборе данных Gapminder, нам нужно будет преобразовать некоторые функции, поскольку эти значения в наборе данных непрерывны, но анализ ANOVA подходит для ситуаций, когда одна переменная является категориальной, а другая – количественной.

Мы можем преобразовать данные из непрерывных в количественные, выбрав категорию и связав рассматриваемую переменную, разделив ее на процентили. Независимая переменная будет преобразована в категориальную переменную, в то время как зависимая переменная останется непрерывной. Мы можем использовать функцию cut() в Pandas для разделения фрейма данных на ячейки:

def bin(dataframe, cols):
	# Create new columns that store the binned data
    for col in cols:
        new_col_name = "{}_bins".format(col)
        dataframe[new_col_name] = pd.qcut(dataframe[col], 10, labels=["1=10%", "2=20%", "3=30%", "4=40%", "5=50%", "6=60%", "7=70%", "8=80", "9=90%", "10=100%"])

df3 = df2.copy()

# This creates new columns filled with the binned column data
bin(df3, cols)
bin(df3, norm_cols)

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

anova_df = df3[['lifeexpectancy', 'internetuserate_bins', 'employrate_bins']].dropna()

relate_df = df3[['lifeexpectancy', 'internetuserate_bins']]

anova = smf.ols(formula='lifeexpectancy ~ C(internetuserate_bins)', data=anova_df).fit()

print(anova.summary())

# We may also want to check the mean and standard deviation for the groups
mean = relate_df.groupby("internetuserate_bins").mean()
sd = relate_df.groupby("internetuserate_bins").std()
print(mean)
print(sd)

Вот результат работы модели:

                            OLS Regression Results                            
==============================================================================
Dep. Variable:         lifeexpectancy   R-squared:                       0.689
Model:                            OLS   Adj. R-squared:                  0.671
Method:                 Least Squares   F-statistic:                     38.65
Date:                Mon, 11 May 2020   Prob (F-statistic):           1.71e-35
Time:                        17:49:24   Log-Likelihood:                -521.54
No. Observations:                 167   AIC:                             1063.
Df Residuals:                     157   BIC:                             1094.
Df Model:                           9                                         
Covariance Type:            nonrobust                                         
======================================================================================================
                                         coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------------------------------
Intercept                             56.6603      1.268     44.700      0.000      54.157      59.164
C(internetuserate_bins)[T.2=20%]       1.6785      1.870      0.898      0.371      -2.015       5.372
C(internetuserate_bins)[T.3=30%]       5.5273      1.901      2.907      0.004       1.772       9.283
C(internetuserate_bins)[T.4=40%]      11.5693      1.842      6.282      0.000       7.932      15.207
C(internetuserate_bins)[T.5=50%]      14.6991      1.870      7.860      0.000      11.005      18.393
C(internetuserate_bins)[T.6=60%]      16.7287      1.870      8.946      0.000      13.035      20.422
C(internetuserate_bins)[T.7=70%]      17.8802      1.975      9.052      0.000      13.978      21.782
C(internetuserate_bins)[T.8=80]       19.8302      1.901     10.430      0.000      16.075      23.586
C(internetuserate_bins)[T.9=90%]      23.0723      1.901     12.135      0.000      19.317      26.828
C(internetuserate_bins)[T.10=100%]    23.3042      1.901     12.257      0.000      19.549      27.060
==============================================================================
Omnibus:                       10.625   Durbin-Watson:                   1.920
Prob(Omnibus):                  0.005   Jarque-Bera (JB):               11.911
Skew:                          -0.484   Prob(JB):                      0.00259
Kurtosis:                       3.879   Cond. No.                         10.0
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Мы видим, что модель дает очень малое P-значение ( Prob F-statistic ) 1.71 e-35 . Это намного меньше обычного порога значимости 0.05 таким образом , мы приходим к выводу, что существует существенная связь между ожидаемой продолжительностью жизни и уровнем использования Интернета.

Поскольку корреляционное P-значение действительно кажется значимым, и поскольку у нас есть 10 различных категорий, мы хотим запустить пост-hoc-тест, чтобы проверить, что разница между средними все еще значима даже после проверки ошибок типа 1. Мы можем проводить пост-hoc тесты с помощью модуля multicomp , используя Tukey Honestly Significant Difference (Tukey HSD) тест:

multi_comparison = multi.MultiComparison(anova_df["lifeexpectancy"], anova_df["internetuserate_bins"])
results = multi_comparison.tukeyhsd()
print(results)

Вот результаты теста:

  Multiple Comparison of Means - Tukey HSD, FWER=0.05  
=======================================================
 group1 group2 meandiff p-adj   lower    upper   reject
-------------------------------------------------------
10=100%  1=10% -23.3042  0.001 -29.4069 -17.2015   True
10=100%  2=20% -21.6257  0.001 -27.9633 -15.2882   True
10=100%  3=30% -17.7769  0.001 -24.2097  -11.344   True
10=100%  4=40% -11.7349  0.001 -17.9865  -5.4833   True
10=100%  5=50%  -8.6051  0.001 -14.9426  -2.2676   True
10=100%  6=60%  -6.5755 0.0352  -12.913   -0.238   True
10=100%  7=70%  -5.4241 0.2199 -12.0827   1.2346  False
10=100%   8=80  -3.4741 0.7474  -9.9069   2.9588  False
10=100%  9=90%  -0.2319    0.9  -6.6647    6.201  False
  1=10%  2=20%   1.6785    0.9  -4.3237   7.6807  False
  1=10%  3=30%   5.5273 0.1127  -0.5754  11.6301  False
  1=10%  4=40%  11.5693  0.001   5.6579  17.4807   True
  1=10%  5=50%  14.6991  0.001   8.6969  20.7013   True
  1=10%  6=60%  16.7287  0.001  10.7265  22.7309   True
  1=10%  7=70%  17.8801  0.001  11.5399  24.2204   True
  1=10%   8=80  19.8301  0.001  13.7274  25.9329   True
  1=10%  9=90%  23.0723  0.001  16.9696  29.1751   True
  2=20%  3=30%   3.8489 0.6171  -2.4887  10.1864  False
  2=20%  4=40%   9.8908  0.001   3.7374  16.0443   True
  2=20%  5=50%  13.0206  0.001   6.7799  19.2614   True
  2=20%  6=60%  15.0502  0.001   8.8095   21.291   True
  2=20%  7=70%  16.2017  0.001   9.6351  22.7683   True
  2=20%   8=80  18.1517  0.001  11.8141  24.4892   True
  2=20%  9=90%  21.3939  0.001  15.0563  27.7314   True
  3=30%  4=40%    6.042 0.0678  -0.2096  12.2936  False
  3=30%  5=50%   9.1718  0.001   2.8342  15.5093   True
  3=30%  6=60%  11.2014  0.001   4.8638  17.5389   True
  3=30%  7=70%  12.3528  0.001   5.6942  19.0114   True
  3=30%   8=80  14.3028  0.001     7.87  20.7357   True
  3=30%  9=90%   17.545  0.001  11.1122  23.9778   True
  4=40%  5=50%   3.1298 0.8083  -3.0237   9.2833  False
  4=40%  6=60%   5.1594 0.1862  -0.9941  11.3129  False
  4=40%  7=70%   6.3108 0.0638  -0.1729  12.7945  False
  4=40%   8=80   8.2608 0.0015   2.0092  14.5124   True
  4=40%  9=90%   11.503  0.001   5.2514  17.7546   True
  5=50%  6=60%   2.0296    0.9  -4.2112   8.2704  False
  5=50%  7=70%    3.181 0.8552  -3.3856   9.7476  False
  5=50%   8=80    5.131 0.2273  -1.2065  11.4686  False
  5=50%  9=90%   8.3732 0.0015   2.0357  14.7108   True
  6=60%  7=70%   1.1514    0.9  -5.4152    7.718  False
  6=60%   8=80   3.1014 0.8456  -3.2361    9.439  False
  6=60%  9=90%   6.3436 0.0496   0.0061  12.6812   True
  7=70%   8=80     1.95    0.9  -4.7086   8.6086  False
  7=70%  9=90%   5.1922 0.2754  -1.4664  11.8508  False
   8=80  9=90%   3.2422 0.8173  -3.1907    9.675  False
-------------------------------------------------------

Теперь мы лучше понимаем, какие группы в нашем сравнении имеют статистически значимые различия.

Если столбец reject имеет метку False , мы знаем, что рекомендуется отклонить нулевую гипотезу и предположить, что существует значительная разница между двумя сравниваемыми группами.

Критерий независимости Хи-квадрат

ANOVA подходит для случаев, когда одна переменная непрерывна, а другая категориальна. Теперь мы рассмотрим, как провести тест Хи-квадрат независимости .

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

Критерий независимости Хи-квадрат-это статистический критерий, используемый для анализа того, насколько значима связь между двумя категориальными переменными. При выполнении теста Хи-квадрат каждая категория одной переменной имеет свою частоту по сравнению с категориями второй переменной. Это означает, что данные могут быть отображены в виде таблицы частот, где строки представляют независимые переменные, а столбцы-зависимые переменные.

Подобно тому, как мы преобразовали нашу независимую переменную в категориальную переменную (путем ее бинирования), для теста ANOVA нам нужно сделать обе переменные категориальными, чтобы выполнить тест Хи-квадрат. Наша гипотеза для этой задачи такая же, как и гипотеза в предыдущей задаче, что существует существенная связь между ожидаемой продолжительностью жизни и уровнем использования Интернета.

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

Мы будем проводить пост-хок-сравнение для защиты от ошибок типа 1 (ложных срабатываний), используя подход, называемый Корректировкой Бонферрони . Чтобы сделать это, вы можете провести сравнение для различных возможных пар вашей переменной ответа, а затем проверить их скорректированную значимость.

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

После этого мы можем проверить наблюдаемые подсчеты и создать таблицы этих сравнений:

def half_bin(dataframe, cols):

    for col in cols:
        new_col_name = "{}_bins_2".format(col)
        dataframe[new_col_name] = pd.qcut(dataframe[col], 2, labels=["1=50%", "2=100%"])

half_bin(df3, ['internetuserate'])

# Recoding scheme
recode_2 = {"3=30%": "3=30%", "7=70%": "7=70%"}
recode_3 = {"2=20%": "2=20%", "8=80": "8=80"}
recode_4 = {"6=60%": "6=60%", "9=90%": "9=90%"}
recode_5 = {"4=40%": "4=40%", "7=70%": "7=70%"}

# Create the new features
df3['Comp_3v7'] = df3['lifeexpectancy_bins'].map(recode_2)
df3['Comp_2v8'] = df3['lifeexpectancy_bins'].map(recode_3)
df3['Comp_6v9'] = df3['lifeexpectancy_bins'].map(recode_4)
df3['Comp_4v7'] = df3['lifeexpectancy_bins'].map(recode_5)

Выполнение теста Хи-квадрат и пост-hoc сравнения включает в себя сначала построение таблицы сравнения кросс-табуляций. Таблица сравнения перекрестных таблиц показывает процент встречаемости переменной ответа для различных уровней объясняющей переменной.

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

# Get table of observed counts
count_table = pd.crosstab(df3['internetuserate_bins_2'], df3['lifeexpectancy_bins'])
print(count_table)
lifeexpectancy_bins     1=10%  2=20%  3=30%  4=40%  ...  7=70%  8=80  9=90%  10=100%
internetuserate_bins_2                              ...                             
1=50%                      18     19     16     14  ...      4     4      1        0
2=100%                      0      0      1      4  ...     15    11     16       19

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

Теперь нам нужно вычислить перекрестные вкладки для различных пар, которые мы создали выше, так как это то, что мы запускаем через тест Хи-квадрат:

count_table_3 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_3v7'])
count_table_4 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_2v8'])
count_table_5 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_6v9'])
count_table_6 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_4v7'])

После того как мы преобразовали переменные так, чтобы можно было выполнить тест Хи-квадрат, мы можем использовать функцию chi2_contingency в statsmodels для выполнения теста.

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

def chi_sq_test(table):

    print("Results for:")
    print(str(table))

    # Get column percentages
    col_sum = table.sum(axis=0)
    col_percents = table/col_sum
    print(col_percents)

    chi_square = scipy.stats.chi2_contingency(table)
    print("Chi-square value, p-value, expected_counts")
    print(chi_square)

    print()

print("Initial Chi-square:")
chi_sq_test(count_table)
print(" ")

chi_sq_test(count_table_3)
chi_sq_test(count_table_4)
chi_sq_test(count_table_5)
chi_sq_test(count_table_6)

Вот результаты:

Initial Chi-square:
Results for:
lifeexpectancy_bins     1=10%  2=20%  3=30%  4=40%  ...  7=70%  8=80  9=90%  10=100%
internetuserate_bins_2                              ...                             
1=50%                      18     19     16     14  ...      4     4      1        0
2=100%                      0      0      1      4  ...     15    11     16       19

[2 rows x 10 columns]
lifeexpectancy_bins     1=10%  2=20%     3=30%  ...      8=80     9=90%  10=100%
internetuserate_bins_2                          ...                             
1=50%                     1.0    1.0  0.941176  ...  0.266667  0.058824      0.0
2=100%                    0.0    0.0  0.058824  ...  0.733333  0.941176      1.0

[2 rows x 10 columns]
Chi-square value, p-value, expected_counts
(102.04563740451277, 6.064860600653971e-18, 9, array([[9.45251397, 9.97765363, 8.9273743 , 9.45251397, 9.45251397,
        9.97765363, 9.97765363, 7.87709497, 8.9273743 , 9.97765363],
       [8.54748603, 9.02234637, 8.0726257 , 8.54748603, 8.54748603,
        9.02234637, 9.02234637, 7.12290503, 8.0726257 , 9.02234637]]))
-----
 
Results for:
Comp_3v7                3=30%  7=70%
internetuserate_bins_2              
1=50%                      16      4
2=100%                      1     15
Comp_3v7                   3=30%     7=70%
internetuserate_bins_2                    
1=50%                   0.941176  0.210526
2=100%                  0.058824  0.789474
Chi-square value, p-value, expected_counts
(16.55247678018576, 4.7322137795376575e-05, 1, array([[ 9.44444444, 10.55555556],
       [ 7.55555556,  8.44444444]]))
-----
Results for:
Comp_2v8                2=20%  8=80
internetuserate_bins_2             
1=50%                      19     4
2=100%                      0    11
Comp_2v8                2=20%      8=80
internetuserate_bins_2                 
1=50%                     1.0  0.266667
2=100%                    0.0  0.733333
Chi-square value, p-value, expected_counts
(17.382650301643437, 3.0560286589975315e-05, 1, array([[12.85294118, 10.14705882],
       [ 6.14705882,  4.85294118]]))
-----
Results for:
Comp_6v9                6=60%  9=90%
internetuserate_bins_2              
1=50%                       6      1
2=100%                     13     16
Comp_6v9                   6=60%     9=90%
internetuserate_bins_2                    
1=50%                   0.315789  0.058824
2=100%                  0.684211  0.941176
Chi-square value, p-value, expected_counts
(2.319693757720874, 0.12774517376836148, 1, array([[ 3.69444444,  3.30555556],
       [15.30555556, 13.69444444]]))
-----
Results for:
Comp_4v7                4=40%  7=70%
internetuserate_bins_2              
1=50%                      14      4
2=100%                      4     15
Comp_4v7                   4=40%     7=70%
internetuserate_bins_2                    
1=50%                   0.777778  0.210526
2=100%                  0.222222  0.789474
Chi-square value, p-value, expected_counts
(9.743247922437677, 0.0017998260000241526, 1, array([[8.75675676, 9.24324324],
       [9.24324324, 9.75675676]]))
-----

Если мы смотрим только на результаты для полной таблицы подсчета, то, похоже, есть P-значение 6.064860600653971 e-18 .

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

Сравнение 6 против 9 дает нам P-значение 0.127 , который находится выше 0.05 порог, указывающий на то, что разница для этой категории может быть несущественной. Наблюдение различий в сравнениях помогает нам понять, почему мы должны сравнивать разные уровни друг с другом.

Корреляция Пирсона

Мы рассмотрели тест, который вы должны использовать, когда у вас есть категориальная объясняющая переменная и количественная переменная ответа (ANOVA), а также тест, который вы используете, когда у вас есть две категориальные переменные (Хи-квадрат).

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

Пирсон Корреляционный тест используется для анализа силы связи между двумя предоставленными переменными, обеими количественными по своей природе. Значение, или сила корреляции Пирсона, будет находиться между +1 и -1 .

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

Поскольку набор данных Gapminder имеет свои особенности, представленные количественными переменными, нам не нужно делать никакого категориального преобразования данных, прежде чем запускать корреляцию Пирсона на нем. Обратите внимание, что предполагается, что обе переменные нормально распределены и в наборе данных не так много значительных выбросов. Нам понадобится доступ к SciPy, чтобы провести корреляцию Пирсона.

Мы построим график зависимости между ожидаемой продолжительностью жизни и уровнем использования Интернета, а также уровнем использования Интернета и уровнем занятости, просто чтобы посмотреть, как может выглядеть другой корреляционный график. После создания графической функции мы будем использовать функцию person() из SciPy для выполнения корреляции и проверки результатов:

df_clean = df2.dropna()
df_clean['incomeperperson'] = df_clean['incomeperperson'].replace('', np.nan)

def plt_regression(x, y, data, label_1, label_2):

    reg_plot = regplot(x=x, y=y, fit_reg=True, data=data)
    plt.xlabel(label_1)
    plt.ylabel(label_2)
    plt.show()

plt_regression('lifeexpectancy', 'internetuserate', df_clean, 'Life Expectancy', 'Internet Use Rate')
plt_regression('employrate', 'internetuserate', df_clean, 'Employment Rate', 'Internet Use Rate')

print('Assoc. - life expectancy and internet use rate')
print(pearsonr(df_clean['lifeexpectancy'], df_clean['internetuserate']))

print('Assoc. - between employment rate and internet use rate')
print(pearsonr(df_clean['employrate'], df_clean['internetuserate']))

Вот результаты:

корреляция между уровнем использования Интернета и ожидаемой продолжительностью жизни
корреляция между уровнем использования Интернета и уровнем занятости
Assoc. - life expectancy and internet use rate
(0.77081050888289, 5.983388253650836e-33)
Assoc. - between employment rate and internet use rate
(-0.1950109538173115, 0.013175901971555317)

Первое значение-это направление и сила корреляции, а второе-Р-значение. Эти цифры свидетельствуют о довольно сильной корреляции между ожидаемой продолжительностью жизни и уровнем использования Интернета, которая не является случайной. Между тем существует более слабая, хотя и все еще значимая корреляция между уровнем занятости и уровнем использования Интернета.

Обратите внимание, что также можно выполнить корреляцию Пирсона на категориальных данных, хотя результаты будут выглядеть несколько иначе. Если бы мы захотели, мы могли бы сгруппировать уровни доходов и провести корреляцию Пирсона по ним. Вы можете использовать его для проверки наличия модерирующих переменных, которые могут повлиять на вашу ассоциацию интересов.

Модераторы и статистическое взаимодействие

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

Умеренность-это когда третья (или более) переменная влияет на силу связи между независимой переменной и зависимой переменной.

Существуют различные способы проверки умеренности/статистического взаимодействия между третьей переменной и независимыми/зависимыми переменными. Например, если вы провели тест ANOVA, вы можете проверить его на умеренность, выполнив двусторонний тест ANOVA, чтобы проверить возможную умеренность.

Однако надежный способ проверки на умеренность, независимо от того, какой тип статистического теста вы провели (ANOVA, Хи-квадрат, корреляция Пирсона), состоит в том, чтобы проверить, существует ли связь между объясняющими и ответными переменными для каждой подгруппы/уровня третьей переменной.

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

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

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

Давайте быстро рассмотрим, как проводить корреляции Пирсона для модерирующих переменных. Мы создадим искусственные категории/уровни из наших непрерывных функций. Процесс тестирования на умеренность для двух других типов тестов (Хи-квадрат и ANOVA) очень похож, но вместо этого у вас будут уже существующие категориальные переменные для работы.

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

def income_groups(row):
    if row['incomeperperson'] <= 744.23:
        return 1
    elif row['incomeperperson'] <= 942.32:
        return 2
    else:
        return 3


# Apply function and set the new features in the dataframe
df_clean['income_group'] = df_clean.apply(lambda row: income_groups(row), axis=1)

# Create a few subframes to try test for moderation
subframe_1 = df_clean[(df_clean['income_group'] == 1)]
subframe_2 = df_clean[(df_clean['income_group'] == 2)]
subframe_3 = df_clean[(df_clean['income_group'] == 3)]

print('Assoc. - life expectancy and internet use rate for low income countries')

print(pearsonr(subframe_1['lifeexpectancy'], subframe_1['internetuserate']))

print('Assoc. - life expectancy and internet use rate for medium income countries')

print(pearsonr(subframe_2['lifeexpectancy'], subframe_2['internetuserate']))

print('Assoc. - life expectancy and internet use rate for high income countries')

print(pearsonr(subframe_3['lifeexpectancy'], subframe_3['internetuserate']))

Вот результаты:

Assoc. - life expectancy and internet use rate for low income countries
(0.38386370068495235, 0.010101223355274047)

Assoc. - life expectancy and internet use rate for medium income countries
(0.9966009508278395, 0.05250454954743393)

Assoc. - life expectancy and internet use rate for high income countries
(0.7019997488251704, 6.526819886007788e-18)

Опять же, первое значение-это направление и сила корреляции, в то время как второе-это P-значение.

Вывод

statsmodels – это чрезвычайно полезная библиотека, которая позволяет пользователям Python анализировать данные и выполнять статистические тесты на наборах данных. Вы можете провести тесты Anova, Хи-квадрат, корреляции Пирсона и тест на умеренность.

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