flowchart TD A[D] --> B[D1] A --> C[D2] A --> D[Dt-1] A --> E[Dt] B --> F[C1 ó R1] C --> G[C2 ó R2] D --> H[Ct-1 ó Rt-1] E --> I[Ct ó Rt] F --> J[C* ó R*] G --> J[C* ó R*] H --> J[C* ó R*] I --> J[C* ó R*] style A fill:#b6daf6
Métodos de consenso
Aprendizaje Supervisado vs Aprendizaje no supervisado.
La mayoría de problemas de aprendizaje estadístico pueden ser clasificados dos categorías: Aprendizaje Supervisado y Aprendizaje No Supervisado.
Aprendizaje supervisado.
Para cada observación de las variables predictoras \(x_i~;~i=1,..,n\) existe una variable respuesta \(y_i\). Se desea ajustar un modelo de datos que relacione la variable respuesta \(y_i\) con las variables predictoras.
Predicción: para futuras observaciones de individuos tratar de pronosticar con exactitud la respuesta.
Inferencia: comprender mejor la relación entre la respuesta y las predictoras.
Algunos ejemplos de métodos de solución de problemas asociados con aprendizaje supervisado:
- Regresión lineal
- Regresión polinómica.
- Regresión Ridge.
- Regresión Lasso.
- Regresión logística.
- Árboles de decisión.
- Máquinas de soporte vectorial.
- Random Forest.
- K-Nearest Neighbors (KNN).
- Naive Bayes. …
Aprendizaje no supervisado.
Para cada observación \(i=1,..., n\), se tiene un vector \(x_i\), sin embargo, no se tiene asociado una variable respuesta \(y_i\) que permita supervisar algún ajuste.
Cuando se utiliza aprendizaje no supervisado se puede tratar de entender las relaciones entre variables o las relaciones entre las observaciones. Una herramienta de aprendizaje estadístico que podemos utilizar en este contexto es el análisis de conglomerados, o clustering. El objetivo del análisis de conglomerados es determinar, a partir del análisis de x1, . , xn , si las observaciones pertenecen a grupos relativamente distintos. Por ejemplo, en un estudio de segmentación de mercado podríamos observar múltiples características (variables) de los clientes potenciales, como el código postal, los ingresos familiares y los hábitos de compra. Podríamos pensar que los clientes pertenecen a grupos diferentes, como los que gastan mucho o los que gastan poco. Si se dispusiera de información sobre los patrones de gasto de cada cliente, sería posible realizar un análisis supervisado. Sin embargo, esta información no está disponible, es decir, no sabemos si cada cliente potencial es un gran gastador o no. En este caso, podemos intentar agrupar a los clientes en función de las variables medidas, con el fin de identificar distintos grupos de clientes potenciales. La identificación de estos grupos puede ser interesante porque es posible que difieran en alguna propiedad de interés, como los hábitos de gasto. Algunos métodos de aprendizaje no supervisado:
- K-means
- Clustering jerárquico.
- Análisis de componentes principales.
- Análisis discriminante no supervizado. …
Problemas de regresión vs Problemas de clasificación
Las variables pueden ser clasificadas como cuantitativas o cualitativas. Las variables cuantitativas toman valores numéricos: edad, estatura, ingreso, precio de una materia prima, costo de una vivienda. En contraste, las variables cualitativas toman valores en una de \(k\) clases o categorías diferentes: estado civil, marca de producto comprado, tipo de diagnóstico de una enfermedad.
En análisis de datos suele referirse a los problemas con variables respuesta cuantitativas como problemas de regresión, mientras que, a los problemas con variable respuesta cualitativa se consideran problemas de clasificaicón
Métodos de consenso
Los árboles de decisión presentan una gran desventaja, poseen alta varianza. Lo anterior significa que, si dividimos la base de datos en dos partes, de manera aleatoria, y aplicamos un árbol de decisión a ambas mitades, los resultados que se van a obtener son posiblemente muy diferentes. Por otro lado, si tuviéramos un procedimiento o técnica con baja varianza los resultados producidos serías similares si se aplica repetidamente a un conjunto de datos distinto.
Bootstrap aggregation, Bagging, o métodos de consenso es una técnica cuyo propósito general consiste en disminuir la varianza en un método de aprendizaje estadístico. Los métodos de consenso son usualmente utilizados en el contexto de árboles de decisión.
La idea es tomar \(m\) muestras aleatorias con reemplazo (BOOSTRAPS) de los datos originales y luego aplicas a cada una de ellas un método predictivo, para luego, con algún criterio estableces un consenso de todos los resultados.
El consenso podría ser un promedio, un promedio ponderado básado en cuál método se obtuvo un mejor resultado.
El consenso más usado es el que obtenga mayor cantidad de votos
Funcionamiento del método de consenso.
El funcionamiento gráfico del método se observa en la Figura 1
\(D\) corresponde a la base de datos para entrenamiento original.
\(D1, D2, D_{t-1}, D_{t}\) corresponden a los múltiples conjuntos de datos creados de manera aleatoria con reemplazo.
\(C1, C2, C_{t-1}, C_{t}\) corresponden a los modelos de clasificación o regresión usado para cada conjunto de dato \(D\).
\(C^*, R^*\) representan el consenso para el pronóstico ya sea para el clasificador o el regresor.
Una ventaja adicional del bagging es que permite estimar el error de la predicción de forma directa, sin necesidad de utilizar una muestra de test o de aplicar validación cruzada u, otra vez, remuestreo, y se obtiene un resultado similar al que obtendríamos con estos métodos. Es bien sabido que una muestra bootstrap va a contener muchas observaciones repetidas y que, en promedio, solo utiliza aproximadamente dos tercios de los datos (para ser más precisos, \(1-(1-\frac{1}{n})^n\) que, a medida que el tamaño del conjunto de datos de entrenamiento aumenta, es aproximadamente \(1-e^{-1} = 0.6321\)). Un dato que no es utilizado para construir un árbol se denomina un dato out-of-bag (OOB). De este modo, para cada observación se pueden utilizar los árboles para los que esa observación es out-of-bag (aproximadamente una tercera parte de los árboles construidos) para generar una única predicción para ella. Repitiendo el proceso para todas las observaciones se obtiene una medida del error.
Una decisión que hay que adoptar es cuántas muestras bootstrap se toman (o lo que es lo mismo, cuántos árboles se construyen). En la práctica, es habitual realizar un estudio gráfico de la convergencia del error OOB a medida que se incrementa el número de árboles. Si aparentemente hay convergencia con unos pocos cientos de árboles, no va a variar mucho el nivel de error al aumentar el número de remuestras. Por tanto, aumentar mucho el número de árboles no mejora las predicciones, aunque tampoco aumenta el riesgo de sobreajuste. Los costes computacionales aumentan con el número de árboles, pero la construcción y evaluación del modelo son fácilmente paralelizables (aunque pueden llegar a requerir mucha memoria si el conjunto de datos es muy grande). Por otra parte, si el número de árboles es demasiado pequeño puede que se obtengan pocas (o incluso ninguna) predicciones OOB para alguna de las observaciones de la muestra de entrenamiento.
Bagging para árboles de deciciones de clasificación enR
usando la librería ramdonForest
Usaremos una base de datos que contiene la siguiente información fisico-química y de calidad:
fixed.acidity: acidez fija.
volatile.acidity:acidez volátil.
Citric.acid: ácido cítrico.
residual.sugar: azúcar residual.
chlorides: cloruros.
free.sulfur.dioxide : dióxido de azufre libre.
total.sulfur.dioxide: dióxido de azufre total.
density: densidad,
pH: PH.
sulphates: sulfatos
alcohol: alcohol)
taste: sabor, que indica la calidad del vino (se considera bueno si la mediana de las evaluaciones de la calidad del vino, realizadas por expertos, que los evaluaron entre 0 = muy malo y 10 = muy excelente, no es inferior a 6. Factor con niveles «bueno» y «malo» que indican la calidad del vino.
Librerías
library(randomForest) #Para bagging
library(mpae) #Contiene la base de datos que se utilizará como ejemplo
library(caret) #Matriz de confusión
library(pROC) #Curva ROC y AUC
Creación del data.frame
a partir de la base de datos winetaste
de mpae
<- winetaste datos
Limpieza básica de datos N/A
<- na.omit(datos) datos
Definición de la base de datos en entrenamiento y prueba
set.seed(1) #Semilla para replicabilidad del ejemplo
<- nrow(datos)
numero_obs <- sample(numero_obs, 0.8*numero_obs, replace=FALSE)
base_entrenamiento<- datos[base_entrenamiento,]
datos_entrenamiento <- datos[-base_entrenamiento,] datos_prueba
Planteamiento del modelo
set.seed(4) #Semilla para replicabilidad del ejemplo
<- randomForest(taste~., data=datos_entrenamiento, mtry = ncol(datos_entrenamiento) - 1)
bagging bagging
Call: randomForest(formula = taste ~ ., data = datos_entrenamiento, mtry = ncol(datos_entrenamiento) - 1) Type of random forest: classification Number of trees: 500 No. of variables tried at each split: 11
OOB estimate of error rate: 23.5%
Confusion matrix: good bad class.error good 565 97 0.1465257 bad 138 200 0.4082840
Evaluación del modelo con matriz de confusión
<- predict(bagging, newdata=datos_prueba)
prediccion <- confusionMatrix(data = prediccion, reference = datos_prueba$taste)
matriz_confusion matriz_confusion
Confusion Matrix and Statistics
Reference
Prediction good bad good 145 42 bad 21 42
Accuracy : 0.748
95% CI : (0.6894, 0.8006)
No Information Rate : 0.664
P-Value [Acc > NIR] : 0.002535
Kappa : 0.3981
Mcnemar’s Test P-Value : 0.011743
Sensitivity : 0.8735
Specificity : 0.5000
Pos Pred Value : 0.7754
Neg Pred Value : 0.6667
Prevalence : 0.6640
Detection Rate : 0.5800
Detection Prevalence : 0.7480
Balanced Accuracy : 0.6867
'Positive' Class : good
Para recordar
\[\begin{align} Accuracy = \frac{TP+TN}{TP+TN+FP+FN} \end{align}\]
\[\begin{align} Accuracy = \frac{145+42}{145+42+42+21} =0.748 \end{align}\]
\[\begin{align} Sensitivity = \frac{TP}{TP+FN} \end{align}\]
\[\begin{align} Sensitivity = \frac{145}{145+21} = 0.873494 \end{align}\]
\[\begin{align} Specificity = \frac{TN}{TN+FP} \end{align}\]
\[\begin{align} Specificity = \frac{42}{42+42} = 0.5 \end{align}\]
Evaluación del modelo con ROC
y AUC
#Predicción como probabilidades
<- predict(bagging,datos_prueba, type="prob")
prob_prediccion
#Probabilidad "Positiva" o "Buena"
<- prob_prediccion[, "good"]
prob_positiva
# Variable binaria con la clase "verdadera"
<- datos_prueba$taste
clase_verdadera
#Curva ROC
<- roc(clase_verdadera, prob_positiva)
curva_ROC plot(curva_ROC, main = "Curva ROC para el modelo Bagging")
#AUC
<- auc(curva_ROC)
valor_AUC print(valor_AUC)
Area under the curve: 0.8026
Se puede examinar la convergencia del error en las muestras OOB
plot(bagging, main = "")
legend("right", colnames(bagging$err.rate), lty = 1:5, col = 1:6)
Bagging para árboles de deciciones de regresión enR
usando la librería ramdonForest
Librerías
library(randomForest) #Para bagging
library(ISLR2) #Contiene la base de datos que se utilizará como ejemplo
library(tidyverse)
library(caret) #Matriz de confusión
Creación del data.frame
a partir de la base de datos winetaste
de mpae
<- Hitters datos
Limpieza básica de datos N/A
<- na.omit(datos) datos
Establecemos como factores las variables cualitativas.
$League <- as.factor(datos$League)
datos$Division <- as.factor(datos$Division)
datos$NewLeague <- as.factor(datos$NewLeague) datos
Definición de la base de datos en entrenamiento y prueba
set.seed(1) #Semilla para replicabilidad del ejemplo
<- nrow(datos)
numero_obs <- sample(numero_obs, 0.8*numero_obs, replace=FALSE)
base_entrenamiento<- datos[base_entrenamiento,]
datos_entrenamiento <- datos[-base_entrenamiento,] datos_prueba
Planteamiento del modelo
set.seed(4) #Semilla para replicabilidad del ejemplo
<- randomForest(Salary~., data=datos_entrenamiento, mtry = ncol(datos_entrenamiento) - 1)
bagging bagging
Call: randomForest(formula = Salary ~ ., data = datos_entrenamiento, mtry = ncol(datos_entrenamiento) - 1) Type of random forest: regression Number of trees: 500 No. of variables tried at each split: 19
Mean of squared residuals: 75677.13
% Var explained: 60.67
Evaluación del modelo
<- predict(bagging, newdata = datos_prueba)
predicciones <- mean((predicciones - datos_prueba$Salary)^2)
mse print(mse)
[1] 105794.2
<- sqrt(mse)
rmse print(rmse)
[1] 325.2602
Análisis de la convergencia
plot(bagging, main = "")
Random Forest
Los bosques aleatorios (random forest) son una variante de bagging específicamente diseñados para trabajar con árboles de decisión. Las muestras bootstrap que se generan al hacer bagging introducen un elemento de aleatoriedad que en la práctica provoca que todos los árboles sean distintos, pero en ocasiones no son lo suficientemente distintos. Es decir, suele ocurrir que los árboles tengan estructuras muy similares, especialmente en la parte alta, aunque después se vayan diferenciando según se desciende por ellos. Esta característica se conoce como correlación entre árboles y se da cuando el árbol es un modelo adecuado para describir la relación entre los predictores y la respuesta, y también cuando uno de los predictores es muy fuerte, es decir, es especialmente relevante, con lo cual casi siempre va a estar en el primer corte. Esta correlación entre árboles se va a traducir en una correlación entre sus predicciones (más formalmente, entre los predictores).
Promediar variables altamente correlacionados produce una reducción de la varianza mucho menor que si promediamos variables incorrelacionadas. La solución pasa por añadir aleatoriedad al proceso de construcción de los árboles, para que estos dejen de estar correlacionados. En la construcción de cada uno de los árboles que finalmente constituirán el bosque, se van haciendo cortes binarios, y para cada corte hay que seleccionar una variable predictora. La modificación introducida fue que antes de hacer cada uno de los cortes, de todas las
\(p\) variables predictoras, se seleccionan al azar \(m<p\) predictores que van a ser los candidatos para el corte.
El hiperparámetro de los bosques aleatorios es \(m\). Como puntos de partida razonables se pueden considerar \(m= \sqrt{p}\) para problemas de clasificación) y $m= para los problemas de regresión. El número de árboles que van a constituir el bosque también puede tratarse como un hiperparámetro, aunque es más frecuente tratarlo como un problema de convergencia. En general, van a hacer falta más árboles que en bagging. En ocasiones, también se trata como hiperparámetro la selección del tamaño mínimo de los nodos terminales de los árboles.
Los bosques aleatorios son computacionalmente más eficientes que el bagging porque, aunque como acabamos de decir requieren más árboles, la construcción de cada árbol es mucho más rápida al evaluarse solo unos pocos predictores en cada corte.
Random Forest para árboles de deciciones de clasificación enR
usando la librería ramdonForest
Librerías
library(randomForest) #Para bagging
library(mpae) #Contiene la base de datos que se utilizará como ejemplo
library(caret) #Matriz de confusión
library(pROC) #Curva ROC y AUC
Creación del data.frame
a partir de la base de datos winetaste
de mpae
<- winetaste datos
Limpieza básica de datos N/A
<- na.omit(datos) datos
Definición de la base de datos en entrenamiento y prueba
set.seed(1) #Semilla para replicabilidad del ejemplo
<- nrow(datos)
numero_obs <- sample(numero_obs, 0.8*numero_obs, replace=FALSE)
base_entrenamiento<- datos[base_entrenamiento,]
datos_entrenamiento <- datos[-base_entrenamiento,] datos_prueba
Planteamiento del modelo
set.seed(1) #Semilla para replicabilidad del ejemplo
<- randomForest(taste~., data=datos_entrenamiento)
random_forest random_forest
Call: randomForest(formula = taste ~ ., data = datos_entrenamiento) Type of random forest: classification Number of trees: 500 No. of variables tried at each split: 3
OOB estimate of error rate: 22%
Confusion matrix: good bad class.error good 578 84 0.1268882 bad 136 202 0.4023669
Evaluación del modelo con matriz de confusión
<- predict(random_forest, newdata=datos_prueba)
prediccion <- confusionMatrix(data = prediccion, reference = datos_prueba$taste)
matriz_confusion matriz_confusion
Confusion Matrix and Statistics
Reference
Prediction good bad good 153 43 bad 13 41
Accuracy : 0.776
95% CI : (0.7192, 0.8261)
No Information Rate : 0.664
P-Value [Acc > NIR] : 7.227e-05
Kappa : 0.4494
Mcnemar’s Test P-Value : 0.0001065
Sensitivity : 0.9217
Specificity : 0.4881
Pos Pred Value : 0.7806
Neg Pred Value : 0.7593
Prevalence : 0.6640
Detection Rate : 0.6120
Detection Prevalence : 0.7840
Balanced Accuracy : 0.7049
'Positive' Class : good
Evaluación del modelo con ROC
y AUC
#Predicción como probabilidades
<- predict(random_forest,datos_prueba, type="prob")
prob_prediccion
#Probabilidad "Positiva" o "Buena"
<- prob_prediccion[, "good"]
prob_positiva
# Variable binaria con la clase "verdadera"
<- datos_prueba$taste
clase_verdadera
#Curva ROC
<- roc(clase_verdadera, prob_positiva)
curva_ROC plot(curva_ROC, main = "Curva ROC para el modelo Bagging")
#AUC
<- auc(curva_ROC)
valor_AUC print(valor_AUC)
Area under the curve: 0.8159
Se puede examinar la convergencia del error en las muestras OOB
plot(random_forest, main = "")
legend("right", colnames(random_forest$err.rate), lty = 1:5, col = 1:6)
Podemos mostrar la importancia de las variables predictoras (utilizadas en el bosque aleatorio y sus sustitutas) con la función importance()
o representarlas con varImpPlot()
importance(random_forest)
MeanDecreaseGini
fixed.acidity 37.77155 volatile.acidity 43.99769 citric.acid 41.50069 residual.sugar 36.79932 chlorides 33.62100 free.sulfur.dioxide 42.29122 total.sulfur.dioxide 39.63738 density 45.38724 pH 32.31442 sulphates 30.32322 alcohol 63.89185
Se puede graficar la importancia de las variables regresoras usando la sentencia varImpPlot()
varImpPlot(random_forest)
Random Forest para árboles de deciciones de regresión enR
usando la librería ramdonForest
Librerías
library(randomForest) #Para bagging
library(ISLR2) #Contiene la base de datos que se utilizará como ejemplo
library(tidyverse)
library(caret) #Matriz de confusión
Creación del data.frame
a partir de la base de datos winetaste
de mpae
<- Hitters datos
Limpieza básica de datos N/A
<- na.omit(datos) datos
Establecemos como factores las variables cualitativas.
$League <- as.factor(datos$League)
datos$Division <- as.factor(datos$Division)
datos$NewLeague <- as.factor(datos$NewLeague) datos
Definición de la base de datos en entrenamiento y prueba
set.seed(1) #Semilla para replicabilidad del ejemplo
<- nrow(datos)
numero_obs <- sample(numero_obs, 0.8*numero_obs, replace=FALSE)
base_entrenamiento<- datos[base_entrenamiento,]
datos_entrenamiento <- datos[-base_entrenamiento,] datos_prueba
Planteamiento del modelo
set.seed(4) #Semilla para replicabilidad del ejemplo
<- randomForest(Salary~., data=datos_entrenamiento)
random_forest random_forest
Call: randomForest(formula = Salary ~ ., data = datos_entrenamiento) Type of random forest: regression Number of trees: 500 No. of variables tried at each split: 6
Mean of squared residuals: 75557.1
% Var explained: 60.73
Evaluación del modelo
<- predict(random_forest, newdata = datos_prueba)
predicciones <- mean((predicciones - datos_prueba$Salary)^2)
mse print(mse)
[1] 97867.42
<- sqrt(mse)
rmse print(rmse)
[1] 312.8377
Análisis de la convergencia
plot(random_forest, main = "")
Podemos mostrar la importancia de las variables predictoras (utilizadas en el bosque aleatorio y sus sustitutas) con la función importance()
o representarlas con varImpPlot()
importance(random_forest)
IncNodePurity
AtBat 1750397.77 Hits 2335167.30 HmRun 1385377.74 Runs 2130302.32 RBI 2421192.53 Walks 2833417.29 Years 762955.96 CAtBat 4309096.75 CHits 4625552.04 CHmRun 1916508.10 CRuns 4040930.22 CRBI 4812676.58 CWalks 2041337.78 League 88378.86 Division 221348.16 PutOuts 2933455.42 Assists 573884.60 Errors 390749.88 NewLeague 68637.34
Se puede graficar la importancia de las variables regresoras usando la sentencia varImpPlot()
varImpPlot(random_forest)
Argumentos interés de randomForest
formula
y data
(opcional): permiten especificar la respuesta y las variables predictoras de la forma habitual (típicamente respuesta ~ .), aunque si el conjunto de datos es muy grande puede ser preferible emplear una matriz o un data.frame para establecer los predictores y un vector para la respuesta (sustituyendo estos argumentos por x e y). Si la variable respuesta es un factor asumirá que se trata de un problema de clasificación, y en caso contrario de regresión.
ntree
: número de árboles; por defecto \(500\).
mtry
: número de predictores seleccionados al azar en cada división; por defecto max(floor(p/3), 1)
en el caso de regresión y floor(sqrt(p))
en clasificación, siendo p = ncol(x) = ncol(data) - 1
el número de predictores.
nodesize
: número mínimo de observaciones en un nodo terminal; por defecto 1 en clasificación y 5 en regresión. Si el conjunto de datos es muy grande, es recomendable incrementarlo para evitar problemas de sobreajuste, disminuir el tiempo de computación y los requerimientos de memoria. Puede ser tratado como un hiperparámetro.
Otros argumentos que pueden ser de interés son:
maxnodes
: número máximo de nodos terminales. Puede utilizarse como alternativa para controlar la complejidad del modelo.
importance = TRUE
: permite obtener medidas adicionales de la importancia de las variables predictoras.
proximity = TRUE
: permite obtener una matriz de proximidades (componente proximity) entre las observaciones (frecuencia con la que los pares de observaciones están en el mismo nodo terminal).
na.action = na.fail
: por defecto, no admite datos faltantes con la interfaz de fórmulas. Si los hubiese, se podrían imputar estableciendo na.action = na.roughfix
(empleando medias o modas) o llamando previamente a rfImpute()
(que emplea proximidades obtenidas con un bosque aleatorio).