Está en la página 1de 30

Material Adicional de Apoyo Machine Learning

Agosto 2022
Horacio Carvajal S.Y. ISC, MSc, MPhil
Contenido
Estructuras de Datos en R 3
Vectores 4
Vectores atómicos 4
Tipos y pruebas 4
Coerción 5
Listas 7
Atributos 9
Nombre - Names 10
Factores - Factors 11
Matrices y arreglos 13
Data frames 15
Creación 15
Prueba y coerción 15
Combinando data frames 16
Ambiente de R 17
Paquetes. 17
Paso más importante: Cómo decidir cuál es el objetivo a analizar. 19
Estructurar los datos en R. 21
Vectores 21
Cómo estructurar una variable. 22
Proceso de generación de un modelo en R y genéricamente en Machine Learning 25
Estructuras de Datos en R
Las estructuras base de R se pueden organizar en base a su dimensionalidad (1d, 2d, o sd) y también en
cuanto a si son homogéneas (todo el contenido es del mismo tipo) o heterogéneas (los contenidos pueden ser
de tipos diferentes). Esto resulta en los cinco tipos de datos utilizados con mayor frecuencia para el análisis de
datos:

Homogéneos Heterogéneos

1d Vector atómico Lista

2d Matriz Data frame

sd Arreglo

Notar que R tiene 0 dimensionales, o tipos escalares. Número individuales o cadenas, se pudieran considerar
como escalares, pero realmente son vectores de longitud uno.
Dado un objeto, la major forma de entender de qué tipo de estructuras está compuesto es utilizar str().
str() quiere decir structure y prove una descripción fácil de leer de cualquier estructura R de datos.
Las propiedades de un vector son su tipo, longitud y atributos. Hay cuatro tipos communes de vector atómico:

● Lógico – logical

● Entero – integer

● Doble (o numérico) – double (numeric)

● Caracter

Los elementos de una lista pueden ser de cualquier tipo (también listas). De forma similar, todo elemento de
una matriz debe ser del mismo tipo; en un data frame las columnas pueden tener tipos diferentes.
Vectores
La estructura de datos básica en R es el vector. Los vectores vienen en dos tipos: vectores atómicos y listas.
Tienen tres propiedades en común:

● Tipo, typeof(), qué es.


● Longitud, length(), cuántos elementos contiene.
● Atributos, attributes(), metadata arbitraria adicional.

Difieren en los tipos de sus elementos: todos los elementos de un vector atómico deben ser del mismo tipo,
mientras que los elementos de una lista pueden ser de tipos diferentes.
is.vector() no prueba si el objeto es un vector. Regresa TRUE solamente si el objeto es un vector sin atributos
aparte de nombres. Utilizar is.atomic(x) || is.list(x) para probar si el objeto es actualmente es un vector.

Vectores atómicos

Existen cuatro tipos comunes de vectores atómicos: lógico, entero, doble (llamado numérico usualmente) y
caracter.
Los vectores atómicos usualmente se crean con c(), que significa combinar o concatenar los elementos
generando un vector:

dbl_var <- c(1, 2.5, 4.5)


# Con el sufijo L se obtiene un entero en vez de un doble
int_var <- c(1L, 6L, 10L)
# Usar TRUE y FALSE (o T y F) para crear vectores lógicos
log_var <- c(TRUE, FALSE, T, F)
chr_var <- c("these are", "some strings")

Los vectores atómicos son siempre planos, aunque se aniden c()’s:

c(1, c(2, c(3, 4)))


#> [1] 1 2 3 4
# es lo mismo que
c(1, 2, 3, 4)
#> [1] 1 2 3 4

Los valores faltantes se especifican con NA, que es un vector de longitud 1. NA siempre será coercionado al
tipo correcto si se usa dentro de c(), o se puede crear NAs de un tipo específico con NA_real_ (vector
doble), NA_integer_ y NA_character_.

Tipos y pruebas

Dado un vector, se puede determiner su tipo con typeof(), o checar si es de un tipo específoco con la función
“is”: is.character(), is.double(), is.integer(), is.logical(), o, de forma más general, is.atomic().

int_var <- c(1L, 6L, 10L)


typeof(int_var)
#> [1] "integer"
is.integer(int_var)
#> [1] TRUE
is.atomic(int_var)
#> [1] TRUE

dbl_var <- c(1, 2.5, 4.5)


typeof(dbl_var)
#> [1] "double"
is.double(dbl_var)
#> [1] TRUE
is.atomic(dbl_var)
#> [1] TRUE

NB: is.numeric() es una prueba general para la “numerabilidad” de un vector y regresa TRUE tanto para
vectores enteros como dobles. No es una prueba específica para vectores dobles, que usualmente son
llamados numéricos (numeric).

is.numeric(int_var)
#> [1] TRUE
is.numeric(dbl_var)
#> [1] TRUE

Coerción

Todos los elementos de un vector atómico deben ser del mismo tipo, de forma que cuando se quiera
combiner tipos deben ser coercionados al tipo más flexible. Los tipos del más al menos flexible son: lógico,
entero, doble y caracter.
Por ejemplo, combiner un caracter y un entero, genera caracter:

str(c("a", 1))
#> chr [1:2] "a" "1"

Cuando un vector lógico se coerciona a entero o doble, TRUE se convierte en 1 y FALSE se convierte en 0. Esto
en muy útil en conjunción con sum() y mean()

x <- c(FALSE, FALSE, TRUE)


as.numeric(x)
#> [1] 0 0 1

# Número total de TRUEs


sum(x)
#> [1] 1

# Proporción que son TRUE


mean(x)
#> [1] 0.3333333

Coerción ocurre de forma automática. La mayoría de ls funciones matemáticas (+, log, abs, etc.) son
coercionadas a doble o entero, y la mayoría de las operaciones lógicas (&, |, any, etc) son coercionadas a
lógica. Usualmente se obtiene un mensaje de advertencia (warning message) si la coerción pierde información.
Si hay confusión, generar la coerción de forma explícita utilizando as.character(), as.double(), as.integer(),
o as.logical().
Listas
Listas son diferentes de los vectores atómicos porque sus elementos pueden ser de cualquier tipo, incluyendo
listas. Se contruyen utilizando list() en vez de c():

x <- list(1:3, "a", c(TRUE, FALSE, TRUE), c(2.3, 5.9))


str(x)
#> Lista de 4
#> $ : int [1:3] 1 2 3
#> $ : chr "a"
#> $ : logi [1:3] TRUE FALSE TRUE
#> $ : num [1:2] 2.3 5.9

Listas a veces son llamadas vectores recursivos, porque una lista puede contener otras listas. Esto las hace
fundamentalmente diferentes de los vectores atómicos.

x <- list(list(list(list())))
str(x)
#> List of 1
#> $ :List of 1
#> ..$ :List of 1
#> .. ..$ : list()
is.recursive(x)
#> [1] TRUE

c() combina varias listas en una. Dada una combinación de vectores atómicos y listas, c() coercina los
vectores a listas antes de combinarlas. Comparar los resultados de list() y c():

x <- list(list(1, 2), c(3, 4))


y <- c(list(1, 2), c(3, 4))
str(x)
#> Lista of 2
#> $ :Lista of 2
#> ..$ : num 1
#> ..$ : num 2
#> $ : num [1:2] 3 4
str(y)
#> List of 4
#> $ : num 1
#> $ : num 2
#> $ : num 3
#> $ : num 4

El typeof() de una lista es list. Se puede probar una lista con is.list() y coercionar a lista con as.list().
Se puede convertir una lista a vector atómico con unlist(). Si los elementos de una lista tienen tipos
diferentes, unlist() usa las mismas reglas de coerción que c().
Listas se usan para construir estructuras de datos más complicadas en R. Por ejemplo, tanto data frames y
objetos de modelos lineales (como los producidos por lm()) son lists:

is.list(mtcars)
#> [1] TRUE

mod <- lm(mpg ~ wt, data = mtcars)


is.list(mod)
#> [1] TRUE
Atributos
Todos los lbjetos pueden tener atributos adicionales, utilizados para almacenar metadatos sobre el objeto. Los
atributos se pueden considerer como una lista nombrada (con nombres únicos). Los atributos pueden ser
accesados de forma individual con attr() o todos al mismo tiempo (como una lista) con attributes().

y <- 1:10
attr(y, "my_attribute") <- "This is a vector"
attr(y, "my_attribute")
#> [1] "This is a vector"
str(attributes(y))
#> List of 1
#> $ my_attribute: chr "This is a vector"

La función structure() regresa un objeto muevo con atributos modificados:

structure(1:10, my_attribute = "This is a vector")


#> [1] 1 2 3 4 5 6 7 8 9 10
#> attr(,"my_attribute")
#> [1] "This is a vector"

Por default, la mayoría de los atributos se pierden al modificarse por un vector:

attributes(y[1])
#> NULL
attributes(sum(y))
#> NULL

Los únicos atributos que no se pierden son los tres más importantes:

● Nombres (Names), un vector caracter que da un nombre a cada elemento.

● Dimensions (Dimensions), usado para convertir vectores en matrices y arreglos.

● Clases (Class), usado para implementar los objetos del sistema S3.

Cada uno de estos atributos tiene una función específica de acceso para obtener y establecer valores. Al
trabajar con estos atributos, utilizar names(x), dim(x) y class(x), no attr(x, "names"), attr(x, "dim")
y attr(x, "class").
Nombre - Names
Se puede nombrar un vector de tres formas:

● Al crearlo: x <- c(a = 1, b = 2, c = 3).

● Modificando un vector existente: x <- 1:3; names(x) <- c("a", "b", "c").

O: x <- 1:3; names(x)[[1]] <- c("a").

● Creando una copia modificada del vector: x <- setNames(1:3, c("a", "b", "c")).

Los nombres no tienen que ser únicos. El subconjunto de caracteres es la razón más importante para utilizar
nombre y es más útil cuando los nombres son únicos.
No todos los elementos de un vector tienen que tener un nombre. Si faltan algunos nombres al crear el vector,
los nombre tendrán asignado una cadena vacía para esos elementos. Si se modifica el vector al establecer
algunos pero no todos los nombre de odas las variables, names() regresará NA (más específicamente el
carácter NA_character_) para ellos. Si faltan todos los nombres, names() regresará NULL.

y <- c(a = 1, 2, 3)
names(y)
#> [1] "a" "" ""

v <- c(1, 2, 3)
names(v) <- c('a')
names(v)
#> [1] "a" NA NA

z <- c(1, 2, 3)
names(z)
#> NULL

Se puede crear un vector nuevo sin nombres utilizando unname(x), o remover nombres con names(x) <- NULL.
Factores - Factors
Uno de los usos más importantes de atributos es la definición de factores. Un factor es un vector que contiene
solamente valores pre-definidos, y es utilizado para almacenar datos categóricos. Los factores se construyen
sobre vectores de enteros usando dos atributos: su clase class, “factor”, que lo hace comportarse diferentes a
los vectores enteros regulares, los niveles levels, que define el conjunto de valores permitidos.

x <- factor(c("a", "b", "b", "a"))


x
#> [1] a b b a
#> Levels: a b
class(x)
#> [1] "factor"
levels(x)
#> [1] "a" "b"

# No se puede usar valores que no están en los niveles - levels


x[2] <- "c"
#> Warning in `[<-.factor`(`*tmp*`, 2, value = "c"): invalid factor level, NA
#> generated
x
#> [1] a <NA> b a
#> Levels: a b

# NB: no se puede combiner factores


c(factor("a"), factor("b"))
#> [1] 1 1

Los factores son útiles cuando se conoce todos los valores posibles que puede tomar una variable, aunque
todavía no se tengan todos los valores en el conjunto de datos. Utilizar un factor en vez de un vector de
caracteres es algo que lo hace obvio cuando algunos grupos no contienen observaciones:

sex_char <- c("m", "m", "m")


sex_factor <- factor(sex_char, levels = c("m", "f"))

table(sex_char)
#> sex_char
#> m
#> 3
table(sex_factor)
#> sex_factor
#> m f
#> 3 0
Algunas veces cuando un data frame se lee directamente de un archive, una columna que se pensaría
produciría un vector numérico produce un factor. Esto es causado por valores no numéricos en la columna, a
menudo un valor faltante codificado de alguna forma especial como . o -. Para remediar esta situación,
coercionary el vector de un factor a un vector de caracteres, y el carácter a un vector doble. (Checar primero
por valores faltantes después de este proceso). Es mejor descubrir qué causo el problema y arreglarlo usando
el argumento na.strings con la función read.csv().

# Leyendo en "texto" en vez desde un archivo:


z <- read.csv(text = "value\n12\n1\n.\n9")
typeof(z$value)
#> [1] "integer"
as.double(z$value)
#> [1] 3 2 1 4
# Eso no es correcto: 3 2 1 4 son los niveles del factor,
# no los valores que se leyeron!
class(z$value)
#> [1] "factor"
# Se puede arreglar así:
as.double(as.character(z$value))
#> Warning: NAs introduced by coercion
#> [1] 12 1 NA 9
# O cambiar cómo se lee:
z <- read.csv(text = "value\n12\n1\n.\n9", na.strings=".")
typeof(z$value)
#> [1] "integer"
class(z$value)
#> [1] "integer"
z$value
#> [1] 12 1 NA 9
# Perfect0! :)

Aunque los factores se ven y a menudo se comportan como vectores caracter, son realmente enteros. En los
algoritmos de clasificación usualmente la variable de clasificación debe ser un factor, ya sea convertida desde
un inicio o utilizando la función factor().
Matrices y arreglos
Agregando un atributo dim a un vector atómico le permite comportarse como un arreglo array multi-
dimensional Un caso especial de arreglo es la matriz matrix, que tiene dos dimensiones. Las matrices son
utilizadas como parte de la maquinaria estadística de matemáticas. Los arreglos se utilizan de forma rara.
Matrices y arreglos se crean con matrix() y array(), o utilizando la forma de asignación de dim():

# Dos argumentos escalares para especificar renglones y columnas


a <- matrix(1:6, ncol = 3, nrow = 2)
# Un argumento de vector para describir todas las dimensiones
b <- array(1:12, c(2, 3, 2))

# Se puede modificar un objeto estableciendo dim()


c <- 1:6
dim(c) <- c(3, 2)
c
#> [,1] [,2]
#> [1,] 1 4
#> [2,] 2 5
#> [3,] 3 6
dim(c) <- c(2, 3)
c
#> [,1] [,2] [,3]
#> [1,] 1 3 5
#> [2,] 2 4 6

length() y names() tienen generalizaciones de alta dimensionalidad:

● length() generaliza a nrow() y ncol() para matrices, y dim() para arreglos.

● names() se genraliza a rownames() y colnames() para matrices, y dimnames(), una lista de vectores
carácter para arreglos.

length(a)
#> [1] 6
nrow(a)
#> [1] 2
ncol(a)
#> [1] 3
rownames(a) <- c("A", "B")
colnames(a) <- c("a", "b", "c")
a
#> a b c
#> A 1 3 5
#> B 2 4 6

length(b)
#> [1] 12
dim(b)
#> [1] 2 3 2
dimnames(b) <- list(c("one", "two"), c("a", "b", "c"), c("A", "B"))
b
#> , , A
#>
#> a b c
#> one 1 3 5
#> two 2 4 6
#>
#> , , B
#>
#> a b c
#> one 7 9 11
#> two 8 10 12

c() se generaliza a cbind() y rbind() para matrices, y a abind() (provisto por el paquete abind) para arreglos.
Se puede transponer una matriz con t(); el equivalente generalizado para arreglos es aperm().
Se puede probar si un objeto es una matriz o arreglo usando is.matrix() y is.array(), o checando la longitud
de dim().
as.matrix() y as.array() permiten cambiar un vector existente a matriz o arreglo.
Se puede tener matrices con un solo renglón o una sola columna, o arreglos con una sola dimensión. Se
imprimen de forma similar, pero se comportan de forma diferente.

str(1:3) # 1d vector
#> int [1:3] 1 2 3
str(matrix(1:3, ncol = 1)) # column vector
#> int [1:3, 1] 1 2 3
str(matrix(1:3, nrow = 1)) # row vector
#> int [1, 1:3] 1 2 3
str(array(1:3, 3)) # "array" vector
#> int [1:3(1d)] 1 2 3
Data frames
Un data frame es la forma más común de almacenar datos en R. Su principal ventaja es que las columnas
pueden ser de diferente tipo, lo que puede ser usual en muchas aplicaciones de aprendizaje de máquina. Se
pueden decir que de forma interna, un data frame es una lista de vectores de misma longitud. Esto genera una
estructura de 2 dimensiones (un simil puede considerarse como si fuera una tabla de base de datos relacional,
o una hoja de Excel).

Un data frame puede utilizar las funciones names(), colnames(), and rownames(),
aunque names() y colnames() son la misma cosa. La longitud length() de un data frame es la longitud de la
lista, así que es lo mismo que ncol(); nrow() provee el número de renglones.

Creación

Se puede crear un data frame usando la función data.frame(), que toma un vector con nombre como entrada:

df <- data.frame(x = 1:3, y = c("a", "b", "c"))


str(df)
#> 'data.frame': 3 obs. de 2 variables:
#> $ x: int 1 2 3
#> $ y: Factor c/ 3 levels "a","b","c": 1 2 3

df <- data.frame(
x = 1:3,
y = c("a", "b", "c"),
stringsAsFactors = FALSE)
str(df)
#> 'data.frame': 3 obs. of 2 variables:
#> $ x: int 1 2 3
#> $ y: chr "a" "b" "c"

Prueba y coerción

Para checar si un objeto es un data frame, usar class() o probar de forma explicita con is.data.frame():

typeof(df)
#> [1] "list"
class(df)
#> [1] "data.frame"
is.data.frame(df)
#> [1] TRUE

Se puede coercinar un objeto a un data frame con as.data.frame():

● Un vector genera un data frame de una-columna.


● Una lista genera una columna para cada element, si no son de la misma longitud se produce un error.

● Una matriz crea un data frame con el mismo número de columnas y renglones que la matriz.

Combinando data frames

Se puede combiner data frames usando cbind() y rbind():

cbind(df, data.frame(z = 3:1))


#> x y z
#> 1 1 a 3
#> 2 2 b 2
#> 3 3 c 1
rbind(df, data.frame(x = 10, y = "z"))
#> x y
#> 1 1 a
#> 2 2 b
#> 3 3 c
#> 4 10 z

Un error comun es tratar de crear un data frame con cbind() usando vectores. Esto no trabaja
porque cbind() creará una matriz a menos de que uno de los argumentos ya sea un.
Usar data.frame() alternativamente directamente:

bad <- data.frame(cbind(a = 1:2, b = c("a", "b")))


str(bad)
#> 'data.frame': 2 obs. of 2 variables:
#> $ a: Factor w/ 2 levels "1","2": 1 2
#> $ b: Factor w/ 2 levels "a","b": 1 2
good <- data.frame(a = 1:2, b = c("a", "b"),
stringsAsFactors = FALSE)
str(good)
#> 'data.frame': 2 obs. of 2 variables:
#> $ a: int 1 2
#> $ b: chr "a" "b"
Ambiente de R
R es un ambiente de software libre para estadística y graficación computacional desarrollado bajo el esquema "open
source" por lo que todos tienen acceso a su código. En su esencia, R existe como un paquete base con una
funcionalidad bastante completa.

Una de las características más importantes de R es su expansión a través de bajar paquetes que añaden una
funcionalidad específica al programa. R y sus paquetes se encuentran almacenados en una localidad central
conocida como CRAN (Comprehensive R Archive Network). CRAN tiene sitios espejo a través del mundo. La filosofía
básica es seleccionar un CRAN que se encuentre cercano a uno.

Le estructura del ambiente se puede visualizar como sigue:

Paquetes.

1. Decidir qué paquete(s) utilizar


2. Instalar el (los) paquete(s) con el comando

install.packages("nombre del paquete")

3. Recordar que la primera vez que se lleve a cabo la instalación de paquetes, se deberá seleccionar un sitio
espejo de las opciones que R estará mostrando.
4. “Activar” el paquete dentro del área de trabajo con el comando:

library("nombre del paquete")

5. Preparar los datos de forma matricial, similar a la estructura de una tabla relacional o tipo hoja de Excel:
cada columna corresponde a una de las variables de los datos, cada renglón corresponde a un elemento
(registro) de los datos.
6. De preferencia, generar los datos bajo un esquema separado por comas (esto es, archivo csv).
7. Llevar a cabo la lectura de los datos. Asumiendo que son de tipo csv y que se asigna al elemento objeto, el
comando a utilizar es:
objeto <- read.csv("ruta y nombre del archivo .csv")

8. Para facilitar el acceso al archivo y no tener que escribir la ruta, se recomienda utilizar el comando
file.choose(). La lectura quedaría de la siguiente forma:

objeto <- read.csv(file.choose())

9. Cuando se lleve a cabo la lectura de un archivo se recomienda revisar su estructura con el comando str().
Observar que todas las variables estén correctas.

str(objeto)

10. Adicionalmente se puede observar tanto los primeros seis registros como los últimos seis registros. El
objetivo es checar que los datos hayan sido cargados de forma correcta. Utilizar los comandos head() y tail()
respectivamente.

head(objeto)

tail(objeto)
Paso más importante: Cómo decidir cuál es el objetivo a analizar.

La decisión más importante es decidir qué es lo que se va a analizar o qué pregunta se va a responder. Aquí se
mostrará el proceso lógico de cómo a partir de un ambiente real se estará acotando los datos a utilizar. Para ello se
utilizará la información en la página American Airlines Fleet Details and History (planespotters.net) analizando la
flota de American Airlines al 16 de junio del 2021.

La matriz de datos de la flota es la siguiente:

Current

Aircraft Type In Service Parked Total Future 2 Historic Avg. Age Total

Airbus A300 35 35

Airbus A319 127 6 133 17.2 Years 133

Airbus A320 47 1 48 20 20.2 Years 68

Airbus A321 231 21 252 1 1 7.8 Years 254

Airbus A330 24 24

BAC 1-11 3 3

Boeing 717 29 29

Boeing 727 1 1

Boeing 737 296 48 344 47 10.5 Years 391

Boeing 747 21 21

Boeing 757 177 177

Boeing 767 107 107

Boeing 777 64 3 67 16.6 Years 67

Boeing 787 Dreamliner 46 46 7 4.3 Years 53

British Aerospace BAe 146/Avro RJ 8 8

Douglas DC-8 6 6

Embraer ERJ-190 20 20

Fokker F70 / F100 75 75

McDonnell Douglas DC-10 66 66

McDonnell Douglas MD-11 19 19

McDonnell Douglas MD-80 383 383

McDonnell Douglas MD-90 5 5

Total 811 79 890 8 1047 11.4 Years 1945

Para el objetivo de este documento se toman las siguientes decisiones:

a) Solamente considerar la flota en uso: en servicio y estacionados.


b) De acuerdo al punto anterior, remover toda la flota histórica que ya no se encuentra en uso.
c) Las variables a considerar son:
a. Aparatos en servicio
b. Aparatos estacionados
c. Edad promedio de los aparatos en a. y b.
d) El punto c) anterior indica que se remuevan los aparatos históricos y los futuros.
e) Se estará trabajando a nivel modelo específico de cada familia de aparatos, por lo que se deberá abrir la
matriz.

Los datos finales a utilizar son los siguientes:

Aircraft
In Service
Type Parked Avg. Age

Airbus A319 127 6 17.2 Years

Airbus A319-100 127 6 17.2 Years

Airbus A320 47 1 20.2 Years

Airbus A320-200 47 1 20.2 Years

Airbus A321 231 21 7.8 Years

Airbus A321-200 198 20 8.9 Years

Airbus A321neo 33 1 1.1 Years

Boeing 737 296 48 10.5 Years

Boeing 737-800 255 48 11.6 Years

Boeing 737 MAX 8 41 2.4 Years

Boeing 777 64 3 16.6 Years

Boeing 777-200 44 3 20.6 Years

Boeing 777-300ER 20 7.4 Years

Boeing 787 Dreamliner 46 4.3 Years

Boeing 787-8 Dreamliner 24 4.9 Years

Boeing 787-9 Dreamliner 22 3.7 Years

Se eliminan los totales ya que se pueden generar en R.

Las familias de aparatos a analizar son:


Airbus A319

Airbus A320

Airbus A321

Boeing 737

Boeing 777

Boeing 787 Dreamliner

Los modelos por familia son:


Airbus A319-100

Airbus A320-200

Airbus A321-200

Airbus A321neo

Boeing 737-800

Boeing 737 MAX 8

Boeing 777-200

Boeing 777-300ER

Boeing 787-8 Dreamliner

Boeing 787-9 Dreamliner

Estructurar los datos en R.

Las estructuras de datos se referirán aquí como estructuras de conocimiento ya que lo que se pretende es capturar,
manipular, analizar conocimiento. Los tipos de estructuras son los siguientes:

● Vectores: estructura que almacena objetos de un mismo tipo.

● Matrices: se pueden considerar como vectores que pueden indexarse por dos o más índices.

● Factores (factors): estructuras que permiten manejar datos categóricos.

● Listas: forma general de vector donde los elementos no tienen que ser del mismo tipo.

● Data Frames: estructuras tipo matriz donde las columnas pueden ser de diferentes tipos.

● Funciones: permiten ejecutar funciones dentro del ambiente de R.

Vectores

Una de las estructuras más utilizadas. Se puede visualizar de forma similar como si fuera una columna en Excel,
donde la primera celda correspondería al nombre el vector, o en el Excel el nombre de la columna. El resto de
elementos dentro de la columna serían los elementos del vector. Una característica de los vectores es que
solamente pueden contener elementos de un mismo tipo de datos. En el ejemplo inferior, todos los elementos son
de tipo cadena de caracteres.
La primera variable a generar se estará llamando FamiliaAA. Se puede seleccionar cualquier nombre, con la única
condición que cumpla con las reglas de estructuración de variables. Esta variable va a contener los nombre de las
familias. Para asignar los datos de familias, la variable FamiliaAA se estará estructurando como un vector, o sea,
donde cada elementos indica la familia correspondiente a los modelos por familia. Por ejemplo, para Airbus A321-
200 y Airbus A321neo los dos primeros modelos pertenecen a la familia Airbus A321, por lo que ésta se deberá
repetir 2 veces.

Cómo estructurar una variable.

El primer concepto que se debe comprender son las variables. Una variable en R puede almacenar una de las
estructuras de conocimiento que se generen dentro del lenguaje. Las reglas que debe seguir el nombrar una variable
son:

● Se compone utilizando letras, números, guión inferior y/o el caracter punto (.).

● El nombre de la variable iniciando con una letra o un punto no puede ser seguido de un número.

● Es recomendable utilizar nombre de variables que permitan recordar/identificar lo que representan.

● Evitar nombres que contengan caracteres como £, $, %, ^ *, +,- , ( ), [ ], #, !, ?, <, >

R es “case-sensitive”: Es muy importante considerar que R es sensible a minúsculas y mayúsculas. Por ejemplo,
la variable flotaAA es diferente a la variable FlotaAA y a la variable FLOTAAA, etc.

La generación de la variable se lleva a cabo con la función de concatenación c(). Es similar a la función de concatenar
en Excel, donde dentro de los paréntesis se indica los elementos a concatenar. Observar que como son cadenas de
caracteres, es necesario acotarlos con comillas y separar cada elemento por coma.

> FamiliaAA <- c("Airbus A319", "Airbus A320", "Airbus A321", "Airbus A321",

+ "Boeing 737", "Boeing 737", "Boeing 777", "Boeing 777",

+ "Boeing 787 Dreamliner", "Boeing 787 Dreamliner")


Revisando la variable, simplemente escribiendo su nombre:

> FamiliaAA

[1] "Airbus A319" "Airbus A320" "Airbus A321"

[4] "Airbus A321" "Boeing 737" "Boeing 737"

[7] "Boeing 777" "Boeing 777" "Boeing 787 Dreamliner"

[10] "Boeing 787 Dreamliner"

>

La segunda variable a crear será FlotAA que contendrá el detalle de la flota:

> FlotaAA <- c("Airbus A319-100", "Airbus A320-200", "Airbus A321-200", "Airbus A321neo", "Boeing 737-800",

+ "Boeing 737 MAX 8", "Boeing 777-200", "Boeing 777-300ER", "Boeing 787-8 Dreamliner", "Boeing 787-9
Dreamliner")

>

Observar que ambas variables tienen el mismo número de elementos, y la correspondencia familia-aparato por
posición:str

> str(FamiliaAA)

chr [1:10] "Airbus A319" "Airbus A320" "Airbus A321" "Airbus A321" "Boeing 737" "Boeing 737" "Boeing 777"
"Boeing 777" ...

> str(FlotaAA)

chr [1:10] "Airbus A319-100" "Airbus A320-200" "Airbus A321-200" "Airbus A321neo" "Boeing 737-800" "Boeing
737 MAX 8" "Boeing 777-200" ...

>

Las siguientes variables a generar son:

EnServicio: número de aparatos en servicio.

Estacionados: número de aparatos estacionados.

EdadPromedio: antigüedad promedio por tipo de aparato.

> EnServicio <- c(127, 47, 198, 33, 255, 41, 44, 20, 24, 22)

> Estacionados <- c(6, 1, 20, 1, 48, 0, 3, 0, 0, 0)

> EdadPromedio <- c(17.2, 20.2, 8.9, 1.1, 11.6, 2.4, 20.6, 7.4, 4.9, 3.7)

Verificando:

> str(EnServicio)

num [1:10] 127 47 198 33 255 41 44 20 24 22

> str(Estacionados)

num [1:10] 6 1 20 1 48 0 3 0 0 0
> str(EdadPromedio)

num [1:10] 17.2 20.2 8.9 1.1 11.6 2.4 20.6 7.4 4.9 3.7

>

> FamiliaAA == "Boeing 777"

[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE

> FlotaAA[FamiliaAA == "Boeing 777"]

[1] "Boeing 777-200" "Boeing 777-300ER"


Proceso de generación de un modelo en R y genéricamente en
Machine Learning

R version 4.0.3 (2020-10-10) -- "Bunny-Wunnies Freak Out"

Copyright (C) 2020 The R Foundation for Statistical Computing

Platform: x86_64-w64-mingw32/x64 (64-bit)

R es un software libre y viene sin GARANTIA ALGUNA.

Usted puede redistribuirlo bajo ciertas circunstancias.

Escriba 'license()' o 'licence()' para detalles de distribucion.

R es un proyecto colaborativo con muchos contribuyentes.

Escriba 'contributors()' para obtener más información y

'citation()' para saber cómo citar R o paquetes de R en publicaciones.

Escriba 'demo()' para demostraciones, 'help()' para el sistema on-line de ayuda,

o 'help.start()' para abrir el sistema de ayuda HTML con su navegador.

Escriba 'q()' para salir de R.

Warning: namespace ‘tm’ is not available and has been replaced

by .GlobalEnv when processing object ‘toSpace’

[Previously saved workspace restored]

# SIEMPRE SE DEBE INSTALAR EL PAQUETE A UTILIZAR PARA LA GENERACIÓN DEL MODELO (A MENOS DE QUE

# R LO CONTENGA EN LA CARGA INICIAL)

> install.packages("tree")

Installing package into ‘C:/Users/INSPIRON/Documents/R/win-library/4.0’

(as ‘lib’ is unspecified)

--- Please select a CRAN mirror for use in this session ---

probando la URL 'https://mirror.las.iastate.edu/CRAN/bin/windows/contrib/4.0/tree_1.0-40.zip'

Content type 'application/zip' length 178393 bytes (174 KB)

downloaded 174 KB

package ‘tree’ successfully unpacked and MD5 sums checked


The downloaded binary packages are in

C:\Users\INSPIRON\AppData\Local\Temp\RtmpcrFZ5k\downloaded_packages

# “ACTIVAR” EL PAQUETE CON LA FUNCIÓN DE library()

> library(tree)

# EN ESTE EJEMPLO SE UTILIZARÁ EL PAQUETE ISLR PARA TOMAR DATOS QUE CONTIENE EL PAQUETE

> install.packages("ISLR")

Installing package into ‘C:/Users/INSPIRON/Documents/R/win-library/4.0’

(as ‘lib’ is unspecified)

probando la URL 'https://mirror.las.iastate.edu/CRAN/bin/windows/contrib/4.0/ISLR_1.2.zip'

Content type 'application/zip' length 2924403 bytes (2.8 MB)

downloaded 2.8 MB

package ‘ISLR’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in

C:\Users\INSPIRON\AppData\Local\Temp\RtmpcrFZ5k\downloaded_packages

> library(ISLR)

# POR FACILIDAD, AL USAR LA FUNCIÓN attach() SE EVITA EL TENER QUE REFERIRSE A LAS VARIABLES DE

# TENIENDO QUE UTILIZAR LA NOMENCLATURA objeto$variable, Y R ASUME QUE LAS VARIABLES PERTENECEN A

# objeto. POR EJEMPLO, EN VEZ DE REFERISE AL PRECIO COMO Carseats$Price, ES SUFICIENTE UTILIZAR Price

> attach(Carseats)

# PASO VERIFICACION: SIEMPRE REVISAR LAS ESTRUCTURAS DE DATOS QUE SE UTILIZEN O SE LEAN

> str(Carseats)

'data.frame': 400 obs. of 11 variables:

$ Sales : num 9.5 11.22 10.06 7.4 4.15 ...

$ CompPrice : num 138 111 113 117 141 124 115 136 132 132 ...

$ Income : num 73 48 35 100 64 113 105 81 110 113 ...

$ Advertising: num 11 16 10 4 3 13 0 15 0 0 ...

$ Population : num 276 260 269 466 340 501 45 425 108 131 ...

$ Price : num 120 83 80 97 128 72 108 120 124 124 ...

$ ShelveLoc : Factor w/ 3 levels "Bad","Good","Medium": 1 2 3 3 1 1 3 2 3 3 ...

$ Age : num 42 65 59 55 38 78 71 67 76 76 ...

$ Education : num 17 10 12 14 13 16 15 10 10 17 ...


$ Urban : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 2 2 1 1 ...

$ US : Factor w/ 2 levels "No","Yes": 2 2 2 2 1 2 1 2 1 2 ...

# PRE-PROCESAMIENTO Y PREPARACIÓN DE DATOS: EN ESTE CASO SE TIENE EL PRECIO DE LOS ASIENTOS

# DE AUTO PARA NIÑO. SE PRETENDE QUE EL MODELO IDENTIFIQUE LAS VARIABLES QUE IDENTIFIQUEN

# SI EL ASIENTO ES DE VENTAS ALTAS O BAJAS. SE CUENTA CON LA VARIABLE DE VENTAS, Y ES NUMÉRICA

# PARA CONVERTIR EN UN PROBLEMA DE CLASIFICACIÓN, ES NECESARIO GENERAR UNA VARIABLE

# DERIVADA. ESTA VARIABLE SE LLAMARA VentasAltas Y SE COMPONE DE LA SIGUIENTE REGLA:

# SI LAS VENTAS SON MENORES O IGUALES A 8, LAS VENTAS NO SON ALTAS, SI SON MAYORES A 8. LAS VENTAS

# SON ALTAS

> VentasAltas <- ifelse(Sales <= 8, "NO", "SI")

# LA VARIABLE NUEVA SE TIENE QUE AGREGAR AL CONJUNTO DE DATOS

> Carseats <- data.frame(Carseats, VentasAltas)

# COMO SE MENCIONÓ, SIEMPRE VERIFICAR LA ESTRUCTURA

> str(Carseats)

'data.frame': 400 obs. of 12 variables:

$ Sales : num 9.5 11.22 10.06 7.4 4.15 ...

$ CompPrice : num 138 111 113 117 141 124 115 136 132 132 ...

$ Income : num 73 48 35 100 64 113 105 81 110 113 ...

$ Advertising: num 11 16 10 4 3 13 0 15 0 0 ...

$ Population : num 276 260 269 466 340 501 45 425 108 131 ...

$ Price : num 120 83 80 97 128 72 108 120 124 124 ...

$ ShelveLoc : Factor w/ 3 levels "Bad","Good","Medium": 1 2 3 3 1 1 3 2 3 3 ...

$ Age : num 42 65 59 55 38 78 71 67 76 76 ...

$ Education : num 17 10 12 14 13 16 15 10 10 17 ...

$ Urban : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 2 2 1 1 ...

$ US : Factor w/ 2 levels "No","Yes": 2 2 2 2 1 2 1 2 1 2 ...

$ VentasAltas: chr "SI" "SI" "SI" "NO" ...

# SE DECIDE UTILIZAR 70% DE LOS DATOS PARA ENTRENAR EL MODELO Y 30% PARA PROBARLO

# 70% DE 400 ES 280

> 400*.70

[1] 280

# COMO SE UTILIZAN FUNCIONES ALEATORIAS EN LA SELECCIÓN DE LOS ÍNDICES DE RENGLONES A TOMAR

# DE LOS 280 DATOS, SE ESTABLECE LA FUNCIÓN set.seed() CON CUALQUIER NÚMERO PARA QUE SE PUEDA

# REPETIR POSTERIORMENTE EL EJERCICIO O CONTINUAR TRABAJANDO EN ÉL, Y ÉSTE CONTENGA LOS MISMOS
# REGISTROS CON LOS QUE SE HA VENIDO TRABAJANDO, YA QUE DE OTRA FORMA, SI SE VUELVE A GENERAR

# EL ALEATORIO, LOS DATOS CAMBIAN Y POR LO TANTO AFECTAN AL MODELO.

> set.seed(50)

# DE FORMA ALEATORIO SE TOMAN 280 NÚMEROS ENTRE EL 1 Y EL 400, ESTOS SON LOS RENGLONES QUE

# CORRESPONDEN A LOS DATOS DE ENTRENAMIENTO

> train <- sample(400,280)

# SE GUARDAN LOS DATOS DE LA MATRIZ PERO SOLAMENTE AQUELLOS RENGLONES DE ENTRENAMIENTO

> Carseats_entrena <- Carseats[train,]

# LOS DATOS DE PRUEBA SON EL COMPLEMENTO, POR LO TANTO SE TOMAN TODOS LOS RENGLONES

# EXCEPTO LOS DE ENTRENAMIENTO. ESO SE GENERA ANTEPONIENDO EL SIGNO – AL VECTOR CON LOS

# ÍNDICES DE ENTRENAMIENTO -train

> Carseats_prueba <- Carseats[-train,]

# YA QUE SE PRE-PROCESARON, LIMPIARON Y TRANSFORMARON LOS DATOS, SE GENERA EL MODELO. PARA

# ELLO SE UTILIZARÁ LA FUNCIÓN tree(). COMO SE MENCIONÓ EN EL MATERIAL DE FACTORES, EN CLASIFICACIÓN

# SE REQUIERE QUE LA VARIABLE DE CLASIFICACIÓN SEA FACTOR. YA QUE EN EL CONJUNTO DE DATOS

# VentasAltas NO ES UN FACTOR, SE CONVIERTE UTILIZANDO LA FUNCIÓN factor().

# VentasAltas ES FUNCIÓN DE VENTAS Sales. POR ELLO ES NECESARIO REMOVER VENTAS Sales DEL

# CONJUNTO DE DATOS -Sales. EL CONJUNTO DE ENTRENAMIENTO ES EL QUE SE GUARDÓ COMO

# Carseats_entrena.

> modelo.carseats <- tree(factor(VentasAltas)~.-Sales, Carseats_entrena)

# ESTE MODELO PERMITE VER EL MODELO DE FORMA GRÁFICA.

> plot(modelo.carseats )

> text(modelo.carseats , pretty=0)

Variable Variable Objetivo Variable de Entrada Variable Eliminada Variable en el


Modelo

Sales

CompPrice

Income

Advertising

Population

Price

ShelveLoc

Age

Education

Urban

US

> summary(modelo.carseats)

Classification tree:

tree(formula = factor(VentasAltas) ~ . - Sales, data = Carseats_entrena)

Variables actually used in tree construction:

[1] "ShelveLoc" "Advertising" "Income" "Age" "Population" "Price" "CompPrice"

Number of terminal nodes: 22

Residual mean deviance: 0.3645 = 94.05 / 258

Misclassification error rate: 0.075 = 21 / 280

# PROCEDER CON LA PRUEBA, UTILIZANDO EL CONJUNTO DE PRUEBA Y LA FUNCIÓN DE PREDICCIÓN.

> modelo.carseats <- tree(factor(VentasAltas)~.-Sales, Carseats_entrena)

> prediccion_carseats =predict(modelo.carseats, Carseats_prueba, type="class")

> Altas = Carseats_prueba$VentasAltas

> table(prediccion_carseats, Altas)

Altas

prediccion_carseats NO SI

NO 55 21

SI 18 26

Nivel de error: (55 + 26) / (55 + 21 + 18 + 29)


# AHORA SE MUESTRA QUÉ PASA SI NO SE ELIMINA LA VARIABLE DE VENTAS Sales. COMO SE OBSERVA CON ESA
VARIABLE ES SUFICIENTE PARA GENERAR EL RESULTADO COMO ES OBVIO. Ventas Altas ESTÁ TOTALMENTE
CORRELACIONADA CON VENTAS Sales.

> prueba <- tree(factor(VentasAltas)~., Carseats_entrena)

> summary(prueba)

Classification tree:

tree(formula = factor(VentasAltas) ~ ., data = Carseats_entrena)

Variables actually used in tree construction:

[1] "Sales"

Number of terminal nodes: 2

Residual mean deviance: 0 = 0 / 278

Misclassification error rate: 0 = 0 / 280

> plot(prueba)

> text(prueba, pretty=0)

También podría gustarte