FBB MSU site Main page About me Terms

Статистика и линейные модели

По ссылке можно скачать или посмотреть R-скрипт с помощью которого проводились все (почти) рассчеты.

Задание 1

Выбран датасет California Housing Prices (kaggle.com). Он содержит поля: longitude, latitude, housing_median_age, total_rooms, total_bedrooms, population, households, median_income, median_house_value, ocean_proximity. Данные можно скачать по ссылке: housing.csv.

Задание 2

В рамках задания необходимо для взятого датасета сформулировать суммарно 6 гипотез H0/H1 и проверить их правильность.

В выбранном датасете в поле ocean_proximity фигурирует 4 значения: NEAR BAY, INLAND, <1H OCEAN, NEAR OCEAN. Соответственно, я могу рассматривать данные для домов в разной удаленности от океана как отдельные выборки и сравнивать их между собой.

#1

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

H0: цены домов в часе езды от океана и в глубине материка распределены одинаково.

H1: цены домов распределены по-разному.

В каждой из выборок более 40 измерений, значит пользуемся знаковым тестом. Дисперсии, вообще-то не известны, но я считаю, что на таком большом объеме данных можно вычислить дисперсию с большой точностью, значит для вычисления SE я буду пользоваться выборочными дисперсиями, считая, что они очень близки к реальным дисперсиям генеральных(/ной) совокупностей(/и).

Для применения знакового теста узнаем точное количество измерений в выборках, посчитаем их среднее и дисперсию. Затем воспользуемся формулой для рассчета стандартной ошибки (при известных неравных дисперсиях) и z-значения. Формулы представлены на рис 1.

Теперь нужно пониять, насколько велика вероятность получить такое z-значение, если верна нулевая гипотеза и обе выборки принадлежат одной генеральной совокупности. Для этого рассчитаем значение функции распределения нормального распределения от квантиля равного z-значению - мы получим p-value.


Рис 1. Формулы для рассчета SE при известных неравных дисперсиях и формула рассчета z-значения.
se1 = sqrt(var(h_ocean)/length(h_ocean) + var(inland)/length(inland))
z_value1 = (mean(h_ocean)-mean(inland))/se1

# z_value1 = 81.90669

pnorm(z_value1, lower.tail = F) #0
pnorm(z_value1, lower.tail = T) #1

z_значение оказалось равно 81.90669. То есть разница между распеределением цен домов в часе езды от океана и на метерике существенная. Вероятность получить еще большее z-значение, если верна нулевая гипотеза равна 0, значит у нас есть основание отвергнуть нулевую гипотезу об однородности распределений.

#2

Проверка гипотезы однородности с использованием распределения Стьюдента.

H0: цены домов в часе езды от океана и в глубине материка распределены одинаково.

H1: цены домов распределены по-разному.

Из каждой из выборок возьмем 12 значений (<40 измерений), пользуемся тестом Стьюдента. Дисперсии не известны, и, так как другой альтернативы для неизвестных дисперсий у нас нет, будем считать, что они равны. (Я не хочу брать дисперсии из #1, тк это бы нарушило чистоту эксперимента.) Для вычисления SE я буду пользоваться оценкой стандартного отклонения. Далее, используя средние значения для выборок и рассчитанную SE, вычислим t-значение. Формулы представлены на рис 2.

Рис 2. Формулы для рассчета SE при неизвестных равных дисперсиях, формула рассчета t-значения и df.
s2 = sqrt(((12-1)*sd(h_ocean_small)^2+(12-1)*sd(inland_small)^2)/(12+12-2)) 
se2 = s2*sqrt(1/12 + 1/12)

df2 = 12 + 12 - 2

t_value2 = (mean(h_ocean_small)-mean(inland_small))/se2

# t_value2 = 3.590202

pt(t_value2, df2, lower.tail = F) #0.0008147488

Теперь нужно понять, насколько велика вероятность получить такое t-значение, если верна нулевая гипотеза и обе выборки принадлежат одной генеральной совокупности. Для этого рассчитаем значение функции распределения распределения Стьюдента (с количеством степеней свобод, рассчитанным по соответствующей формуле) от квантиля равного t-значению - мы получим p-value.

t-значени оказалось равно 3.590202. То есть разница между распеределением цен домов в часе езды от океана и на метерике даже при такой маленькой выборке довольно существенная. Вероятность получить еще большее t-значение, если верна нулевая гипотеза равна 0.0008147488, значит у нас есть основание отвергнуть нулевую гипотезу об однородности распределений.

#3

Проверка гипотезы независимости с использованием распределения Хи-квадрат.

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

H1: в разной удаленности от океана преобладает дешевое или дороге жилье.

Медиана стоимости жилья по всей Калифорнии 200000$. Подсчитаем, сколько домов стоит дешевле и дороже 200000$ в разной удаленности от океана, следовательно получим 8 групп, которые запишем в табличку (см таблицу 1).

Таблица 1. Наблюдаемое количество дорогого и дешевого
жилья в разной удаленности от океана.
Priсe_less_200000Price_more_200000
INLAND5829714
<1H OCEAN40555056
NEAR BAY9031383
NEAR OCEAN10981551
median(data$median_house_value) #~200000

str1 = c(group0, group2, group4, group6)
str2 = c(group1, group3, group5, group7)

table1 <- data.frame('Priсe_less_200000' = str1, 
                     'Price_more_200000' = str2)

Проверим независимость параметров с помощью встроенного теста Хи-квадрат.

chisq.test(table1) # X-squared = 3888.2, df = 3, p-value < 2.2e-16
#df = (4-1)*(2-1) = 3

Получить такие данные если верна гипотеза о независимости очень маловероятно (p-value < 2.2e-16), значит у нас есть основания отвергнуть Н0.

Теперь проверим тоже самое, но посчитаем значение Хи-квадрата вручную. По алгоритму, изложенному в презентации (см таблицу 1.1), можно рассчитать таблицу ожидаемых значений (см таблицу 2), затем применить формулу, показанную на рис.3 и проанализировать результат.

Таблица 1.1. Данные для рассчета ожидаемых значений.

Priсe_less_200000Price_more_200000СуммаВероятность
INLAND5829714 65430.32
<1H OCEAN40555056 91110.44
NEAR BAY9031383 22860.11
NEAR OCEAN10981551 26490.13
Сумма118858704 20589
Вероятность0.580.42
Таблица 2. Ожидаемое количество дорогого и дешевого
жилья в разной удаленности от океана.
Priсe_less_200000Price_more_200000
INLAND38212767
<1H OCEAN52543805
NEAR BAY1314951
NEAR OCEAN15531124

str1_exp  = c(3821, 5254, 1314, 1553)
str2_exp = c(2767, 3805, 951, 1124)

table1_exp <- data.frame('Priсe_less_200000' = str1_exp,
                         'Price_more_200000' = str2_exp)

Рис 3. Формула для рассчета значения Хи-квадрат и df.
chisq3 = ((table1[1,1]-table1_exp[1,1])^2)/table1_exp[1,1] + ...
         + ((table1[4,2]-table1_exp[4,2])^2)/table1_exp[4,2]
# chisq3 = 3883.716
# df = (4-1)*(2-1) = 3

Значение хи-квадрат с df=3 на уровне значимости 0.01 равно 11.341, значит на основании полученного chisq3 = 3883.716 мы отвергаем гипотезу о независимости.

#4

Проверка на Goodness of fit с использованием распределения Хи-квадрат.

H0: количество продаваемых домов распределено равномерно по регионам в разной удаленности от океана.

H1: модель равномерного распределения плохо описывает имеющиеся данные.

Для проверки гипотезы посчитаем среднее количество подаваемого жилья, запишем это число в столбец ожидаемых значений (см таблицу 3) и с помощью теста хи-квадрат проверим, насколько хорошо такая можель соответствует реальному распределению количеству продаваемых домов в разных регионах (эти выборки обозначены как group**) (см рис. 4).

Таблица 3. Наблюдаемые и ожидаемые значения
количества продаваемых домов.
RealExpected
INLAND65516551
<1H OCEAN91366551
NEAR BAY22906551
NEAR OCEAN26586551

mean(group00, group11, group22, group33) # 6551

str11 = c(group00, group11, group22, group33)
str22 = c(6551, 6551, 6551, 6551)

table2 <- data.frame('Real' = str11, 'Expected' = str22)

Рис 4. Формула для рассчета значения Хи-квадрат и df.

chisq.test(table2) # X-squared = 3512.8, df = 3, p-value < 2.2e-16
# df = 4 - 1 = 3

chisq4 = ((group00-6551)^2)/6551 + ((group11-6551)^2)/6551 +
         ((group22-6551)^2)/6551 + ((group33-6551)^2)/6551
# chisq4 = 6104.991

Почему-то при подсчете значения хи-квадрат с помощью встроенного теста и вручную получились разные значения... Однако p-value < 2.2e-16 свидетельствует о том, что Н0 нужно отклонить (а в случае ручного подсчета получается еще большее значение хи-квадрат, так что сомнений, что можель равномерного распределения плохо описывает данные нет).

#5

Построим двусторонний доверительный интервал для среднего значения возраста продаваемого в Калифорнии жилья. Будем пользоваться нормальным распределением, так как у нас более 40 измерений. Формулы представлены на рис. 5.


Рис 5. Формулы для рассчета доверительного интервала.
mean(house_age) #28.63949

se5 = sd(house_age)/sqrt(length(house_age))

left = mean(house_age) + se5*qnorm((1-0.95)/2) # left = 28.46779 
right = mean(house_age) + se5*qnorm((1+0.95)/2) # right = 28.81118

Таким образом, оцениваемое среднее с вероятностью 0.95 лежит в интервале [28.46779; 28.81118].

#6

Построим одноронний доверительный интервал для среднего значения возраста продаваемого в Калифорнии жилья. Будем пользоваться нормальным распределением, так как у нас более 40 измерений. Формулы представлены на рис. 6.


Рис 5. Формулы для рассчета правостороннего доверительного интервала.
mean(house_age) #28.63949

se5 = sd(house_age)/sqrt(length(house_age))

left6 = mean(house_age) + se5*qnorm(1-0.95) # left6 = 28.49539

Таким образом, оцениваемое среднее с вероятностью 0.95 лежит в интервале [28.49539; ∞].

Задание 3

Проверим, нормально ли распределены цены домов около океана. Для этого построим гистограмму (рис. 7) и QQ-plot (рис. 8) для данного распределения.


Рис 7. Гистограмма распределения цен домов около океана.


Рис 8. QQ-plot.

По гистограмме (рис 9) и QQ-plot (рис 8) видно, что данное распределение рядом особенностей отличается от нормального. Во-первых, по форме QQ-plot (отклонение краевых точек в верхнюю полуплоскость) можно сказать, что у нас имеется ассимметрия в виде сдвига влево. Во-вторых небольшой сигмоидный участок в правом верхнем углу QQ-plot свидетельствует о том, что слева у нас присутствует "тяжелый хвост". Данные наблюдения подтверждаются при анализе гистограммы - сдвиг влево и очень тяжелый правый хвост.

О чем говорит такое наблюдение с человеческой точки зрения? О том, что около океана преобладает более дешевое жилье, но есть также некое количество очень дорогих домов. Логично - по совсем низким ценам жилье не продают застройщики, население в основном предпочитает жилье подешевле, но есть также элитные дома.

Также для проверки распределения на нормальность требуется применить специальные тесты. Применим (строгий) тест Шапиро-Уилка - получаем p-value < 2.2e-16, значит гипотеза нормальности отвергается. Проверим тоже самое с помощью теста Колмогорова-Смирнова. Если провести One-sample тест, то есть просто сравнить с нормальным распределением, получаем p-value < 2.2e-16. Если провести Two-sample тест, для которого сгенерировать нормальное распределение с ровно таким же количеством измерений, тем же средним и стандартным отклонением, как в нашей выборке, получаем p-value = 1.225e-06. То есть и в том и в другом случае гипотезу о нормальности распределения отвергаем. Можно было бы еще проверить с помощью критерия согласия Хи-квадрат, но мне лень.

shapiro.test(near_ocean) # p-value < 2.2e-16

ks.test(near_ocean, "pnorm") # p-value < 2.2e-16

ks.test(near_ocean, rnorm(length(near_ocean), mean(near_ocean), sd(near_ocean))) # p-value = 1.225e-06

Задание 4

Проведем проверку на выбросы в нашем распределении. Воспользуемся для этого графическим изображением данных в виде boxplot (рис. 9) и диаграммы Кливленда, постоенной для отсортированного массива данных (рис. 10).

boxplot(near_bay)
dotchart(sort(near_bay))

Рис 9. Boxplot распределения цен домов около залива.


Рис 10. Диаграммы Кливленда распределения цен домов около залива.

На диаграмме Кливленда видно, что есть выбросы в правой части распределения - то есть неожиданно большое количество дорогих домов. На графике Boxplot выбросы не показаны, значит данные выборки "укладываются в распределение" (в расстояние между усами - я не знаю, как сказать). Чтобы проверить, как выглядит распределение, можно построить гистограмму и QQ-plot для этого распределения (рис. 11 и 12).


Рис 11. Гистограмма распределения цен домов около залива.


Рис 12. QQ-plot.

Ситуация с распределением тут ровно такая же как и среди домов около океана (см задание 3). Явных выбросов не наблюдается.

Задание 5

Множественное тестирование.

Поправки:

  • FWER (Family-Wise Error Rate) - вероятность того, что среди тестов будет получен хотя бы один ложноположительный результат, меньше заданного порога α
  • FDR (False Discovery Rate) - процент ложноположительных результатов не больше некого заданного порога α

Сгенерируем 1000 рандомных парных стандартных нормальных выборок по 100 значений в каждой. Для каждой пары выборок проверим гипотезу об однородности с помощью t-теста и запишем в массив 1000 полученных p-value.

<.p>

Рис 13. Сравнение 1000 рандомных парных стандартных нормальных выборок.<.p>

p_value = NULL
for(i in 1:1000){
  before = rnorm(100)
  after = rnorm(100)
  p_value[i] = t.test(before, after)$p.value
}

Применим поправки:

  • FWER. Применим Holm-Bonferonni: α = 0.01
  • FDR. Применим Benjamini & Hochberg: α = 0.1

Рис 14. Сравнение 1000 одинаковых выборок с поправкой Холма-Бонферрони, α = 0.01.

Рис 15. Сравнение 1000 одинаковых выборок с поправкой Бенжамина и Хокберга, α = 0.01.

correction_fwer = p.adjust(p_value, method = "holm") < 0.01
any(correction_fwer) #FALSE
p_value_fwer = p_value*correction_fwer
plot(p_value_fwer)
correction_fdr = p.adjust(p_value, method = "BH") < 0.1 
any(correction_fdr) #TRUE
p_value_fdr = p_value*correction_fdr
plot(p_value_fdr)

Сгенерируем 990 рандомных парных стандартных нормальных выборок по 100 значений в каждой и 10 рандомных нормальных выборок с mean = 3 & sd = 5. Для каждой пары выборок проверим гипотезу об однородности с помощью t-теста и запишем в массив 1000 полученных p-value.

Рис 16. Сравнение 990 рандомных парных стандартных нормальных выборок и 10 отличающихся.

p_value_alter = NULL
for(i in 1:990){
  before = rnorm(100)
  after = rnorm(100)
  p_value_alter[i] = t.test(before, after)$p.value
}
for(i in 990:1000){
  before = rnorm(100)
  after = rnorm(100, 3, 5)
  p_value_alter[i] = t.test(before, after)$p.value
}

Применим поправки:

  • FWER. Применим Holm-Bonferonni: α = 0.01
  • FDR. Применим Benjamini & Hochberg: α = 0.1

Рис 17. Сравнение 990 одинаковых выборок и 10 отличающихся с поправкой Холма-Бонферрони, α = 0.01.

Рис 18. Сравнение 990 одинаковых и 10 отличающихся выборок с поправкой Бенжамина и Хокберга, α = 0.01.

correction_alter_fwer = p.adjust(p_value_alter, method = "holm") < 0.01
any(correction_alter_fwer) #TRUE
p_value_alter_fwer = p_value_alter*correction_alter_fwer
plot(p_value_alter_fwer, main="FWER correction")
correction_alter_fdr = p.adjust(p_value_alter, method = "BH") < 0.1 
any(correction_alter_fdr) #TRUE
p_value_alter_fdr = p_value_alter*correction_alter_fdr
plot(p_value_alter_fdr)

Вывод из этого всего - поправка на множественное сравнение обеспечивает надежную защиту от ложноположительных результатов. Однако, судя по графикам 17 и 18, эти поправки достаточно суровы, чтобы из 10, действительно отличающихся парных выборок, пропустить как значимо различающиеся только 3.

Задание 6

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

Линейная регрессия имеет вид Y = X*β + ε, где Y - вектор откликов (предсказываемая величина), X - матрица факторов регрессии (значения параметров, от которых зависят цены домов), β - вектор коэффициентов регрессии (именно их мы получаем при рассчете модели) и ε - вектор ошибок (обычно про них есть ряд предположений, позволяющих с ними работать).

Для обучения будем использовать данные для домов, которые продаются около залива. И, в качестве эксперимента, попробуем использовать для обучения только те из них, которые стоят меньше 200000$.
Для того, чтобы система работала, требуется заменить пустые ячейки средним значением по столбцу или выкинуть целиком строку с пропущенными значениями. Я выбираю первый вариант.

learning_set <- data[data$ocean_proximity == 'NEAR BAY',]
model = lm(median_house_value ~ housing_median_age + total_rooms + total_bedrooms + median_income, data=learning_set)
summary(model)

learning_set2 <- data[data$ocean_proximity == 'NEAR BAY' & data$median_house_value < 200000,]
model2 = lm(median_house_value ~ housing_median_age + total_rooms + total_bedrooms + median_income, data=learning_set2)
summary(model2)

Функция summary выдает данные построенной модели (см. таблицы 4, 5). Теперь мы знаем коэффициенты с которыми входят факторы регрессии в выражение, и знаем, насколько это достоверно, то есть насколько реально удалось выявить зависимость значений предсказываемой переменной от факторов. Для первой модели эти показатели очень хорошие, зависимость достоверна (p-value очень маленькие). Для воторой модели (которая построена на основе данных только по дешевым домам) показатели сильно хуже, в частности, получилось, что цена дома не зависит от возраста этого дома и почти не зависит от количества комнат.

Таблица 4. Модель, обученная на данных о домах около залива.

Coefficients:
       (Intercept)  housing_median_age         total_rooms      total_bedrooms       median_income  
         -66919.92             2550.94              -27.58              189.34            48189.13  

                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)        -66919.919   8774.841  -7.626 3.53e-14 ***
housing_median_age   2550.945    148.713  17.153  < 2e-16 ***
total_rooms           -27.583      2.859  -9.648  < 2e-16 ***
total_bedrooms        189.340     13.751  13.769  < 2e-16 ***
median_income       48189.129   1098.309  43.876  < 2e-16 ***

Таблица 5. Модель, обученная на данных о домах около залива, дешевле 200000.

Coefficients:
       (Intercept)  housing_median_age         total_rooms      total_bedrooms       median_income  
         84313.292             -84.365              -5.398              32.787           19444.257  

                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        84313.292   6123.663  13.768  < 2e-16 ***
housing_median_age   -84.365     96.410  -0.875  0.38177    
total_rooms           -5.398      2.344  -2.303  0.02150 *  
total_bedrooms        32.787     10.024   3.271  0.00111 ** 
median_income      19444.257   1155.214  16.832  < 2e-16 ***

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

test_set <- data[data$ocean_proximity != 'NEAR BAY',]

predictResult <- predict(model, test_set)
predictResult2 <- predict(model2, test_set)

Проверять качество обучения будем с помощью Min Max accuracy и MAPE. Эти показатели качества обучения по сути показывают, насколько предсказанные значения отклоняются от реальных. Формулы см на рис. 19.

Рис 19. Min Max accuracy и MAPE.

Для того, чтобы применить вышеозначенные критерии качества обучения, требуется датафрейм, содержащий предсказанные и реальные значения цен домов. Можно оценить насколько эти значения соответствуют друг другу, рассчитав коэффициент корреляции между двумя столбцами. В случае первой модели предсказанные значения совпадают с реальными на 73%, а в случае "ущербной" модели на 71% (то есть вообще-то она может тоже нормально работает).

actuals_preds <- data.frame(cbind(actuals=test_set$median_house_value, predicteds=predictResult))
correlation_accuracy <- cor(actuals_preds)

            actuals predicteds
actuals    1.000000   0.726244
predicteds 0.726244   1.000000

actuals_preds2 <- data.frame(cbind(actuals=test_set$median_house_value, predicteds=predictResult2))
correlation_accuracy2 <- cor(actuals_preds2)

             actuals predicteds
actuals    1.0000000  0.7073301
predicteds 0.7073301  1.0000000

Критерии рассчитываются по формулам (рис. 19).

# min_max accuracy and mean absolute percentage error

min_max_accuracy <- mean(apply(actuals_preds, 1, min) / apply(actuals_preds, 1, max)) # 0.7339644
mape <- mean(abs((actuals_preds$predicteds - actuals_preds$actuals))/actuals_preds$actuals) # 0.4293735

min_max_accuracy2 <- mean(apply(actuals_preds2, 1, min) / apply(actuals_preds2, 1, max)) # 0.7119408
mape2 <- mean(abs((actuals_preds2$predicteds - actuals_preds2$actuals))/actuals_preds2$actuals) # 0.3701025

Насколько я понимаю, значение min_max_accuracy (MMA) для идеальной линейной регрессии стремится к 1, а MAPE стремится к 0. У нас получилось, что для первой модели MMA = 73%, MAPE = 43%; а для второй MMA = 71%, MAPE = 37%.
По значениям MMA обе модели почти равноправны, первая немного лучше. По значениям MAPE получается, что вторая модель работает лучше, что немного странно, тк она обучалась на неполных данных. Не знаю, почему так получилось. Но в целом обе модели работают нормально, значит обучение было успешным.

Term 5


© Darya Potanina, 2017