Resumen

1.- El siguiente Análisis, comprende en la revisión de un set de datos llamado Titanic, el cual se encuentra en la siguiente URL: https://www.kaggle.com/pilotgod/titanic-truth-data?select=titanic3.csv

2.- Primero realizaremos un análisis exploratorio de los datos, revisaremos los tipos de variables, cantidad de datos, distribución, etc.

3.- Uno de los objetivos es realizar un árbol de de clasificación

4.- La variable target o a analizar es la sobrevida, y debe ser tipo factor

5.- Construcción de 1 árbol que muestre el análisis de la variable sobrevida versus el resto de las variables

6.- Construcción de un árbol 2, se debe analizar la variable target de sobrevida versus la variable de mayor incidencia.

Análisis Exploratorio

Comenzamos realizando un análisis de los datos, ésto nos pemrite conocer la estructura, comprender en un primero acercamiento a que nos enfrentamos.

Establecemos Ruta de trabajo del Proyecto, cargamos librerías y llamamos al archivo de datos Titanic

#getwd()
#setwd("C:/Users/Meuch/OneDrive - informática Zenweb Ltda/Análitica de Negocios/TitanicCompleto") #Establezco Ruta de Trabajo
getwd() #Obtengo nuevamente la Ruta
## [1] "/Users/psandoval/OneDrive - informática Zenweb Ltda/Análitica de Negocios/analiticaTitanic"
# Instalación de los paquetes que unifica caret. Esta instalación puede tardar.
# Solo es necesario ejecutarla si no se dispone de los paquetes.
#install.packages("caret", dependencies = c("Depends", "Suggests"))

library(readr) #Librería para leer archivos
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(titanic)
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.3     ✓ purrr   0.3.4
## ✓ tibble  3.1.2     ✓ stringr 1.4.0
## ✓ tidyr   1.1.3     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(rmarkdown)
library(rsconnect)
#library(caret)
datosMuestra <- read.csv("titanic3.csv") # Cargamos archivo de datos Titanic y la almacenamos en variable
str(datosMuestra) # Se utiliza para mostrar la estructura de datos del dataset
## 'data.frame':    1310 obs. of  14 variables:
##  $ pclass   : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ survived : int  1 1 0 0 0 1 1 0 1 0 ...
##  $ name     : chr  "Allen, Miss. Elisabeth Walton" "Allison, Master. Hudson Trevor" "Allison, Miss. Helen Loraine" "Allison, Mr. Hudson Joshua Creighton" ...
##  $ sex      : chr  "female" "male" "female" "male" ...
##  $ age      : num  29 0.917 2 30 25 ...
##  $ sibsp    : int  0 1 1 1 1 0 1 0 2 0 ...
##  $ parch    : int  0 2 2 2 2 0 0 0 0 0 ...
##  $ ticket   : chr  "24160" "113781" "113781" "113781" ...
##  $ fare     : num  211 152 152 152 152 ...
##  $ cabin    : chr  "B5" "C22 C26" "C22 C26" "C22 C26" ...
##  $ embarked : chr  "S" "S" "S" "S" ...
##  $ boat     : chr  "2" "11" "" "" ...
##  $ body     : int  NA NA NA 135 NA NA NA NA NA 22 ...
##  $ home.dest: chr  "St Louis, MO" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" ...

Tipos de datos en el dataset

Pclass: Clase a la que pertenecía el pasajero: 1, 2 o 3.

Survived: Si el pasajero sobrevivió al naufragio, codificada como 0 (no) y 1 (si). Esta es la variable respuesta que interesa predecir.

Name: Nombre del pasajero.

Sex: Sexo del pasajero.

Age: Edad del pasajero.

SibSp: Número de hermanos, hermanas, hermanastros o hermanastras en el barco.

Parch: Número de padres e hijos en el barco.

Ticket: Identificador del billete.

Fare: Precio pagado por el billete.

Cabin: Identificador del camarote asignado al pasajero.

Embarked: Puerto en el que embarcó el pasajero.

Boat: Identificador del Bote salvavidas

Body: Se refiere a la identificación de un número de cuerpo si es que fue encontrado

Home.dest: Identifica ciudad de origen y ciudad de destino

Tipos de Variables

Verificamos los tipos de variables, tipos de valor, verificamos que las variables numeros sean números, factores, etc.

glimpse(datosMuestra) #Se utiliza para mostrar la estructura de datos del dataset, similar a str.
## Rows: 1,310
## Columns: 14
## $ pclass    <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ survived  <int> 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, …
## $ name      <chr> "Allen, Miss. Elisabeth Walton", "Allison, Master. Hudson Tr…
## $ sex       <chr> "female", "male", "female", "male", "female", "male", "femal…
## $ age       <dbl> 29.0000, 0.9167, 2.0000, 30.0000, 25.0000, 48.0000, 63.0000,…
## $ sibsp     <int> 0, 1, 1, 1, 1, 0, 1, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ parch     <int> 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, …
## $ ticket    <chr> "24160", "113781", "113781", "113781", "113781", "19952", "1…
## $ fare      <dbl> 211.3375, 151.5500, 151.5500, 151.5500, 151.5500, 26.5500, 7…
## $ cabin     <chr> "B5", "C22 C26", "C22 C26", "C22 C26", "C22 C26", "E12", "D7…
## $ embarked  <chr> "S", "S", "S", "S", "S", "S", "S", "S", "S", "C", "C", "C", …
## $ boat      <chr> "2", "11", "", "", "", "3", "10", "", "D", "", "", "4", "9",…
## $ body      <int> NA, NA, NA, 135, NA, NA, NA, NA, NA, 22, 124, NA, NA, NA, NA…
## $ home.dest <chr> "St Louis, MO", "Montreal, PQ / Chesterville, ON", "Montreal…

Transformación de Datos

Detectamos que la variable que debemos comprobar, la variable target de sobrevida, se encuentra almacenada en valores 1 y 0, 1 si la persona sobrevivió y 0 si murió. Procedemos a cambiar ésta variable a valor Si o No según corresponda.

datosMuestra$survived <- if_else(datosMuestra$survived == 1, "Si", "No")
datosMuestra$survived <- as.factor(datosMuestra$survived)
glimpse(datosMuestra)
## Rows: 1,310
## Columns: 14
## $ pclass    <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ survived  <fct> Si, Si, No, No, No, Si, Si, No, Si, No, No, Si, Si, Si, Si, …
## $ name      <chr> "Allen, Miss. Elisabeth Walton", "Allison, Master. Hudson Tr…
## $ sex       <chr> "female", "male", "female", "male", "female", "male", "femal…
## $ age       <dbl> 29.0000, 0.9167, 2.0000, 30.0000, 25.0000, 48.0000, 63.0000,…
## $ sibsp     <int> 0, 1, 1, 1, 1, 0, 1, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ parch     <int> 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, …
## $ ticket    <chr> "24160", "113781", "113781", "113781", "113781", "19952", "1…
## $ fare      <dbl> 211.3375, 151.5500, 151.5500, 151.5500, 151.5500, 26.5500, 7…
## $ cabin     <chr> "B5", "C22 C26", "C22 C26", "C22 C26", "C22 C26", "E12", "D7…
## $ embarked  <chr> "S", "S", "S", "S", "S", "S", "S", "S", "S", "C", "C", "C", …
## $ boat      <chr> "2", "11", "", "", "", "3", "10", "", "D", "", "", "4", "9",…
## $ body      <int> NA, NA, NA, 135, NA, NA, NA, NA, NA, 22, 124, NA, NA, NA, NA…
## $ home.dest <chr> "St Louis, MO", "Montreal, PQ / Chesterville, ON", "Montreal…
head(datosMuestra) # revisamos nueva estructura, mostrando sólo encabezado de registros
##   pclass survived                                            name    sex
## 1      1       Si                   Allen, Miss. Elisabeth Walton female
## 2      1       Si                  Allison, Master. Hudson Trevor   male
## 3      1       No                    Allison, Miss. Helen Loraine female
## 4      1       No            Allison, Mr. Hudson Joshua Creighton   male
## 5      1       No Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female
## 6      1       Si                             Anderson, Mr. Harry   male
##       age sibsp parch ticket     fare   cabin embarked boat body
## 1 29.0000     0     0  24160 211.3375      B5        S    2   NA
## 2  0.9167     1     2 113781 151.5500 C22 C26        S   11   NA
## 3  2.0000     1     2 113781 151.5500 C22 C26        S        NA
## 4 30.0000     1     2 113781 151.5500 C22 C26        S       135
## 5 25.0000     1     2 113781 151.5500 C22 C26        S        NA
## 6 48.0000     0     0  19952  26.5500     E12        S    3   NA
##                         home.dest
## 1                    St Louis, MO
## 2 Montreal, PQ / Chesterville, ON
## 3 Montreal, PQ / Chesterville, ON
## 4 Montreal, PQ / Chesterville, ON
## 5 Montreal, PQ / Chesterville, ON
## 6                    New York, NY

Algunas variables del set de datos se encuentran almacenadas como números enteros, por ejemplo las variables SibSp y Parch. En sí estas variables por definción explican que cantidad de hermanas o padres tenia cada pasajero, entendemos que para la finalidad del estudio no es relevante hacer un cambio.

La variable Sex es una variable a analizar en el caso de estudio, por ende la transformaremos a tipo factor.

datosMuestra$sex <- as.factor(datosMuestra$sex)

Comprobamos el número total de resgistros del dataset:

nrow(datosMuestra)
## [1] 1310

Comprobamos si existe alguna fila con datos incompletos:

any(!complete.cases(datosMuestra))
## [1] TRUE

realizamos la misma comprobación, pero ahora por columnas o variables:

map_dbl(datosMuestra, .f = function(x){sum(is.na(x))})
##    pclass  survived      name       sex       age     sibsp     parch    ticket 
##         1         1         0         0       264         1         1         0 
##      fare     cabin  embarked      boat      body home.dest 
##         2         0         0         0      1189         0

Según éste resultado, donde hemos buscado los valores NA por columna o variable, existe una variable que esta casi completamente vacía, la variable Body, en el dataset éste dato es muy vago, por ello se toam la decisión de no tomar en cuenta la variable o columna.

datosMuestra2 <- select(datosMuestra, -body)
head(datosMuestra2)
##   pclass survived                                            name    sex
## 1      1       Si                   Allen, Miss. Elisabeth Walton female
## 2      1       Si                  Allison, Master. Hudson Trevor   male
## 3      1       No                    Allison, Miss. Helen Loraine female
## 4      1       No            Allison, Mr. Hudson Joshua Creighton   male
## 5      1       No Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female
## 6      1       Si                             Anderson, Mr. Harry   male
##       age sibsp parch ticket     fare   cabin embarked boat
## 1 29.0000     0     0  24160 211.3375      B5        S    2
## 2  0.9167     1     2 113781 151.5500 C22 C26        S   11
## 3  2.0000     1     2 113781 151.5500 C22 C26        S     
## 4 30.0000     1     2 113781 151.5500 C22 C26        S     
## 5 25.0000     1     2 113781 151.5500 C22 C26        S     
## 6 48.0000     0     0  19952  26.5500     E12        S    3
##                         home.dest
## 1                    St Louis, MO
## 2 Montreal, PQ / Chesterville, ON
## 3 Montreal, PQ / Chesterville, ON
## 4 Montreal, PQ / Chesterville, ON
## 5 Montreal, PQ / Chesterville, ON
## 6                    New York, NY
map_dbl(datosMuestra2, .f = function(x){sum(is.na(x))})
##    pclass  survived      name       sex       age     sibsp     parch    ticket 
##         1         1         0         0       264         1         1         0 
##      fare     cabin  embarked      boat home.dest 
##         2         0         0         0         0
nrow(datosMuestra2) #Cuento numeros de filas
## [1] 1310
datosMuestra2 <- na.omit(datosMuestra2) # Borro registros NA sobrantes.
nrow(datosMuestra2) #Vuelvo a contar numeros de fila despues de eliminar sobrantes NA
## [1] 1045
map_dbl(datosMuestra2, .f = function(x){sum(is.na(x))})
##    pclass  survived      name       sex       age     sibsp     parch    ticket 
##         0         0         0         0         0         0         0         0 
##      fare     cabin  embarked      boat home.dest 
##         0         0         0         0         0

Hasta el momento tenemos todo el set de datos limpio, y ahora procederemos a analizar. para ver que tan dispersos se encuentran los datos realizaremos un ggplot, o gráfica interactiva donde nos muestra de la totalidad de pasajeros, quienes sobrevivieron y quienes no.

Interpretación de los datos

library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(ggpubr)
pl <- ggplot(data = datosMuestra2, aes(x = survived, y = ..count.., fill = survived)) +
  geom_bar() + 
  scale_fill_manual(values = c("blue", "orange")) + 
  labs(title = "Sobrevivencia") + theme_bw() + 
  theme(legend.position = "bottom")

plotazo <- ggplotly(pl)
plotazo

Resultado en tabla y procentaje variable sobrevida:

table(datosMuestra2$survived)
## 
##  No  Si 
## 618 427
prop.table(table(datosMuestra2$survived)) %>% round(digits = 2)
## 
##   No   Si 
## 0.59 0.41

La finalidad del caso de estudio es determinar quienes sobrevivieron, quienes no y porque, debemos empezar a observar con que variables se relaciona la variable sobrevida. Para ello realizaremos dos graficas ggplot comparando la variable sobrevida con edad.

p1 <- ggplot(data = datosMuestra2, aes(x = age, fill = survived)) + geom_density(alpha = 0.5) + scale_fill_manual(values = c("blue", "orange")) + geom_rug(aes(color = survived), alpha = 0.5) + scale_color_manual(values = c("blue", "orange")) + theme_bw()
p2 <- ggplot(data = datosMuestra2, aes(x = survived, y = age, color = survived)) +
      geom_boxplot(outlier.shape = NA) +
      geom_jitter(alpha = 0.3, width = 0.15) +
      scale_color_manual(values = c("blue", "orange")) +
      theme_bw()
final_plot <- ggarrange(p1, p2, legend = "top")
final_plot <- annotate_figure(final_plot, top = text_grob("Sobrevivencia / Edad", size = 20))
final_plot

Determinamos en una tabla la relación de sobrevivientes y su relación con la edad:

datosMuestra2 %>% filter(!is.na(age)) %>% group_by(survived) %>% summarise(media = mean(age), mediana = median(age), min = min(age), max = max(age)) 
## # A tibble: 2 x 5
##   survived media mediana   min   max
##   <fct>    <dbl>   <dbl> <dbl> <dbl>
## 1 No        30.5      28 0.333    74
## 2 Si        28.9      28 0.167    80

Otra variable que podemos analizar es la variable Fare o tarifa, ya que podemos revisar el punto de vista si el costo del ticket tiene relación directa con la variable survived o sobrevivencia.

plot1 <- ggplot(data = datosMuestra2, aes(x = fare, fill = survived)) + 
  geom_density(alpha = 0.5) + scale_fill_manual(values = c("blue", "orange")) + 
  geom_rug(aes(color = survived), alpha = 0.5) + scale_color_manual(values = c("blue", "orange")) + theme_bw()

plot2 <- ggplot(data = datosMuestra2, aes(x = survived, y = fare, color = survived)) +
      geom_boxplot(outlier.shape = NA) +
      geom_jitter(alpha = 0.3, width = 0.15) +
      scale_color_manual(values = c("blue", "orange")) +
      theme_bw()

plot_zen <- ggarrange(plot1, plot2, legend = "top")
plot_zen <- annotate_figure(plot_zen, top = text_grob("Sobreviviencia / Valor Ticket", size = 20))
plot_zen

Otra variable interesante de revisar, es la variable pclass, es de relevancia evaluar si las distintas clases en el titanic tuvo relación con al sobrevivencia.

pl <- ggplot(data = datosMuestra2, aes(x = pclass, y = ..count.., fill = survived)) + 
  geom_bar() +
  scale_fill_manual(values = c("blue", "orange")) +
  labs(title = "Sobreviviencia /Clase") +
  theme_bw() +
  theme(legend.position = "bottom")

plotazo <- ggplotly(pl)
plotazo

Sin duda, debemos analizar la variable sex, la cual nos entregará información de que sexo es la que mas sobrevivió, para ellos lo graficamos en el siguiente ggplot interactivo:

pl <- ggplot(data = datosMuestra2, aes(x = sex, y = ..count.., fill = survived)) +
  geom_bar() +
  labs(title = "Sobreviviencia / Sexo") +
  scale_fill_manual(values = c("blue", "orange")) +
  theme_bw() +
  theme(legend.position = "bottom")

plotazo <- ggplotly(pl)
plotazo

Arboles de Clasificación

Vamos a visualizar árboles de decisión con el fin de comprobar o comparar con el análisis exploratorio que realizamos

# cargar librerias para clasificacion
# install.packages('rpart')
library(rpart)
# install.packages('rattle')
library(rattle)
## Loading required package: bitops
## Rattle: A free graphical interface for data science with R.
## Version 5.4.0 Copyright (c) 2006-2020 Togaware Pty Ltd.
## Type 'rattle()' to shake, rattle, and roll your data.
# install.packages('rpart.plot')
library(rpart.plot)
arbol <- rpart(
  formula = survived ~ sex + age + pclass + fare,
  data = datosMuestra2,
  method = 'class'
)

# graficando el arbol
fancyRpartPlot(arbol)

Determinamos al revisar que tanto el análisis exploratorio de los datos, más las variables analizadas en el primer árbol, que las variables mas influyentes son sex “Sexo”, ages “Edad” y pclass “Clase”. Vamos a visualizar el mismo árbol pero con las variables mas influyentes.

arbol <- rpart(
  formula = survived ~ sex + age + pclass,
  data = datosMuestra2,
  method = 'class'
)

# graficando el arbol
fancyRpartPlot(arbol)

Resultados

Como resultado de los ejercicios de análisis exploratorio nos muestran las principales variables influyentes. gracias a la exploración de los datos y modelos de árboles podemos orientar a una visualización clara de cómo se comprtan las variables del dataset titanic.

Discusión

¿Podemos determinar si algunas de éstas variables infuyeron en la sobreviviencia de los pasajeros?

Conclusión

Podemos llegar a tomar conclusiones un poco más claras, observando los resultados de como se comportaron las variables más influyentes. Al principio del estudio descartamos variables de análisis sólo por calidad del dato, por ejemplo en la variable boat la cual indicaba el bote asignado, la mayoría se encontraba vacia, por la cual se eliminó en la sección limpieza de datos. De la misma forma las variables ticket. name, body, etc. todas variables que no indicaban un patrón claro.

La variables determinantes del estudio son: Sexo, Edad y Clase. Las cuales nos llevan a determinar primero, que hubo una preferencia a sobrevivir mujeres antes que hombres, en relación a la edad, el promedio de edad por cantidad si obsrevamos la media fue de 29 años aproximadamente, pero se prefirió salvar a niños y ancianos antes que adultos.