Un bosque aleatorio ejecutado correctamente aplicado a un problema que es más "apropiado para el bosque aleatorio" puede funcionar como un filtro para eliminar el ruido y generar resultados que son más útiles como entradas para otras herramientas de análisis.
Descargos de responsabilidad:
- ¿Es una "bala de plata"? De ninguna manera. El kilometraje variará. Funciona donde funciona, y no en otro lugar.
- ¿Hay formas en que puede usarlo groseramente de manera incorrecta y obtener respuestas que están en el dominio de basura a vudú? puedes apostar. Como toda herramienta analítica, tiene límites.
- Si lames una rana, ¿tu aliento huele a rana? probable. No tengo experiencia allí.
Tengo que dar un "grito" a mis "píos" que hicieron "Spider". ( enlace ) Su problema de ejemplo informó mi enfoque. ( enlace ) También me encantan los estimadores de Theil-Sen, y desearía poder darle accesorios a Theil y Sen.
Mi respuesta no se trata de cómo hacerlo mal, sino de cómo podría funcionar si lo hicieras bien. Si bien uso el ruido "trivial", quiero que piense en el ruido "no trivial" o "estructurado".
Una de las fortalezas de un bosque aleatorio es qué tan bien se aplica a los problemas de alta dimensión. No puedo mostrar 20k columnas (también conocido como un espacio dimensional de 20k) de una manera visual limpia. No es una tarea fácil. Sin embargo, si tiene un problema de 20k dimensiones, un bosque aleatorio podría ser una buena herramienta cuando la mayoría de los demás caen de bruces sobre sus "caras".
Este es un ejemplo de eliminación de ruido de la señal utilizando un bosque aleatorio.
#housekeeping
rm(list=ls())
#library
library(randomForest)
#for reproducibility
set.seed(08012015)
#basic
n <- 1:2000
r <- 0.05*n +1
th <- n*(4*pi)/max(n)
#polar to cartesian
x1=r*cos(th)
y1=r*sin(th)
#add noise
x2 <- x1+0.1*r*runif(min = -1,max = 1,n=length(n))
y2 <- y1+0.1*r*runif(min = -1,max = 1,n=length(n))
#append salt and pepper
x3 <- runif(min = min(x2),max = max(x2),n=length(n)/2)
y3 <- runif(min = min(y2),max = max(y2),n=length(n)/2)
x4 <- c(x2,x3)
y4 <- c(y2,y3)
z4 <- as.vector(matrix(1,nrow=length(x4)))
#plot class "A" derivation
plot(x1,y1,pch=18,type="l",col="Red", lwd=2)
points(x2,y2)
points(x3,y3,pch=18,col="Blue")
legend(x = 65,y=65,legend = c("true","sampled","false"),
col = c("Red","Black","Blue"),lty = c(1,-1,-1),pch=c(-1,1,18))
Permítanme describir lo que está pasando aquí. La siguiente imagen muestra datos de entrenamiento para la clase "1". La clase "2" es aleatoria uniforme sobre el mismo dominio y rango. Puede ver que la "información" de "1" es principalmente una espiral, pero se ha corrompido con material de "2". Tener el 33% de sus datos corruptos puede ser un problema para muchas herramientas de adaptación. Theil-Sen comienza a degradarse en aproximadamente un 29%. ( enlace )
Ahora separamos la información, solo teniendo una idea de qué es el ruido.
#Create "B" class of uniform noise
x5 <- runif(min = min(x4),max = max(x4),n=length(x4))
y5 <- runif(min = min(y4),max = max(y4),n=length(x4))
z5 <- 2*z4
#assemble data into frame
data <- data.frame(c(x4,x5),c(y4,y5),as.factor(c(z4,z5)))
names(data) <- c("x","y","z")
#train random forest - I like h2o, but this is textbook Breimann
fit.rf <- randomForest(z~.,data=data,
ntree = 1000, replace=TRUE, nodesize = 20)
data2 <- predict(fit.rf,newdata=data[data$z==1,c(1,2)],type="response")
#separate class "1" from training data
idx1a <- which(data[,3]==1)
#separate class "1" from the predicted data
idx1b <- which(data2==1)
#show the difference in classes before and after RF based filter
plot(data[idx1a,1],data[idx1a,2])
points(data[idx1b,1],data[idx1b,2],col="Red")
Aquí está el resultado apropiado:
Realmente me gusta esto porque puede mostrar tanto las fortalezas como las debilidades de un método decente a un problema difícil al mismo tiempo. Si mira cerca del centro, puede ver cómo hay menos filtrado. La escala geométrica de información es pequeña y al bosque aleatorio le falta eso. Dice algo sobre el número de nodos, el número de árboles y la densidad de la muestra para la clase 2. También hay un "espacio" cercano (-50, -50) y "chorros" en varios lugares. En general, sin embargo, el filtrado es decente.
Comparar vs SVM
Aquí está el código para permitir una comparación con SVM:
#now to fit to svm
fit.svm <- svm(z~., data=data, kernel="radial",gamma=10,type = "C")
x5 <- seq(from=min(x2),to=max(x2),by=1)
y5 <- seq(from=min(y2),to=max(y2),by=1)
count <- 1
x6 <- numeric()
y6 <- numeric()
for (i in 1:length(x5)){
for (j in 1:length(y5)){
x6[count]<-x5[i]
y6[count]<-y5[j]
count <- count+1
}
}
data4 <- data.frame(x6,y6)
names(data4) <- c("x","y")
data4$z <- predict(fit.svm,newdata=data4)
idx4 <- which(data4$z==1,arr.ind=TRUE)
plot(data4[idx4,1],data4[idx4,2],col="Gray",pch=20)
points(data[idx1b,1],data[idx1b,2],col="Blue",pch=20)
lines(x1,y1,pch=18,col="Green", lwd=2)
grid()
legend(x = 65,y=65,
legend = c("true","from RF","From SVM"),
col = c("Green","Blue","Gray"),lty = c(1,-1,-1),pch=c(-1,20,15),pt.cex=c(1,1,2.25))
Resulta en la siguiente imagen.
Este es un SVM decente. El gris es el dominio asociado con la clase "1" por el SVM. Los puntos azules son las muestras asociadas con la clase "1" por el RF. El filtro basado en RF funciona de manera comparable a SVM sin una base impuesta explícitamente. Se puede ver que los "datos ajustados" cerca del centro de la espiral están mucho más "firmemente" resueltos por la RF. También hay "islas" hacia la "cola" donde el RF encuentra una asociación que el SVM no.
Estoy entretenido Sin tener antecedentes, hice una de las primeras cosas que también hizo un muy buen colaborador en el campo. El autor original utilizó "distribución de referencia" ( enlace , enlace ).
EDITAR:
Aplique FOREST aleatorio a este modelo: si
bien el usuario777 piensa que un CART es el elemento de un bosque aleatorio, la premisa del bosque aleatorio es la "agregación en conjunto de alumnos débiles". El CART es un aprendiz débil conocido pero no es nada remotamente cerca de un "conjunto". El "conjunto" aunque en un bosque aleatorio está destinado "en el límite de una gran cantidad de muestras". La respuesta del usuario777, en el diagrama de dispersión, utiliza al menos 500 muestras y eso dice algo sobre la legibilidad humana y los tamaños de muestra en este caso. El sistema visual humano (en sí mismo un conjunto de estudiantes) es un sorprendente sensor y procesador de datos y considera que ese valor es suficiente para facilitar el procesamiento.
Si tomamos incluso la configuración predeterminada en una herramienta de bosque aleatorio, podemos observar que el comportamiento del error de clasificación aumenta para los primeros árboles y no alcanza el nivel de un árbol hasta que haya alrededor de 10 árboles. Inicialmente el error crece, la reducción del error se vuelve estable alrededor de 60 árboles. Por estable quiero decir
x <- cbind(x1, x2)
plot(rf,type="b",ylim=c(0,0.06))
grid()
Cuyos rendimientos:
Si en lugar de mirar al "alumno débil mínimo" miramos el "conjunto mínimo débil" sugerido por una heurística muy breve para la configuración predeterminada de la herramienta, los resultados son algo diferentes.
Tenga en cuenta que usé "líneas" para dibujar el círculo que indica el borde sobre la aproximación. Puede ver que es imperfecto, pero mucho mejor que la calidad de un solo alumno.
El muestreo original tiene 88 muestras "interiores". Si se aumentan los tamaños de muestra (permitiendo que se aplique el conjunto), la calidad de la aproximación también mejora. El mismo número de alumnos con 20,000 muestras hace un ajuste increíblemente mejor.
La información de entrada de mucha mayor calidad también permite la evaluación del número apropiado de árboles. La inspección de la convergencia sugiere que 20 árboles es el número mínimo suficiente en este caso particular, para representar bien los datos.