Сегодня мы работаем с набором данных “Титаник”. Это данные реальных людей, которые путешествовали на “Титанике”, некоторая информация о них, а так же выжили они или нет в результате крушения. Мы загрузим данные, исследуем их, попытаемся предсказать какие переменные влияют на шансы выжить.

Мы возьмем эти данные из специального модуля.

install.packages('titanic')

С остальными библиотеками мы уже знакомы, загрузим все.

library('dplyr')
library('titanic')
library('ggplot2')
library('psych')

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

data("titanic_train")
head(titanic_train)
##   PassengerId Survived Pclass
## 1           1        0      3
## 2           2        1      1
## 3           3        1      3
## 4           4        1      1
## 5           5        0      3
## 6           6        0      3
##                                                  Name    Sex Age SibSp
## 1                             Braund, Mr. Owen Harris   male  22     1
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1
## 3                              Heikkinen, Miss. Laina female  26     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1
## 5                            Allen, Mr. William Henry   male  35     0
## 6                                    Moran, Mr. James   male  NA     0
##   Parch           Ticket    Fare Cabin Embarked
## 1     0        A/5 21171  7.2500              S
## 2     0         PC 17599 71.2833   C85        C
## 3     0 STON/O2. 3101282  7.9250              S
## 4     0           113803 53.1000  C123        S
## 5     0           373450  8.0500              S
## 6     0           330877  8.4583              Q

Посмотрим на переменные. По описанию переменных и данным в них, опишите их тип (количественные, категориальные, порядковые, бинарные).

?titanic_train
## starting httpd help server ... done
str(titanic_train)
## 'data.frame':    891 obs. of  12 variables:
##  $ PassengerId: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Survived   : int  0 1 1 1 0 0 0 0 1 1 ...
##  $ Pclass     : int  3 1 3 1 3 3 1 3 3 2 ...
##  $ Name       : chr  "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
##  $ Sex        : chr  "male" "female" "female" "female" ...
##  $ Age        : num  22 38 26 35 35 NA 54 2 27 14 ...
##  $ SibSp      : int  1 1 0 1 0 0 0 3 0 1 ...
##  $ Parch      : int  0 0 0 0 0 0 0 1 2 0 ...
##  $ Ticket     : chr  "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
##  $ Fare       : num  7.25 71.28 7.92 53.1 8.05 ...
##  $ Cabin      : chr  "" "C85" "" "C123" ...
##  $ Embarked   : chr  "S" "C" "S" "S" ...

Сегодня мы попробуем построить самые простые гипотезы и протестировать их. Мы будем пытаться предсказать переменную Survived (выжил пассажир или нет в результате крушения).

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

table(titanic_train$Survived)
## 
##   0   1 
## 549 342

Мы даже можем посмотреть на эти данные как на части целого (proportion.)

prop.table(table(titanic_train$Survived))
## 
##         0         1 
## 0.6161616 0.3838384

Давайте построим график.

ggplot(titanic_train, aes(x = Survived)) +
  geom_bar()

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

Пол

Если вдруг вы помните, то на “Титанике” оперировали правилом “первыми - женщины и дети”. Давайте посмотрим, как эти переменные связаны с нашей зависимой.

titanic_train$Sex <- as.factor(titanic_train$Sex)
summary(titanic_train$Sex)
## female   male 
##    314    577

Какой самый простой способ посмотреть на то, как пол связан с зависимой переменной?

prop.table(table(titanic_train$Sex, titanic_train$Survived))
##         
##                   0          1
##   female 0.09090909 0.26150393
##   male   0.52525253 0.12233446

Такой вариант, к сожалению, не очень информативен, потому что дает нам пропорцию в КАЖДОЙ ячейке нашей таблицы 2x2, а нам нужна разбивка по рядам. Сделать это можно так:

# если мы заменим 1 на 2, то получим proportion table по колонкам
prop.table(table(titanic_train$Sex, titanic_train$Survived), 1)
##         
##                  0         1
##   female 0.2579618 0.7420382
##   male   0.8110919 0.1889081

Давайте посмотрим на распределение на графике.

ggplot(subset(titanic_train, Survived == 0), aes(x = Sex)) +
  geom_bar()

ggplot(subset(titanic_train, Survived == 1), aes(x = Sex)) +
  geom_bar(aes(fill = Sex))

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

Титул

Перед тем как перейти ко второй половине теории “первыми - женщины и дети” давайте подумаем, не можем ли мы в наших данных выделить дополнительный признак, на основе которого тоже можно будет делать предсказания/работать с другими переменными.

Да, мы видим, что в каждом имени у нас “зашит” титул, из которого мы тоже можем вычленить некоторую информацию (возраст, статусность, принадлежность к аристократии).

Подумайте, по какому признаку мы могли вычленить титул в отдельную переменную.

titanic_train$Name[1]
## [1] "Braund, Mr. Owen Harris"

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

# в параметре split в квадратных скобках указываем знаки, по которым хотим разбить
strsplit(titanic_train$Name[1], split = '[,.]')
## [[1]]
## [1] "Braund"       " Mr"          " Owen Harris"

Убедимся, что вся эта история возвращает нам контэйнер [[1]] с несколькими элементами внутри.

strsplit(titanic_train$Name[1], split = '[,.]')[[1]][2]
## [1] " Mr"

Отлично! Давайте создадим новую переменную Title и применим эту функцию ко всем рядам внтури c помощью функции sapply. Она работает как цикл for - проходит по всем рядам и применяет заданную функцию. в аргументе FUN мы задаем, какую функцию мы хотим использовать. Если это не встроенная функция, то пишем ее сами по синтаксису циклов.

titanic_train$Title <- sapply(titanic_train$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][2]})
table(titanic_train$Title)
## 
##          Capt           Col           Don            Dr      Jonkheer 
##             1             2             1             7             1 
##          Lady         Major        Master          Miss          Mlle 
##             1             2            40           182             2 
##           Mme            Mr           Mrs            Ms           Rev 
##             1           517           125             1             6 
##           Sir  the Countess 
##             1             1

Еще, если посмотрит выше на нашего ‘Mr’, то увидим, что в титуле был пробел. Давайте удалим все затесавшиеся пробелы в начале и конце строк, иначе нам потом будет сложно фильтровать. Функция sub находит заданные символы (пробелы " “) и заменяет их на отсуттвие символов (”“) в нашем случае.

titanic_train$Title <- sub(' ', '', titanic_train$Title)

Теперь давайте подумаем о наших титулах с точки зрения предсказательной важности. У нас есть достаточно редкие категории, которые встречаются один или всего несколько раз. Нужно ли их сохранять? Нужно ли укрупнить категории? Нет точного ответа, сколько категорий - хорошо. Но лучше ориентироваться не больше, чем на 5-6 категорий, по которым равномерно распределены наши наблюдения. Пока давайте избавимся от совсем избыточных категорий.

Какие встречаются совсем редко?

‘Capt’, ‘Don’, ‘Major’, ‘Sir’ встречаются редко и все они вцелом значат, что носитель титула - крупный землевладелец. ‘Dona’, ‘Lady’, ‘the Countess’, ‘Jonkheer’ - то же самое, но для женщин. Давайте объединим этим категории. Mme и Mlle (madame и mademoiselle) - титулы французской аристократии, давайте их тоже объединим. Для фильтрации наших векторов воспользуемся %in% - благодаря этому оператору R сравнивает значение в нужном ряду нужной колонке с рядом значений в векторе и, если условие выполняется, присваивает новое значение переменной (похоже по принципу на конструкцию if else).

titanic_train$Title[titanic_train$Title %in% c('Capt', 'Don', 'Major', 'Sir')] <- 'Sir'
titanic_train$Title[titanic_train$Title %in% c('Lady', 'the Countess', 'Jonkheer')] <- 'Lady'
titanic_train$Title[titanic_train$Title %in% c('Mlle', 'Mme')] <- 'Mlle'

table(titanic_train$Title)
## 
##    Col     Dr   Lady Master   Miss   Mlle     Mr    Mrs     Ms    Rev 
##      2      7      3     40    182      3    517    125      1      6 
##    Sir 
##      5

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

titanic_train$Title <- as.factor(titanic_train$Title)

Возраст

Хорошо, кажется теория с “первыми - женщины и дети” наполовину подтвердилась. Давайте разбираться с возрастом. Это у нас количественная переменная, можем посмотреть ее дискриптивные статитистики.

summary(titanic_train$Age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.42   20.12   28.00   29.70   38.00   80.00     177

Ого! 177 пропущенных значений. Давайте подумаем, что с этим можно сделать? Какие стратегии вы предложите? (Хорошие статьи по стратегиям работы с пропущенными значениями: https://r-analytics.blogspot.com/2017/01/blog-post.html#.XAV41WgzZRY https://medium.com/coinmonks/dealing-with-missing-data-using-r-3ae428da2d17)

Выше мы выделили новый признак. Давайте посмотрим связан ли титул с возрастом.

ggplot(titanic_train, aes(x = Title, y = Age)) +
  geom_boxplot()
## Warning: Removed 177 rows containing non-finite values (stat_boxplot).

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

Посмотрим, как остутствующие значения распределены по группам.

table(subset(titanic_train, is.na(Age))$Title)
## 
##    Col     Dr   Lady Master   Miss   Mlle     Mr    Mrs     Ms    Rev 
##      0      1      0      4     36      0    119     17      0      0 
##    Sir 
##      0

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

median_Age <- summarize(group_by(titanic_train, Title), median_Age = median(Age, na.rm = TRUE))
median_Age
## # A tibble: 11 x 2
##    Title  median_Age
##    <fct>       <dbl>
##  1 Col          58  
##  2 Dr           46.5
##  3 Lady         38  
##  4 Master        3.5
##  5 Miss         21  
##  6 Mlle         24  
##  7 Mr           30  
##  8 Mrs          35  
##  9 Ms           28  
## 10 Rev          46.5
## 11 Sir          49

Заполним пропуски с помощью пайплайнов и функции ifelse. Подумайте над структурой такого запроса. Совет - сначала создадим новую колонку, чтобы случайно не перезаписать оригинальную переменную кодом с ошибкой.

titanic_train <-
  titanic_train %>% 
  group_by(Title) %>% 
  mutate(Copy_Age = ifelse(is.na(Age), median(Age, na.rm = TRUE), Age))

Давайте посмотрим на наши NA и сверимся, что функция сработала верно.

subset(titanic_train, is.na(Age))
## # A tibble: 177 x 14
## # Groups:   Title [5]
##    PassengerId Survived Pclass Name  Sex     Age SibSp Parch Ticket   Fare
##          <int>    <int>  <int> <chr> <fct> <dbl> <int> <int> <chr>   <dbl>
##  1           6        0      3 Mora~ male     NA     0     0 330877   8.46
##  2          18        1      2 Will~ male     NA     0     0 244373  13   
##  3          20        1      3 Mass~ fema~    NA     0     0 2649     7.22
##  4          27        0      3 Emir~ male     NA     0     0 2631     7.22
##  5          29        1      3 "O'D~ fema~    NA     0     0 330959   7.88
##  6          30        0      3 Todo~ male     NA     0     0 349216   7.90
##  7          32        1      1 Spen~ fema~    NA     1     0 PC 17~ 147.  
##  8          33        1      3 Glyn~ fema~    NA     0     0 335677   7.75
##  9          37        1      3 Mame~ male     NA     0     0 2677     7.23
## 10          43        0      3 Krae~ male     NA     0     0 349253   7.90
## # ... with 167 more rows, and 4 more variables: Cabin <chr>,
## #   Embarked <chr>, Title <fct>, Copy_Age <dbl>

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

titanic_train$Age <- titanic_train$Copy_Age

И наконец-то посмотрим распределение выживших по возрасту.

ggplot(titanic_train, aes(x = Age, group = Survived)) +
  geom_density(aes(fill = Survived), alpha =0.5)

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

titanic_train$Child <- 0
titanic_train$Child[titanic_train$Age < 18] <- 1

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

View(titanic_train)

aggregate(Survived ~ Child + Sex, data=titanic_train, FUN=sum)
##   Child    Sex Survived
## 1     0 female      195
## 2     1 female       38
## 3     0   male       84
## 4     1   male       25

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

aggregate(Survived ~ Child + Sex, data=titanic_train, FUN= function(x) {sum(x)/length(x)})
##   Child    Sex  Survived
## 1     0 female 0.7528958
## 2     1 female 0.6909091
## 3     0   male 0.1631068
## 4     1   male 0.4032258

Влияет ли тот факт, что пассажир младше 18 лет на то, выживет он или нет, по вашему мнению?

18 лет мы выбрали достаточно арбитрарно (как и многие другие вещи в статистике). Давайте предположим, что детей опеределяли не юридически, а на “глаз”. Давайте перекодируем переменную Child, на этот раз будем считать детьми всех младше 12.

titanic_train$Child <- 0
titanic_train$Child[titanic_train$Age < 12] <- 1
aggregate(Survived ~ Child + Sex, data=titanic_train, FUN= function(x) {sum(x)/length(x)})
##   Child    Sex  Survived
## 1     0 female 0.7588652
## 2     1 female 0.5937500
## 3     0   male 0.1620112
## 4     1   male 0.5500000

Стало ли лучше? Давайте экспериментальным путем ще раз уменьшим возраст “детей”.

titanic_train$Child <- 0
titanic_train$Child[titanic_train$Age < 10] <- 1
aggregate(Survived ~ Child + Sex, data=titanic_train, FUN= function(x) {sum(x)/length(x)})
##   Child    Sex  Survived
## 1     0 female 0.7535211
## 2     1 female 0.6333333
## 3     0   male 0.1626617
## 4     1   male 0.5833333

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

Цена билета (Fare) и класс

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

summary(titanic_train$Fare)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00    7.91   14.45   32.20   31.00  512.33

Не переживайте из-за минимального значения 0 - здесь это не пропуски, а специальные билеты (например, для членов команды или их семей).

Класс у нас переменная категориальная. Давайте посмотрим, как они соотносятся между собой.

ggplot(titanic_train, aes(x = as.factor(Pclass), y = Fare)) +
  geom_boxplot()

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

ggplot(titanic_train, aes(x = as.factor(Pclass), y = Fare)) +
  geom_boxplot(outlier.shape = NA) +
  scale_y_continuous(limits = c(0, 150)) 
## Warning: Removed 29 rows containing non-finite values (stat_boxplot).

Подтверждает ли предположение, что цена сильно зависит от класса? Какую переменную лучше использовать? Ваши версии.

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

titanic_train$Fare2 <- '30+'
titanic_train$Fare2[titanic_train$Fare < 30 & titanic_train$Fare >= 20] <- '20-30'
titanic_train$Fare2[titanic_train$Fare < 20 & titanic_train$Fare >= 10] <- '10-20'
titanic_train$Fare2[titanic_train$Fare < 10] <- '<10'

Теперь давайте посмотрим, как цена билета и класс каюты влияют на “выживаемость”.

ggplot(titanic_train, aes(x = Fare2, group = Survived)) +
  geom_bar(aes(fill = Survived)) +
  facet_wrap(~Pclass)

Какие выводы можете сделать? В приницие все, как и ожидалось. Самая большая пропорпция выживших людей - в первом классе с самыми дорогими билетами, во втором классе пропорции примерно 50/50 во всех категориях, в третьем классе интересно, что люди с билетами за 10-20 долларов выживали в пропорции чаще, чем люди с другими билетами (в том числе и дороже). Возможно, это как-то связано с расположением кают в каждой ценовой категории. Мы с вами не настраиваем сейчас модель так тонко, поэтому просто примем решение использовать для предсказания только одну перменную из класса и цены за проезд.

Сформулируем гипотезу: Чем выше класс путешествующего пассажира, тем больше вероятности, что он выживет.

Размер семьи

Последний признак, с которым мы будем работать - размер семьи. У нас есть признаки SpSib и ParCh, которые показывают сколько горизонтальных и вертикальных родственников было у пассажира на борту.

Пока мы не начали работать, какие у вас есть идеи? Как размер семьи может быть свзязан с шансами на выживание?

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

titanic_train$FamilySize <- titanic_train$SibSp + titanic_train$Parch + 1

table(titanic_train$FamilySize)
## 
##   1   2   3   4   5   6   7   8  11 
## 537 161 102  29  15  22  12   6   7

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

ggplot(titanic_train, aes(x=FamilySize,group=Survived)) +
  geom_bar(aes(fill=Survived))

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

titanic_train$FamilySize[titanic_train$FamilySize == 1] <- 'Alone'
titanic_train$FamilySize[titanic_train$FamilySize %in% c(2,3,4)] <- 'Small'
titanic_train$FamilySize[titanic_train$FamilySize %in% c(5,6,7,8,11)] <- 'Big'
titanic_train$FamilySize <- as.factor(titanic_train$FamilySize) 

Давайте еще раз построим график.

ggplot(titanic_train, aes(x=FamilySize, group = Survived)) +
  geom_bar(aes(fill=Survived))

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

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

Тестирование гипотез

Выше мы сформулировали несколько гипотез. Давайте попробуем их проверить. Сначала мы воспользуемся непараметрическим тестом хи-квадрат. http://kineziolog.su/content/proverka-gipotez-kriteriem-khi-kvadrat-pirsona Такой тест дает нам понимание, существенно ли отличаются значения в наших таблицах (например, выжившие мужчины и женщины).

Потом мы попробуем протестировать наши гипотезы тестом Стьюдента, чтобы понять, статистически ли значимо отличаются между собой средние наших выборок, сформулированных в гипотезе (например, мальчики выживают чаще, чем взрослые мужчины). http://www.machinelearning.ru/wiki/index.php?title=%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B9_%D0%A1%D1%82%D1%8C%D1%8E%D0%B4%D0%B5%D0%BD%D1%82%D0%B0

Затем попробуем построить логистическую регрессию, в которую в качестве независимых переменных передадим те признаки, которые по нашему мнению влияют на шансы выжить. https://habr.com/company/io/blog/265007/

install.packages("gmodels")
library(gmodels)

Хи-квадрат

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

Когда мы формлируем гипотезу, мы всегда хотим опровергнуть гипотезу нулевую: о том, что изменений нет/фактор не влияет. H0: пол пассажира не влияет на шансы выжить

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

CrossTable(titanic_train$Survived,titanic_train$Sex)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## | Chi-square contribution |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  891 
## 
##  
##                        | titanic_train$Sex 
## titanic_train$Survived |    female |      male | Row Total | 
## -----------------------|-----------|-----------|-----------|
##                      0 |        81 |       468 |       549 | 
##                        |    65.386 |    35.583 |           | 
##                        |     0.148 |     0.852 |     0.616 | 
##                        |     0.258 |     0.811 |           | 
##                        |     0.091 |     0.525 |           | 
## -----------------------|-----------|-----------|-----------|
##                      1 |       233 |       109 |       342 | 
##                        |   104.962 |    57.120 |           | 
##                        |     0.681 |     0.319 |     0.384 | 
##                        |     0.742 |     0.189 |           | 
##                        |     0.262 |     0.122 |           | 
## -----------------------|-----------|-----------|-----------|
##           Column Total |       314 |       577 |       891 | 
##                        |     0.352 |     0.648 |           | 
## -----------------------|-----------|-----------|-----------|
## 
## 
options(scipen = 999) # отключаем научную запись малых чисел.

chisq.test(table(titanic_train$Survived,titanic_train$Sex))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(titanic_train$Survived, titanic_train$Sex)
## X-squared = 260.72, df = 1, p-value < 0.00000000000000022

Чтобы опровергнуть или принять гипотезу, мы в первую очередь смотрим на p-значение. Оно нам говорит, является ли статистика с таким значением, которое мы получили нормальным для распределения или попадает в ту его часть, где находится очень маленькое количество значений. В частности, когда мы отвергаем нулевую гипотезу при p-value < 0.05, мы фактически говорим, что мы отвергаем нулевую гипотезу с вероятностью 5%, что мы ошиблись.

Отвергаем ли мы нулевую гипотезу?

https://ru.wikipedia.org/wiki/P-%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5

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

H0: Для пассажиров мужского пола возраст не влияет на шансы выжить. H0: Для пассажиров женского пола возраст не влияет на шансы выжить.

titanic_men <- subset(titanic_train, Sex == 'male')
table(titanic_men$Survived, titanic_men$Child)
##    
##       0   1
##   0 453  15
##   1  88  21
chisq.test(table(titanic_men$Survived, titanic_men$Child))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(titanic_men$Survived, titanic_men$Child)
## X-squared = 36.287, df = 1, p-value = 0.000000001703
titanic_women <- subset(titanic_train, Sex == "female")
table(titanic_women$Survived, titanic_women$Child)
##    
##       0   1
##   0  70  11
##   1 214  19
chisq.test(table(titanic_women$Survived, titanic_women$Child))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(titanic_women$Survived, titanic_women$Child)
## X-squared = 1.4679, df = 1, p-value = 0.2257

Можем ли мы отвергнуть нулевые гипотезы?

Упражнение: проверьте гипотезы о влиянии размера семьи и класс пассажира на выживание

Критерий Стьюдента

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

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

t.test(Age~Survived,data = titanic_women)
## 
##  Welch Two Sample t-test
## 
## data:  Age by Survived
## t = -2.3118, df = 149.49, p-value = 0.02216
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -6.9744559 -0.5462351
## sample estimates:
## mean in group 0 mean in group 1 
##        24.71605        28.47639
t.test(Age~Survived,data = titanic_men)
## 
##  Welch Two Sample t-test
## 
## data:  Age by Survived
## t = 2.4821, df = 141.94, p-value = 0.01423
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  0.8096098 7.1444575
## sample estimates:
## mean in group 0 mean in group 1 
##        31.16667        27.18963

Проинтерпретируйте результаты.

Логистическая регрессия

А теперь давайте попробуем построить модель логистической регрессии, которая будет нам предсказывать выжили пассажиры или нет и передадим в нее в качестве переменных Sex, FamilySize, Pclass, Child.

titanic_log <- glm(formula = Survived ~ Sex + FamilySize + Pclass + Child, family = binomial, data = titanic_train)
summary(titanic_log)
## 
## Call:
## glm(formula = Survived ~ Sex + FamilySize + Pclass + Child, family = binomial, 
##     data = titanic_train)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.1884  -0.6675  -0.4220   0.6151   2.3426  
## 
## Coefficients:
##                 Estimate Std. Error z value             Pr(>|z|)    
## (Intercept)      3.50194    0.34859  10.046 < 0.0000000000000002 ***
## Sexmale         -2.91911    0.20824 -14.018 < 0.0000000000000002 ***
## FamilySizeBig   -2.82588    0.49446  -5.715        0.00000001097 ***
## FamilySizeSmall  0.03802    0.20693   0.184                0.854    
## Pclass          -0.98549    0.11431  -8.621 < 0.0000000000000002 ***
## Child            2.52222    0.43404   5.811        0.00000000621 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1186.66  on 890  degrees of freedom
## Residual deviance:  755.15  on 885  degrees of freedom
## AIC: 767.15
## 
## Number of Fisher Scoring iterations: 5

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

Проинтерпретируйте результаы.