Clase 3

Conceptos relevantes de la clase anterior

Ciclo de vida de un proyecto de ciencia de datos

Qué es la Ciencia de datos?

El Team Data Science Process (TDSP) es una metodología de ciencia de datos ágil e iteractiva para ofrecer soluciones de análisis predictivo y aplicaciones inteligentes de manera eficiente. En la medida que las instituciones crean una metodología estandarizada para manejar procesos en equipo que incluyen el procesamiento de datos.

Ciclo de vida de un proyecto de Ciencia de datos

Business Understanding

Esta etapa implica la identificacion del problema de negocios, la definición de los objetivos y la identificación de las variables imrportantes para mi análisis. También abarca las métricas que serán utilizadas para medir el exito de un proyecto. Esta etapa además abarca la revision de los datos y el análisis de si estos son suficientes para responder la pregunta del proyecto.

Metas

Especificar cuáles son las variables que van a servir como las objetivo del modelo y cuáles son las métricas que se van a utilizar para evaluar el éxito del proyecto.

Identificar las fuentes de datos relevantes que el negocio tiene acceso o que necesita obtener.

Cómo Hacerlo

Cuánto? (Regresión). Qué categoría? (Clasificación). Qué grupo? (Clustering). Hay algo extraño? (Detección anomalías)

Definir los criterios de éxito

Los criterios de éxito deben ser SMART:

Data Aquisition and Understanding

Dado que los datos son el componente principal de los proyectos de ciencia de datos, el segundo paso requiere su uso intensivo. En este escenario, tengo que realizar todas las preguntas relativas a los datos que tengo, los que me faltan y los que podrían complementar mi pregunta. El principal objetivo es entender los datos, encontrar inconsistencias para que posibles errores de tipificacion no se propagen en mi modelo.

El objetivo es explorar los datos, preprocesarlos y limpiarlos. Existen otras preguntas que deben ser atentidas:

Data Aquisition and Understanding

Además implica el proceso de importación de datos al software escogido.

Retomemos la clase anterior …

Tipos de estructura

  • Vector Vector es la estructura de datos más común y básica en R.Son datos del mismo tipo, pero ordenados en una lista. Podemos crear un vector de la siguiente manera
z<-c(1,2.5,4,8)
  • Matrix Se caracteriza por ser bidimensional. Para definir una matriz a partir de un vector, la sintaxis es matriz (vector, nrow, ncol, byrow). Byrow define como se llena.
x<- matrix(1:20, nrow=5, ncol=4, byrow=TRUE)
x
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
## [5,]   17   18   19   20
  • Array Se comporta como una matriz, pero es multidimensional (más de 2).
x<- array(1:12, c(2,3,2))
x
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]    7    9   11
## [2,]    8   10   12
  • Dataframe Formato más utilizado, permite visualizar la base de datos como un excel.
df <- data.frame(
 type = c("A", "B", "C"),
 NC  = c(100,122,130),
 SC  = c(200,220,250),
 NY  = c(300,320, 380))

LLamamos un elemento

df[1,2]
## [1] 100

Llamamos un columna completa

df[,2]
## [1] 100 122 130
df$SC
## [1] 200 220 250

Llamamos una fila completa

df[1,]
##   type  NC  SC  NY
## 1    A 100 200 300

Llamamos un intervalo completo

df[,2:4]
##    NC  SC  NY
## 1 100 200 300
## 2 122 220 320
## 3 130 250 380

¡Vamos con datos reales!

library(readr)
titanic <- read_csv("https://raw.githubusercontent.com/edojimenez/r_datascience/main/titanic.csv")
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   PassengerId = col_double(),
##   Survived = col_double(),
##   Pclass = col_double(),
##   Name = col_character(),
##   Sex = col_character(),
##   Age = col_double(),
##   SibSp = col_double(),
##   Parch = col_double(),
##   Ticket = col_character(),
##   Fare = col_double(),
##   Cabin = col_character(),
##   Embarked = col_character()
## )

Datos que contiene la base titanic:

Survived : nominal - indica si la persona sobrevivió o no. Pclass : ordinal - indica la clase Sex : nominal - indica el sexo de la persona Age : Numeric - indica la edad SibSP : Numeric - indica el número de hermanos o esposos abordo con el pasajero. Parch : Numeric - indica el número de padres abordo Ticket : nominal - indica el número de ticket del pasajero Fare : Numeric - el monto de dinero que pagó el pasajero Cabin : nominal - el número de cabina Embarked : nominal - indica el puerto donde se embarco.

Tipos de datos

Principalmente, usaremos 3 tipos de datos: numericos, categoricos y textos.

Algo importante a examinar, es que los datos esten efectivamente en el formato correcto. de no ser así tenemos las siguientes herramientas:

A veces la lectura de las variables puede no ser correcto, por lo que tenemos que adaptarlo. Veamos que pasa con la base de Titanic

str(titanic)
## spec_tbl_df[,12] [891 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ PassengerId: num [1:891] 1 2 3 4 5 6 7 8 9 10 ...
##  $ Survived   : num [1:891] 0 1 1 1 0 0 0 0 1 1 ...
##  $ Pclass     : num [1:891] 3 1 3 1 3 3 1 3 3 2 ...
##  $ Name       : chr [1:891] "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
##  $ Sex        : chr [1:891] "male" "female" "female" "female" ...
##  $ Age        : num [1:891] 22 38 26 35 35 NA 54 2 27 14 ...
##  $ SibSp      : num [1:891] 1 1 0 1 0 0 0 3 0 1 ...
##  $ Parch      : num [1:891] 0 0 0 0 0 0 0 1 2 0 ...
##  $ Ticket     : chr [1:891] "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
##  $ Fare       : num [1:891] 7.25 71.28 7.92 53.1 8.05 ...
##  $ Cabin      : chr [1:891] NA "C85" NA "C123" ...
##  $ Embarked   : chr [1:891] "S" "C" "S" "S" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   PassengerId = col_double(),
##   ..   Survived = col_double(),
##   ..   Pclass = col_double(),
##   ..   Name = col_character(),
##   ..   Sex = col_character(),
##   ..   Age = col_double(),
##   ..   SibSp = col_double(),
##   ..   Parch = col_double(),
##   ..   Ticket = col_character(),
##   ..   Fare = col_double(),
##   ..   Cabin = col_character(),
##   ..   Embarked = col_character()
##   .. )
summary(titanic)
##   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                                        
## 
#Hacemos los cambios correspondientes
titanic$Pclass<-as.factor(titanic$Pclass)
titanic$Sex<-as.factor(titanic$Sex)
titanic$Cabin<-as.factor(titanic$Cabin)
titanic$Embarked<-as.factor(titanic$Embarked)
str(titanic)
## spec_tbl_df[,12] [891 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ PassengerId: num [1:891] 1 2 3 4 5 6 7 8 9 10 ...
##  $ Survived   : num [1:891] 0 1 1 1 0 0 0 0 1 1 ...
##  $ Pclass     : Factor w/ 3 levels "1","2","3": 3 1 3 1 3 3 1 3 3 2 ...
##  $ Name       : chr [1:891] "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
##  $ Sex        : Factor w/ 2 levels "female","male": 2 1 1 1 2 2 2 2 1 1 ...
##  $ Age        : num [1:891] 22 38 26 35 35 NA 54 2 27 14 ...
##  $ SibSp      : num [1:891] 1 1 0 1 0 0 0 3 0 1 ...
##  $ Parch      : num [1:891] 0 0 0 0 0 0 0 1 2 0 ...
##  $ Ticket     : chr [1:891] "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
##  $ Fare       : num [1:891] 7.25 71.28 7.92 53.1 8.05 ...
##  $ Cabin      : Factor w/ 147 levels "A10","A14","A16",..: NA 82 NA 56 NA NA 130 NA NA NA ...
##  $ Embarked   : Factor w/ 3 levels "C","Q","S": 3 1 3 3 3 2 3 3 3 1 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   PassengerId = col_double(),
##   ..   Survived = col_double(),
##   ..   Pclass = col_double(),
##   ..   Name = col_character(),
##   ..   Sex = col_character(),
##   ..   Age = col_double(),
##   ..   SibSp = col_double(),
##   ..   Parch = col_double(),
##   ..   Ticket = col_character(),
##   ..   Fare = col_double(),
##   ..   Cabin = col_character(),
##   ..   Embarked = col_character()
##   .. )

Paquete dplyr

El paquete dplyr fue desarrollado por Hadley Wickham de RStudio y es un versión optimizada de su paquete plyr. El paquete dplyr no proporciona ninguna nueva funcionalidad a R per se, en el sentido que todo aquello que podemos hacer con dplyr lo podríamos hacer con la sintaxis básica de R.

Una importante contribución del paquete dplyr es que proporciona una “gramática” (particularmente verbos) para la manipulación y operaciones con data frames.

Fuente: Programación en R

Se caracteriza por el signo %>% (pipe)

#install.packages("dplyr")
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

En general, los comandos que más se utilizan son:

Paquete dplyr: Ejemplos

Calcularemos el porcentaje de sobrevivencia por sexo

titanic %>% group_by(Sex) %>% summarise(mean(Survived)*100)
## # A tibble: 2 x 2
##   Sex    `mean(Survived) * 100`
##   <fct>                   <dbl>
## 1 female                   74.2
## 2 male                     18.9

Calcularemos el porcentaje de sobrevivencia por clase

titanic %>% group_by(Pclass) %>% summarise(mean(Survived)*100)
## # A tibble: 3 x 2
##   Pclass `mean(Survived) * 100`
##   <fct>                   <dbl>
## 1 1                        63.0
## 2 2                        47.3
## 3 3                        24.2

Calcularemos el porcentaje de sobrevivencia por clase por sexo

titanic %>% group_by(Pclass, Sex) %>% summarise(promedio=mean(Survived)*100)
## `summarise()` has grouped output by 'Pclass'. You can override using the `.groups` argument.
## # A tibble: 6 x 3
## # Groups:   Pclass [3]
##   Pclass Sex    promedio
##   <fct>  <fct>     <dbl>
## 1 1      female     96.8
## 2 1      male       36.9
## 3 2      female     92.1
## 4 2      male       15.7
## 5 3      female     50  
## 6 3      male       13.5

Calcularemos cuánto pagaron en promedio por clase aquellos que sobrevivieron

titanic %>% filter(Survived==1) %>% group_by(Pclass) %>% summarise(mean(Fare)) 
## # A tibble: 3 x 2
##   Pclass `mean(Fare)`
##   <fct>         <dbl>
## 1 1              95.6
## 2 2              22.1
## 3 3              13.7

Calcularemos cuantos vienen de cada puerto

titanic %>% group_by(Embarked) %>% summarise(total=n())
## # A tibble: 4 x 2
##   Embarked total
##   <fct>    <int>
## 1 C          168
## 2 Q           77
## 3 S          644
## 4 <NA>         2

Calcularemos cuantos vienen por cada puerto por sexo

titanic %>% group_by(Embarked, Sex) %>% summarise(Total=n())
## `summarise()` has grouped output by 'Embarked'. You can override using the `.groups` argument.
## # A tibble: 7 x 3
## # Groups:   Embarked [4]
##   Embarked Sex    Total
##   <fct>    <fct>  <int>
## 1 C        female    73
## 2 C        male      95
## 3 Q        female    36
## 4 Q        male      41
## 5 S        female   203
## 6 S        male     441
## 7 <NA>     female     2

Calcularemos cuantos vienen por cada puerto por sexo por clase

titanic %>% group_by(Embarked, Sex, Pclass) %>% summarise(Total=n())
## `summarise()` has grouped output by 'Embarked', 'Sex'. You can override using the `.groups` argument.
## # A tibble: 19 x 4
## # Groups:   Embarked, Sex [7]
##    Embarked Sex    Pclass Total
##    <fct>    <fct>  <fct>  <int>
##  1 C        female 1         43
##  2 C        female 2          7
##  3 C        female 3         23
##  4 C        male   1         42
##  5 C        male   2         10
##  6 C        male   3         43
##  7 Q        female 1          1
##  8 Q        female 2          2
##  9 Q        female 3         33
## 10 Q        male   1          1
## 11 Q        male   2          1
## 12 Q        male   3         39
## 13 S        female 1         48
## 14 S        female 2         67
## 15 S        female 3         88
## 16 S        male   1         79
## 17 S        male   2         97
## 18 S        male   3        265
## 19 <NA>     female 1          2

Exploración de los datos

La exploración de los datos posee los siguientes los siguientes etapas: - Inspección - Identificación de variables - Tratamiento de datos faltantes - Tratamiento de Outlier - Análisis univariado y bivariado - Transformación de variables - Creación de variables

Inspección

titanic %>% distinct  # Select only unique/distinct rows from a data frame.
## # A tibble: 891 x 12
##    PassengerId Survived Pclass Name   Sex     Age SibSp Parch Ticket  Fare Cabin
##          <dbl>    <dbl> <fct>  <chr>  <fct> <dbl> <dbl> <dbl> <chr>  <dbl> <fct>
##  1           1        0 3      Braun… male     22     1     0 A/5 2…  7.25 <NA> 
##  2           2        1 1      Cumin… fema…    38     1     0 PC 17… 71.3  C85  
##  3           3        1 3      Heikk… fema…    26     0     0 STON/…  7.92 <NA> 
##  4           4        1 1      Futre… fema…    35     1     0 113803 53.1  C123 
##  5           5        0 3      Allen… male     35     0     0 373450  8.05 <NA> 
##  6           6        0 3      Moran… male     NA     0     0 330877  8.46 <NA> 
##  7           7        0 1      McCar… male     54     0     0 17463  51.9  E46  
##  8           8        0 3      Palss… male      2     3     1 349909 21.1  <NA> 
##  9           9        1 3      Johns… fema…    27     0     2 347742 11.1  <NA> 
## 10          10        1 2      Nasse… fema…    14     1     0 237736 30.1  <NA> 
## # … with 881 more rows, and 1 more variable: Embarked <fct>

Missing Values

No existen reglas rígidas sobre qué hacer en caso que las variables. En general, debo plantearme ciertas preguntas importantes: - Por qué tengo datos faltantes?

Los errores sobre la recolección de datos pueden ser principalmente de 3 tipos: + Missing at random + Missing dependiendo de valores no observados + Missing dependiendo del mismo valor

Qué se puede hacer con los missing entonces?

En general, las alternativas para tratar las observaciones faltantes, solo son válidas cuando la atrición de la base de datos es aleatoria.

Reconocimiento de Missings

summary(titanic)
##   PassengerId       Survived      Pclass      Name               Sex     
##  Min.   :  1.0   Min.   :0.0000   1:216   Length:891         female:314  
##  1st Qu.:223.5   1st Qu.:0.0000   2:184   Class :character   male  :577  
##  Median :446.0   Median :0.0000   3:491   Mode  :character               
##  Mean   :446.0   Mean   :0.3838                                          
##  3rd Qu.:668.5   3rd Qu.:1.0000                                          
##  Max.   :891.0   Max.   :1.0000                                          
##                                                                          
##       Age            SibSp           Parch           Ticket         
##  Min.   : 0.42   Min.   :0.000   Min.   :0.0000   Length:891        
##  1st Qu.:20.12   1st Qu.:0.000   1st Qu.:0.0000   Class :character  
##  Median :28.00   Median :0.000   Median :0.0000   Mode  :character  
##  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                                                        
##       Fare                Cabin     Embarked  
##  Min.   :  0.00   B96 B98    :  4   C   :168  
##  1st Qu.:  7.91   C23 C25 C27:  4   Q   : 77  
##  Median : 14.45   G6         :  4   S   :644  
##  Mean   : 32.20   C22 C26    :  3   NA's:  2  
##  3rd Qu.: 31.00   D          :  3             
##  Max.   :512.33   (Other)    :186             
##                   NA's       :687

Reconocimiento de Missings

Identifico las variables que tienen NA

colSums(is.na(titanic))
## PassengerId    Survived      Pclass        Name         Sex         Age 
##           0           0           0           0           0         177 
##       SibSp       Parch      Ticket        Fare       Cabin    Embarked 
##           0           0           0           0         687           2

¿Qué pasa si hago intento calcular estadísticas con la base como esta?

sum(titanic$Age)
## [1] NA
median(titanic$Age)
## [1] NA
mean(titanic$Age)
## [1] NA

¡¡NO FUNCIONA!!

Entonces, tengo que agregar na.rm para que los calculos ocurran adecuadamente

sum(titanic$Age, na.rm = TRUE)
## [1] 21205.17
mean(titanic$Age, na.rm = TRUE)
## [1] 29.69912
median(titanic$Age, na.rm = TRUE)
## [1] 28
max(titanic$Age, na.rm = TRUE)
## [1] 80