Вступление
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, Хи-квадрат, корреляции Пирсона и тест на умеренность.
Как только вы познакомитесь с тем, как проводить эти тесты, вы сможете проверить значимые отношения между зависимыми и независимыми переменными, адаптируясь к категориальному или непрерывному характеру переменных.