Analiza danych Titanic
Baza danych Titanic
W momencie wodowania “Titanic” był największym pasażerskim statkiem parowym na świecie. W swój dziewiczy rejs wypłynął z portu w Southampton 10 kwietnia 1912 roku do Nowego Jorku. W nocy z 14 na 15 kwietnia zderzył się z górą lodową. Zatonął w ciągu niespełna trzech godzin. Katastrofa “Titanica” była największą katastrofą morską w czasach pokoju. Spośród ponad 2,2 tys. pasażerów i członków załogi życie straciło ponad 1,5 tys. osób.
Pracujemy na danych pt. “Titanic Passenger Survival Data Set” z pakietu titanic w R, korzystamy zarówno z danych titanic_train jak i titanic_test. Na ich podstawie analizujemy które czynniki mają wpływ na przeżycie tej katastrofy. Więcej szczegółów o tej bazie danych można znaleźć https://github.com/cran/titanic.
#install.packages("titanic")
library(titanic)
library(dplyr)
library(ggplot2)
library(zoo)
library(reshape2)
#install.packages("PerformanceAnalytics")
library("PerformanceAnalytics")
library(tidyverse)
library(extrafont)
library(extrafontdb)
Dane wejsciowe
Podstawowe informacje o danych w titanic_train
summary(titanic_train) #podstawowe statystyki
## PassengerId Survived Pclass Name
## Min. : 1.0 Min. :0.0000 Min. :1.000 Length:891
## 1st Qu.:223.5 1st Qu.:0.0000 1st Qu.:2.000 Class :character
## Median :446.0 Median :0.0000 Median :3.000 Mode :character
## Mean :446.0 Mean :0.3838 Mean :2.309
## 3rd Qu.:668.5 3rd Qu.:1.0000 3rd Qu.:3.000
## Max. :891.0 Max. :1.0000 Max. :3.000
##
## Sex Age SibSp Parch
## Length:891 Min. : 0.42 Min. :0.000 Min. :0.0000
## Class :character 1st Qu.:20.12 1st Qu.:0.000 1st Qu.:0.0000
## Mode :character Median :28.00 Median :0.000 Median :0.0000
## Mean :29.70 Mean :0.523 Mean :0.3816
## 3rd Qu.:38.00 3rd Qu.:1.000 3rd Qu.:0.0000
## Max. :80.00 Max. :8.000 Max. :6.0000
## NA's :177
## Ticket Fare Cabin Embarked
## Length:891 Min. : 0.00 Length:891 Length:891
## Class :character 1st Qu.: 7.91 Class :character Class :character
## Mode :character Median : 14.45 Mode :character Mode :character
## Mean : 32.20
## 3rd Qu.: 31.00
## Max. :512.33
##
names(titanic_train) #nazwy zmiennych
## [1] "PassengerId" "Survived" "Pclass" "Name" "Sex"
## [6] "Age" "SibSp" "Parch" "Ticket" "Fare"
## [11] "Cabin" "Embarked"
dim(titanic_train) #wymiar ramki danych
## [1] 891 12
::kable(head(titanic_train)) knitr
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.2500 | S | |
2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | |
4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1000 | C123 | S |
5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.0500 | S | |
6 | 0 | 3 | Moran, Mr. James | male | NA | 0 | 0 | 330877 | 8.4583 | Q |
Podstawowe informacje o danych w titanic_test
summary(titanic_test) #podstawowe statystyki
## PassengerId Pclass Name Sex
## Min. : 892.0 Min. :1.000 Length:418 Length:418
## 1st Qu.: 996.2 1st Qu.:1.000 Class :character Class :character
## Median :1100.5 Median :3.000 Mode :character Mode :character
## Mean :1100.5 Mean :2.266
## 3rd Qu.:1204.8 3rd Qu.:3.000
## Max. :1309.0 Max. :3.000
##
## Age SibSp Parch Ticket
## Min. : 0.17 Min. :0.0000 Min. :0.0000 Length:418
## 1st Qu.:21.00 1st Qu.:0.0000 1st Qu.:0.0000 Class :character
## Median :27.00 Median :0.0000 Median :0.0000 Mode :character
## Mean :30.27 Mean :0.4474 Mean :0.3923
## 3rd Qu.:39.00 3rd Qu.:1.0000 3rd Qu.:0.0000
## Max. :76.00 Max. :8.0000 Max. :9.0000
## NA's :86
## Fare Cabin Embarked
## Min. : 0.000 Length:418 Length:418
## 1st Qu.: 7.896 Class :character Class :character
## Median : 14.454 Mode :character Mode :character
## Mean : 35.627
## 3rd Qu.: 31.500
## Max. :512.329
## NA's :1
names(titanic_test) #nazwy zmiennych
## [1] "PassengerId" "Pclass" "Name" "Sex" "Age"
## [6] "SibSp" "Parch" "Ticket" "Fare" "Cabin"
## [11] "Embarked"
dim(titanic_test) #wymiar ramki danych
## [1] 418 11
::kable(head(titanic_test)) knitr
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
---|---|---|---|---|---|---|---|---|---|---|
892 | 3 | Kelly, Mr. James | male | 34.5 | 0 | 0 | 330911 | 7.8292 | Q | |
893 | 3 | Wilkes, Mrs. James (Ellen Needs) | female | 47.0 | 1 | 0 | 363272 | 7.0000 | S | |
894 | 2 | Myles, Mr. Thomas Francis | male | 62.0 | 0 | 0 | 240276 | 9.6875 | Q | |
895 | 3 | Wirz, Mr. Albert | male | 27.0 | 0 | 0 | 315154 | 8.6625 | S | |
896 | 3 | Hirvonen, Mrs. Alexander (Helga E Lindqvist) | female | 22.0 | 1 | 1 | 3101298 | 12.2875 | S | |
897 | 3 | Svensson, Mr. Johan Cervin | male | 14.0 | 0 | 0 | 7538 | 9.2250 | S |
Dane titanic_train zawieracją 891 obserwacji o pasażerach o numerach identyfikacyjnych od 1 do 891, natomiast titanic_test zawierają 418 obserwacji o pasażerach o numerach identyfikacyjnych od 892 do 1309. Ponadto dane treningowe zawierają dodatkowo zmienną Survived. W dalszej analizie połączymy dane testowe z treningowymi w jedną całość. Najpierw musimy dodać kolumnę Survived do danych testowych, natępnie (jak już obie tabele mają tą samą liczbę zmiennych) możemy połączyć dane testowe i treningowe w jedną ramkę danych titanic_calosc.
$Survived <- NA # test$Survived dodajemy pustą informację
titanic_test<- rbind(titanic_train, titanic_test) titanic_calosc
Oto kilka pierwszych wierszy tabeli titanic_calosc
::kable(head(titanic_calosc)) knitr
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.2500 | S | |
2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | |
4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1000 | C123 | S |
5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.0500 | S | |
6 | 0 | 3 | Moran, Mr. James | male | NA | 0 | 0 | 330877 | 8.4583 | Q |
Przy czym poszczególne zmienne mają następujące znaczenie:
nazwa | opis |
---|---|
PassengerId | Numer identyfikacyjny pasażera |
Survived | Czy dana osoba przeżyła czy nie. Oznaczenia: 0-nie przeżyła, 1-przeżyła |
Pclass | Klasa socjalno-ekonomiczna. Oznaczenia: 1-Wyższa, 2-Średnia, 3-Niższa |
Name | Imiona i nazwiska oddzielone przecinkami w formacie: nazwisko, tytuł imię |
Sex | Płeć. Oznaczenia: male - mężczyzna, female -kobieta |
Age | Wiek |
SibSp | Liczba rodzeństwa lub małżonków na pokładzie |
Parch | Liczba rodziców lub dzieci na pokładzie |
Ticket | Numer biletu |
Fare | Opłata za bilet |
Cabin | Numer kabiny |
Embarked | Port źródłowy. Oznaczenia: C -Cherbourk, Q - Quenstown, S - Southampton |
Kolejno wyświetlamy podstawowe informacje o danych, jak nazwa, typ i przykłady wartości:
str(titanic_calosc)
## 'data.frame': 1309 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" ...
oraz podstawowe statystyki
summary(titanic_calosc)
## PassengerId Survived Pclass Name
## Min. : 1 Min. :0.0000 Min. :1.000 Length:1309
## 1st Qu.: 328 1st Qu.:0.0000 1st Qu.:2.000 Class :character
## Median : 655 Median :0.0000 Median :3.000 Mode :character
## Mean : 655 Mean :0.3838 Mean :2.295
## 3rd Qu.: 982 3rd Qu.:1.0000 3rd Qu.:3.000
## Max. :1309 Max. :1.0000 Max. :3.000
## NA's :418
## Sex Age SibSp Parch
## Length:1309 Min. : 0.17 Min. :0.0000 Min. :0.000
## Class :character 1st Qu.:21.00 1st Qu.:0.0000 1st Qu.:0.000
## Mode :character Median :28.00 Median :0.0000 Median :0.000
## Mean :29.88 Mean :0.4989 Mean :0.385
## 3rd Qu.:39.00 3rd Qu.:1.0000 3rd Qu.:0.000
## Max. :80.00 Max. :8.0000 Max. :9.000
## NA's :263
## Ticket Fare Cabin Embarked
## Length:1309 Min. : 0.000 Length:1309 Length:1309
## Class :character 1st Qu.: 7.896 Class :character Class :character
## Mode :character Median : 14.454 Mode :character Mode :character
## Mean : 33.295
## 3rd Qu.: 31.275
## Max. :512.329
## NA's :1
Kategoryzacja danych
Część danych jest w postaci tekstowej i trzeba je skategoryzować. W tym celu dodajemy nowe pola w naszej tabeli: Sex2 i Embarked2:
$Sex2 <- as.numeric(as.factor(titanic_calosc$Sex))
titanic_calosc$Embarked2 <- as.numeric(as.factor(titanic_calosc$Embarked)) titanic_calosc
Oto kilka pierwszych wierszy nowej tabeli titanic_calosc
::kable(head(titanic_calosc)) knitr
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Sex2 | Embarked2 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.2500 | S | 2 | 4 | |
2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 1 | 2 |
3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | 1 | 4 | |
4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1000 | C123 | S | 1 | 4 |
5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.0500 | S | 2 | 4 | |
6 | 0 | 3 | Moran, Mr. James | male | NA | 0 | 0 | 330877 | 8.4583 | Q | 2 | 3 |
Widzimy, że mamy następujące dane w nowych kolumnach
Embarked | Embarked2 |
---|---|
S | 3 |
Q | 2 |
C | 1 |
Analiza brakujących danych
Wyświetlimy teraz informacje, które pole zawiera brakujące dane NA i ile jest tych braków:
%>%
titanic_calosc select(everything()) %>%
summarise_all(funs(sum(is.na(.))))
## PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin
## 1 0 418 0 0 0 263 0 0 0 1 0
## Embarked Sex2 Embarked2
## 1 0 0 0
Widzimy, że pole Survived zawiera 418 braków danych, Age - 263 braki danych, a Fare - 1 brak danych. Ponadto jeśli pogrupujemy naszą tabelę po zmiennej Embarked, to zauważymy, że występują tu też dwa braki danych:
%>%
titanic_calosc group_by(Embarked)%>%
summarise(cnt = n()) %>%
arrange(desc(cnt))
## # A tibble: 4 x 2
## Embarked cnt
## <chr> <int>
## 1 "S" 914
## 2 "C" 270
## 3 "Q" 123
## 4 "" 2
%>%
titanic_calosc filter( is.na(Embarked) )
## [1] PassengerId Survived Pclass Name Sex Age
## [7] SibSp Parch Ticket Fare Cabin Embarked
## [13] Sex2 Embarked2
## <0 wierszy> (lub 'row.names' o zerowej długości)
%>%
titanic_calosc filter( Embarked=="" )
## PassengerId Survived Pclass Name Sex
## 1 62 1 1 Icard, Miss. Amelie female
## 2 830 1 1 Stone, Mrs. George Nelson (Martha Evelyn) female
## Age SibSp Parch Ticket Fare Cabin Embarked Sex2 Embarked2
## 1 38 0 0 113572 80 B28 1 1
## 2 62 0 0 113572 80 B28 1 1
Zastępujemy najpierw “” w polu Embarked przez NA
<- titanic_calosc %>% mutate(Embarked = ifelse( Embarked=="",NA, Embarked) )
titanic_calosc #inny sposób mutate_all(na_if,"")
%>%
titanic_calosc filter( is.na(Embarked) )
## PassengerId Survived Pclass Name Sex
## 1 62 1 1 Icard, Miss. Amelie female
## 2 830 1 1 Stone, Mrs. George Nelson (Martha Evelyn) female
## Age SibSp Parch Ticket Fare Cabin Embarked Sex2 Embarked2
## 1 38 0 0 113572 80 B28 <NA> 1 1
## 2 62 0 0 113572 80 B28 <NA> 1 1
Wówczas nasze zestawienie brakujących wartości wygląda następujaco
%>%
titanic_calosc select(everything()) %>%
summarise_all(funs(sum(is.na(.))))
## PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin
## 1 0 418 0 0 0 263 0 0 0 1 0
## Embarked Sex2 Embarked2
## 1 2 0 0
W kwestii Cabin
%>%
titanic_calosc filter( Cabin=="" )%>%
summarise(cnt = n())
## cnt
## 1 1014
mamy aż 1014 braków danych na 1309 obserwacji. W związku z tym postanowiłyśmy pominąć pole Cabin w naszych analizach.
= titanic_calosc %>% select(-Cabin) titanic_calosc
W związku z tym w dalszej części zajmiemy się usuwaniem braków danych dla zmiennych Age, Fare i Embarked.
Wypełnianie braków danych w Embarked
Pole Embarked ma tylko dwa braki danych. Wynika z tego, że można Embarked wypełnić wartościami z wierwszy o zbliżonych wartościach. Najpierw sprawdzimy od czego ona najbardziej zależy Embarked.
<- c('Age','Sex2', 'Embarked2','Fare', 'Parch' , 'Pclass', 'SibSp')
cols abs(cor(titanic_calosc[,cols],use="complete.obs")[,"Embarked2"]) %>% .[order(., decreasing = TRUE)]
## Embarked2 Fare Pclass Sex2 Age SibSp Parch
## 1.00000000 0.30310839 0.28198941 0.11599775 0.09064651 0.04836727 0.01411680
Badając korelację zmiennej Embarked z pozostałymi zmiennymi, widzimy, że zależy ona najbardziej o zmiennych: Fare, Pclass i Sex2. A zatem potrzebujemy dla cClass, Sex2 obliczyć Fare i zobaczyć który Embarked jest najbliżej. Najpierw wyświetlmy dane tych pasazerów, u których są braki danych w Embarked:
::kable(titanic_calosc %>%
knitrfilter( is.na(Embarked) ))
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Sex2 | Embarked2 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
62 | 1 | 1 | Icard, Miss. Amelie | female | 38 | 0 | 0 | 113572 | 80 | NA | 1 | 1 |
830 | 1 | 1 | Stone, Mrs. George Nelson (Martha Evelyn) | female | 62 | 0 | 0 | 113572 | 80 | NA | 1 | 1 |
Widzimy, że są to kobiety podróżujace pierwszą klasą, a ich opłata wynosi 80. Wówczas wybieramy dane, które właśnie spełniają te warunki.
%>%
titanic_calosc filter(Pclass == 1 & Sex2 == 1 ) %>%
group_by(Embarked) %>%
summarise( sum = sum(Fare), count = n(), mean = mean(Fare), median = median(Fare))
## # A tibble: 4 x 5
## Embarked sum count mean median
## <chr> <dbl> <int> <dbl> <dbl>
## 1 C 8442. 71 119. 83.2
## 2 Q 180 2 90 90
## 3 S 6974. 69 101. 78.8
## 4 <NA> 160 2 80 80
Najbliżej 80 jest mediana z portu źródłowego Southampton. Możemy to jeszcze ilustrować na wykresie, gdzie czerwoną linią jest zaznaczony poziom Fare=80.
ggplot(data=titanic_calosc %>%filter(Pclass == 1 & Sex2 == 1 & Embarked %in% c('C','S', 'Q') ), aes(Embarked, Fare, group = Embarked)) +
geom_boxplot() + geom_hline(yintercept=80,color='red')
Wynika stąd, że brakujące wrtości w polu Embarked można zastąpić wartością S.
62,'Embarked'] = 'S'
titanic_calosc[830,'Embarked'] = 'S'
titanic_calosc[$Embarked2 <- as.numeric(as.factor(titanic_calosc$Embarked))
titanic_caloscstr(titanic_calosc)
## 'data.frame': 1309 obs. of 13 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 ...
## $ Embarked : chr "S" "C" "S" "S" ...
## $ Sex2 : num 2 1 1 1 2 2 2 2 1 1 ...
## $ Embarked2 : num 3 1 3 3 3 2 3 3 3 1 ...
Wypełnianie braków danych w Age
W przypadku zmiennej Age uzupełniamy braki danych wartością średnią zmiennej Age:
$Age[is.na(titanic_calosc$Age)] <- mean(titanic_calosc$Age,na.rm=T) titanic_calosc
Wypełnianie braków danych w Fare
Zaczynamy od wyświetlenia tej obserwacji, gdzie Fare jest NA i od sprawdzenia z czym zmienna Fare jest nabardziej skorelowana:
::kable(titanic_calosc %>%
knitrfilter( is.na(Fare) ))
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Sex2 | Embarked2 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1044 | NA | 3 | Storey, Mr. Thomas | male | 60.5 | 0 | 0 | 3701 | NA | S | 2 | 3 |
<- c('Age','Sex2', 'Embarked2','Fare', 'Parch' , 'Pclass', 'SibSp')
cols abs(cor(titanic_calosc[,cols],use="complete.obs")[,"Fare"]) %>% .[order(., decreasing = TRUE)]
## Fare Pclass Embarked2 Parch Sex2 Age SibSp
## 1.0000000 0.5586287 0.2380054 0.2215387 0.1855230 0.1718929 0.1602383
Widzimy, że zmienna Fare jest skorelowana z Pclass, Embarked2, Parch Sex2 i Age. A zatem biorąc pod uwagę, że nasz pasażer, dla którego mamy brak opłaty, podróżuje klasą 3, wyruszył z portu w Southampton, jest mężczyzną i ma 60,5 roku. A zatem szukamy pasujących danych:
%>%
titanic_calosc filter(Pclass == 3 & Embarked2 == 3 & Parch == 0 & Sex2 ==2 & Age > 50) %>%
group_by(Age) %>%
summarise( sum = sum(Fare), count = n(), mean = mean(Fare), median = median(Fare))
## # A tibble: 6 x 5
## Age sum count mean median
## <dbl> <dbl> <int> <dbl> <dbl>
## 1 51 22.9 3 7.62 7.75
## 2 55.5 8.05 1 8.05 8.05
## 3 59 7.25 1 7.25 7.25
## 4 60.5 NA 1 NA NA
## 5 61 6.24 1 6.24 6.24
## 6 74 7.78 1 7.78 7.78
Można przypuszczać że osoby w tym wieku średnio płaciły między 6.24 a 7.25 funtów. Możemy w takim razie przyjąć średnią z tych dwóch wartości. Różnica między 6.24 a 7.25 jest zbyt mała, aby mieć istotny wpływ w porównaniu do całego obszaru cen (od 0 do 512, gdzie średnia to 33 a mediana to 14).
1044,'Fare'] = (7.25 + 6.24)/2 titanic_calosc[
Ostatecznies nasze zestawienie brakujących wartości wygląda następujaco
%>%
titanic_calosc select(everything()) %>%
summarise_all(funs(sum(is.na(.))))
## PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Embarked
## 1 0 418 0 0 0 0 0 0 0 0 0
## Sex2 Embarked2
## 1 0 0
W kwestii Survived braki danych pozostają, posłużą nam one w przyszłości do podziału danych na dane testowe i treningowe.
Podstawowe wykresy
Ile osób przeżyło (1), a ile nie przeżyło (0):
table(titanic_calosc$Survived)
##
## 0 1
## 549 342
%>%
titanic_calosc ggplot(aes(x = factor(!is.na(Survived))))+
geom_bar(width = 0.4) +
scale_x_discrete(labels=c("przeżyli", "zginęli"))+
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold")
+
) labs(title = "Ogólne wskaźniki przeżycia", x = NULL, y = "Liczba pasazerów")
Na podstawie wykresu widać, że szanse na przeżycie były małe.
Ile jest kobiet, a ile mężczyzn:
table(titanic_calosc$Sex)
##
## female male
## 466 843
%>%
titanic_calosc ggplot(aes(x = Sex)) +
geom_bar(width = 0.4) +
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold")
+
) labs(title = "Podział ze względu na płeć", x = NULL, y = "Liczba pasażerów")
### Ile osób wsiadło w każdym porcie
table(titanic_calosc$Embarked)
##
## C Q S
## 270 123 916
%>%
titanic_calosc ggplot(aes(x = Embarked)) +
geom_bar(width = 0.4) +
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold")
+
) labs(title = "Podział ze względu na port źródłowy", x = NULL, y = "Liczba pasażerów")
### Ile osób podróżowało samych, a ile z rodziną:
table(titanic_calosc$SibSp)
##
## 0 1 2 3 4 5 8
## 891 319 42 20 22 6 9
%>%
titanic_calosc ggplot(aes(x = SibSp)) +
geom_bar(width = 0.4) +
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold")
+
) labs(title = "Podział ze względu na posiadanie rodzeńswta/współmałżonka", x = NULL, y = "Liczba pasazerów")
table(titanic_calosc$Parch)
##
## 0 1 2 3 4 5 6 9
## 1002 170 113 8 6 6 2 2
%>%
titanic_calosc ggplot(aes(x = Parch)) +
geom_bar(width = 0.4) +
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold")
+
) labs(title = "Podział ze względu na posiadanie dzieci/rodziców", x = NULL, y = "Liczba pasazerów")
Ile osób było w każdej klasie
table(titanic_calosc$Pclass)
##
## 1 2 3
## 323 277 709
%>%
titanic_calosc ggplot(aes(x = Pclass)) +
geom_bar(width = 0.4) +
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold")
+
) labs(title = "Podział ze względu na klasę podróży", x = NULL, y = "Liczba pasazerów")
Najwięcej osób podróżowało w 3 klasie.
ggplot(data = titanic_calosc, aes(Pclass, Age, group = Pclass)) + geom_boxplot()+
labs(title = "Podział ze względu na klasę podróży", x = "Klasy", y = "Wiek pasażerów")
Osoby z 3 klasy są najmłodsze i rozrzut jest najmniejszy ze wszystkich. 50% osób w pierwszej klasie znajduje się między 30 a 50 rokiem życia
Histogram zmiennej Age
ggplot(data=titanic_calosc, aes(titanic_calosc$Age)) + geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(data=titanic_calosc, aes(x=Age)) +
geom_histogram(binwidth = 2.5, alpha = 0.2) +
geom_histogram(data = subset(titanic_calosc,Survived == 1), fill = "blue", alpha = 0.2) +
geom_density(aes(y=2.5 * ..count..),color="red",na.rm = T) +
geom_density(data = subset(titanic_calosc,Survived == 1), aes(y=2.5 * ..count..),color="blue",na.rm = T)+
labs(title = "Histogram zmiennej Age", x = "Wiek", y = "Ilość osób")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Analiza przeżycia - związek zmiennej Survived z pozostałymi
Zwizualizujmy, jak wskaźniki przeżycia różniły się w zależności od płci.
Czy przeżyło więcej mężczyzn czy kobiet?
table(titanic_calosc$Sex)
##
## female male
## 466 843
%>%
titanic_calosc ggplot(aes(x = Sex, fill = factor(!is.na(Survived)))) +
geom_bar(width = 0.4) +
scale_x_discrete(labels=c("Kobiety", "Mężczyźni"))+
scale_fill_discrete(labels=c("zginęli","przeżyli"))+
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold"),
legend.title = element_blank(),
legend.text = element_text(family = "Times New Roman")
+
) labs(title = "Współczynnik przeżycia wg płci", x = NULL, y = "Liczba pasażerów")
W oparciu o powyższy wykres, kobiety miały większe szanse na przeżycie.
Sprawdźmy zależność przeżycia w odniesieniu do wieku
%>%
titanic_calosc ggplot(aes(x = Age, fill = factor(!is.na(Survived)))) +
geom_histogram() +
scale_fill_discrete(labels=c("zginęli","przeżyli"))+
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold"),
legend.title = element_blank(),
legend.text = element_text(family = "Times New Roman")
+
) labs(title = "Zależność pomiędzy wiekiem a przeżywalnością ", x="Wiek", y= "Ilość osób")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
%>%
titanic_calosc ggplot(aes(x = Survived, y = Age)) +
geom_boxplot() +
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman", face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold"),
legend.title = element_blank(),
legend.text = element_text(family = "Times New Roman")
+
) labs(title = "Wskaźniki przeżywalności według wieku", x = NULL)
Dzieci poniżej 5 lat miały większe szanse na przeżycie. Pasażerowie w wieku 20-40 lat byli bardziej narażeni na śmierć. Pasażerowie w wieku około 65 - 75 lat mieli prawie zerowe szanse na przeżycie. Przeżył jeden pasażer w wieku 80 lat. Pasażerowie, którzy przeżyli wydają się mieć niższą medianę wieku.
###Sprawdźmy współczynnik przeżycia według klasy pasażerskiej.
%>%
titanic_calosc ggplot(aes(x = Pclass, fill = factor(!is.na(Survived)))) +
geom_bar(width = 0.4) +
scale_fill_discrete(labels=c("zginęli","przeżyli"))+
theme_classic() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman",face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold"),
legend.title = element_blank(),
legend.text = element_text(family = "Times New Roman")
+
) labs(title = "Współczynnik przeżycia według klasy pasażerskiej [1-Wyższa, 2-Średnia, 3-Niższa]", x = NULL, y = "Liczba pasażerów")
Przeżyło najwiecej osób, którzy kupili bilet w klasie pierwszej.
Zbadamy, jak różne zmienne oddziaływały na siebie i na wskaźnik przeżycia.
%>%
titanic_calosc ggplot(aes(x = Sex, fill = factor(!is.na(Survived)))) +
geom_bar(width = 0.4) +
scale_fill_discrete(labels=c("zginęli","przeżyli"))+
facet_wrap(~ Pclass) +
theme_test() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman", face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold"),
legend.title = element_blank(),
legend.text = element_text(family = "Times New Roman")
+
) labs(title = "Wskaźniki przeżywalności wg płci i klasy pasażerskiej", x = NULL, y = "Liczba pasażerów")
Kobiety w 1, 2 i 3 klasie miały odpowiednio 90%, 90% i 50% szans na przeżycie w porównaniu do mężczyzn.
%>%
titanic_calosc ggplot(aes(x = Age, fill = factor(!is.na(Survived)))) +
geom_histogram() +
scale_fill_discrete(labels=c("zginęli","przeżyli"))+
facet_wrap(~Sex + Pclass) +
theme_test() +
theme(
plot.title = element_text(family = "Times New Roman", hjust = 0.5),
axis.text = element_text(family = "Times New Roman", face = "bold"),
axis.title = element_text(family = "Times New Roman", face = "bold"),
legend.title = element_blank(),
legend.text = element_text(family = "Times New Roman")
+
) labs(title = "Wskaźniki przeżywalności wg wieku, płci i klasy pasażerskiej", x = NULL, y = "Liczba pasażerów")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
W danych dotyczących Titanica, wiek, płeć i klasa pasażerów były ważnymi czynnikami predykcyjnymi przeżycia. Najwięcej umarło mężczyzn w 3 klasie w wieku między 18 a 50 rokiem życia.
Spojrzymy jeszcze na korelacje między zmiennymi
<- c('Age','Sex2','Embarked2','Fare','Parch','Pclass','SibSp','Survived')
cols <- cor( titanic_calosc[,cols], use="complete.obs")
corr
heatmap(corr,
na.rm = T, # same data set for cell labels
)
###Bardziej zaawansowany heatmap oferuje ggplot, trzeba tylko wynik korelacji (który jest typu matrix) zamienić na data.frame. Można to zrobić przez funkcje melt
<- melt(corr, na.rm = TRUE)
corr_df
ggplot(corr_df, aes(x=Var1,y=Var2, fill=value)) +
geom_tile() +
geom_text(aes(Var2, Var1, label = round(value,2)), color = "white", size = 4)
###Sprawdzimy od czego Survived najbardziej zależy.
<- c('Age','Sex2', 'Embarked2','Fare', 'Parch' , 'Pclass', 'SibSp', 'Survived')
cols ::kable(abs(cor(titanic_calosc[,cols],use="complete.obs")[,"Survived"]) %>% .[order(., decreasing = TRUE)]) knitr
x | |
---|---|
Survived | 1.0000000 |
Sex2 | 0.5433514 |
Pclass | 0.3384810 |
Fare | 0.2573065 |
Embarked2 | 0.1676753 |
Parch | 0.0816294 |
Age | 0.0703227 |
SibSp | 0.0353225 |
Tak jak w analizie powyżej szansa przeżycia zależała przede wszytskim od płci, klasy i ceny biletu.
Ciekawym wykresem jest Performance Analytics. Pozwala na jedynm wykresie pokazać histogram, zależności między zmiennymi i jak zmieniają się dane w zależności od zmiennych.
<- c('Age','Sex2', 'Embarked2','Fare', 'Parch' , 'Pclass', 'SibSp', 'Survived')
cols
library("PerformanceAnalytics")
chart.Correlation(titanic_calosc[,cols], histogram=TRUE, pch=19, font.size = 15)
Po przekątnej mamy histogram, po lewej na dole wykresy punktowe i szacowany wykres zależności między punktami. Np: wiersz Survived z kolumną Age widzimy, że wraz ze wzrostem wieku przeżywalność spada, odwrotnie jak w przypadku opłaty za bilet Fare, wraz ze wzrostem przeżywalność rośnie.