Análisis discriminante (LDA)

Analizaremos los datos de Iris para obtener una clasificación de las especies a partir de datos de morfología.

library(MASS)
library(ggplot2)
library(caret)

attach(iris)
str(iris)

# escalamos cada variable predictora (i.e.  primeras cuatro columnas)
iris[1:4] <- scale(iris[1:4])

# hacemos que el ejemlo sea reproducible
set.seed(1)

# Usamos 70% del dataset como training set y el estante 30% como testing set
sample <- sample(c(TRUE, FALSE), nrow(iris), replace=TRUE, prob=c(0.7,0.3))
train <- iris[sample, ]
test <- iris[!sample, ] 

# hacemos el LDA
model <- lda(Species~., data = train)

# vemos  el modelo 
model

# usamos el LDA para hacer predicciones
predicted <- predict(model, test)
names(predicted)

# view lo que predijo el modelo para las primeras 6 observaciones en test
head(predicted$class)

# vemos las probilidades posteriores para las primeras 6 observaciones 
# en el test
head(predicted$posterior)

# vemos los discriminantes lineales para las primeras 6 observaciones 
# en el test
head(predicted$x)

# vemos el accuracy de nuestro modelo
mean(predicted$class == test$Species)

# definimos que vamos a graficar
lda_plot <- cbind(train, predict(model)$x)

# creamos el plot
ggplot(lda_plot, aes(LD1, LD2)) +
  geom_point(aes(color = Species))

# Histogramas para los valores de la función discriminante (LDA1)
p <- predict(model, train)
ldahist(data = p$x[,1], g = train$Species)

# Histogramas para el LDA2
ldahist(data = p$x[,2], g = train$Species)

# Matriz de confusión y Accuracy (en train)
p1 <- predict(model, train)$class
tab <- table(Predicted = p1, Actual = train$Species)
tab
sum(diag(tab))/sum(tab)

confusionMatrix(p1, train$Species) # con caret

#  de confusión y Accuracy (en testing)
p2 <- predict(model, test)$class
tab1 <- table(Predicted = p2, Actual = test$Species)
tab1
sum(diag(tab1))/sum(tab1)

confusionMatrix(p2, test$Species)

Árboles de clasificación

Analizaremos los datos de carseats (venta de asientos de auto para niños) mediante árboles de clasificación. Los datos pertenecen a la librería ISLR2.

library (tree)
library (ISLR2)
attach (Carseats)

?Carseats

##Convertimos la variable en binaria
High <- factor (ifelse(Sales <= 8, "No", " Yes "))

# Agregamos la nueva variable
Carseats <- data.frame(Carseats, High)

# Probamos un árbol
tree.carseats <- tree(High ~ . -Sales, Carseats)
summary(tree.carseats)

# Graficamos el árbol
plot(tree.carseats)
text(tree.carseats, pretty = 0)
tree.carseats

# Veo en test
set.seed(2)
train <- sample(1: nrow(Carseats), 200)
Carseats.test <- Carseats[-train, ]
High.test<- High[- train]
tree.carseats<- tree(High ~ . -Sales, Carseats, subset = train)
tree.pred<- predict(tree.carseats, Carseats.test, type = "class")
table(tree.pred,High.test)

# Podamos el árbol y vemos si mejora
set.seed(7)
cv.carseats <- cv.tree(tree.carseats, FUN = prune.misclass)
names(cv.carseats)
cv.carseats

# A pesar de su nombre, dev corresponde al número de errores de validación 
# cruzada. El árbol con 9 nodos terminales da como resultado sólo 74 errores 
# de validación cruzada.

# Ploteamos la tasa de error en función del tamaño y de K
par(mfrow = c(1, 2))
plot(cv.carseats$size, cv.carseats$dev,type = "b")
plot(cv.carseats$k, cv.carseats$dev,type = "b")

# Podamos el árbol y obtenemos un ábol con 9 nodos
prune.carseats <- prune.misclass(tree.carseats, best = 8)
plot(prune.carseats)
text(prune.carseats, pretty = 0)

# Cómo funcionan nuestro árbol podado
tree.pred <- predict(prune.carseats, Carseats.test, type = "class")
table(tree.pred,High.test)

Random Forest

Analizaremos el precio de las viviendas en 506 suburbios de Boston. Los datos provienen del paquete ILSR2.

library(randomForest)
attach(Boston)

# Divido en datos de train y test
train <- sample(1:nrow(Boston), nrow(Boston)/2)
boston.test <-Boston[-train,"medv"]

# Pruebo un Random Forest
set.seed(1)
bag.boston <- randomForest(medv~., data = Boston,
      subset = train, mtry = 8, importance = TRUE)
bag.boston

# Como predice en test en Random Forest
yhat.bag <- predict(bag.boston,newdata = Boston[-train, ])
plot(yhat.bag, boston.test)
abline(0, 1)
mean((yhat.bag - boston.test)^2)

#Podemos cambiar el n+umero de árboles usando el argumento mtry
set.seed (1)
rf.boston<-randomForest(medv~., data = Boston ,
          subset = train , mtry = 6, importance = TRUE )
yhat.rf <- predict(rf.boston, newdata = Boston [-train , ])
mean((yhat.rf- boston.test)^2)

#Vemos la importancia de cada variable
importance(rf.boston)

#Gráfico
varImpPlot(rf.boston)

Ejercicios.

  1. Utilice sus propios datos para aplicar alguno de estos métodos de aprendizaje supervisado y discuta con sus compañeros la mejor estrategia de análisis y sus resultados.