Pesi casuali e di classe


11

Domanda in una frase: qualcuno sa come determinare pesi di buona classe per una foresta casuale?

Spiegazione: Sto giocando con set di dati non bilanciati. Voglio usare il Rpacchetto randomForestper formare un modello su un set di dati molto distorto con solo piccoli esempi positivi e molti esempi negativi. Lo so, ci sono altri metodi e alla fine li userò ma per motivi tecnici, la costruzione di una foresta casuale è un passaggio intermedio. Quindi ho giocato con il parametro classwt. Sto impostando un set di dati molto artificiale di 5000 esempi negativi nel disco con raggio 2 e quindi campiono 100 esempi positivi nel disco con raggio 1. Quello che sospetto è che

1) senza ponderazione di classe il modello diventa "degenerato", ovvero predice FALSEovunque.

2) con una ponderazione di classe discreta vedrò un 'punto verde' nel mezzo, cioè predirò il disco con raggio 1 come TRUEse ci fossero esempi negativi.

Ecco come appaiono i dati:

inserisci qui la descrizione dell'immagine

Questo è ciò che accade senza ponderazione: (chiamata è: randomForest(x = train[, .(x,y)],y = as.factor(train$z),ntree = 50))

inserisci qui la descrizione dell'immagine

Per verificare ho anche provato cosa succede quando bilanci violentemente il set di dati effettuando il downsampling della classe negativa in modo che la relazione sia di nuovo 1: 1. Questo mi dà il risultato atteso:

inserisci qui la descrizione dell'immagine

Tuttavia, quando calcolo un modello con una ponderazione di classe di 'FALSE' = 1, 'TRUE' = 50 (si tratta di una ponderazione corretta in quanto vi sono 50 volte più negativi che positivi) quindi ottengo questo:

inserisci qui la descrizione dell'immagine

Solo quando imposto i pesi su un valore strano come 'FALSO' = 0,05 e 'VERO' = 500000, ottengo risultati sensati:

inserisci qui la descrizione dell'immagine

E questo è abbastanza instabile, vale a dire cambiare il peso 'FALSO' a 0,01 fa degenerare di nuovo il modello (cioè predire TRUEovunque).

Domanda: qualcuno sa come determinare pesi di buona classe per una foresta casuale?

Codice R:

library(plot3D)
library(data.table)
library(randomForest)
set.seed(1234)
amountPos = 100
amountNeg = 5000

# positives
r = runif(amountPos, 0, 1)
phi = runif(amountPos, 0, 2*pi)
x = r*cos(phi)
y = r*sin(phi)
z = rep(T, length(x))
pos = data.table(x = x, y = y, z = z)

# negatives
r = runif(amountNeg, 0, 2)
phi = runif(amountNeg, 0, 2*pi)
x = r*cos(phi)
y = r*sin(phi)
z = rep(F, length(x))
neg = data.table(x = x, y = y, z = z)

train = rbind(pos, neg)

# draw train set, verify that everything looks ok
plot(train[z == F]$x, train[z == F]$y, col="red")
points(train[z == T]$x, train[z == T]$y, col="green")
# looks ok to me :-)

Color.interpolateColor = function(fromColor, toColor, amountColors = 50) {
  from_rgb = col2rgb(fromColor)
  to_rgb = col2rgb(toColor)

  from_r = from_rgb[1,1]
  from_g = from_rgb[2,1]
  from_b = from_rgb[3,1]

  to_r = to_rgb[1,1]
  to_g = to_rgb[2,1]
  to_b = to_rgb[3,1]

  r = seq(from_r, to_r, length.out = amountColors)
  g = seq(from_g, to_g, length.out = amountColors)
  b = seq(from_b, to_b, length.out = amountColors)

  return(rgb(r, g, b, maxColorValue = 255))
}
DataTable.crossJoin = function(X,Y) {
  stopifnot(is.data.table(X),is.data.table(Y))
  k = NULL
  X = X[, c(k=1, .SD)]
  setkey(X, k)
  Y = Y[, c(k=1, .SD)]
  setkey(Y, k)
  res = Y[X, allow.cartesian=TRUE][, k := NULL]
  X = X[, k := NULL]
  Y = Y[, k := NULL]
  return(res)
}

drawPredictionAreaSimple = function(model) {
  widthOfSquares = 0.1
  from = -2
  to = 2

  xTable = data.table(x = seq(from=from+widthOfSquares/2,to=to-widthOfSquares/2,by = widthOfSquares))
  yTable = data.table(y = seq(from=from+widthOfSquares/2,to=to-widthOfSquares/2,by = widthOfSquares))
  predictionTable = DataTable.crossJoin(xTable, yTable)
  pred = predict(model, predictionTable)
  res = rep(NA, length(pred))
  res[pred == "FALSE"] = 0
  res[pred == "TRUE"] = 1
  pred = res
  predictionTable = predictionTable[, PREDICTION := pred]
  #predictionTable = predictionTable[y == -1 & x == -1, PREDICTION := 0.99]
  col = Color.interpolateColor("red", "green")

  input = matrix(c(predictionTable$x, predictionTable$y), nrow = 2, byrow = T)
  m = daply(predictionTable, .(x, y), function(x) x$PREDICTION)
  image2D(z = m, x = sort(unique(predictionTable$x)), y = sort(unique(predictionTable$y)), col = col, zlim = c(0,1))
}


rfModel = randomForest(x = train[, .(x,y)],y = as.factor(train$z),ntree = 50)
rfModelBalanced = randomForest(x = train[, .(x,y)],y = as.factor(train$z),ntree = 50, classwt = c("FALSE" = 1, "TRUE" = 50))
rfModelBalancedWeird = randomForest(x = train[, .(x,y)],y = as.factor(train$z),ntree = 50, classwt = c("FALSE" = 0.05, "TRUE" = 500000))


drawPredictionAreaSimple(rfModel)
title("unbalanced")
drawPredictionAreaSimple(rfModelBalanced)
title("balanced with weights")
pos = train[z == T]
neg = train[z == F]
neg = neg[sample.int(neg[, .N], size = 100, replace = FALSE)]
trainSampled = rbind(pos, neg)
rfModelBalancedSampling = randomForest(x = trainSampled[, .(x,y)],y = as.factor(trainSampled$z),ntree = 50)
drawPredictionAreaSimple(rfModelBalancedSampling)
title("balanced with sampling")


drawPredictionAreaSimple(rfModelBalancedWeird)
title("balanced with weird weights")

se il sampsize funziona perché non usarlo? Ho anche scoperto che il sampsize funziona meglio per risolvere questo problema, così come altri. Si veda anche una grande risposta qui stats.stackexchange.com/questions/157714/...
Katya

daply è in plyr, dovresti chiamarlo così.
EngrStudent,

classwt Priori delle classi. Non è necessario aggiungere fino a uno. Ignorato per la regressione.
Diego,

@Diego: questo parametro sembra essere molto problematico, non capisco come si comporta questo parametro (vedi i commenti nella domanda!) ...
Fabian Werner

Risposte:


2

Non utilizzare un limite massimo per classificare un abbonamento rigido e non utilizzare KPI che dipendono da una previsione di abbonamento così difficile. Invece, lavora con una previsione probabilistica, usando predict(..., type="prob")e valutandoli usando le appropriate .

Questo thread precedente dovrebbe essere utile: perché l'accuratezza non è la misura migliore per valutare i modelli di classificazione? Abbastanza sorprendentemente, credo che la mia risposta sarebbe particolarmente utile (scusate per la spudoratezza), così come una mia precedente risposta .


1
questo è l'argomento di cui hai parlato oggi, giusto? Lo cercherò nel mio lavoro :-)
Jonas Heidelberg il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.