랜덤 포레스트 및 클래스 가중치


11

한 문장으로 질문 : 누군가 임의의 숲에 대해 좋은 학급 가중치를 결정하는 방법을 알고 있습니까?

설명 : 불균형 데이터 세트로 놀고 있습니다. 긍정적 인 예와 많은 부정적인 예만으로 매우 치우친 데이터 세트에서 모델을 훈련시키기 위해 R패키지 를 사용하고 싶습니다 randomForest. 나는 다른 방법이 있다는 것을 알고 결국에는 그것들을 사용할 것이지만 기술적 인 이유로 임의의 숲을 만드는 것은 중간 단계입니다. 그래서 나는 매개 변수로 놀았습니다 classwt. 반지름이 2 인 디스크에 5000 개의 음수 예제로 구성된 인공 데이터 세트를 설정 한 다음 반지름이 1 인 디스크에서 100 개의 양수 예제를 샘플링합니다.

1) 클래스 가중치를 적용하지 않으면 모델이 '퇴화'됩니다 (예 : FALSE모든 곳에서 예측) .

2) 공정한 클래스 가중치를 사용하면 중간에 '녹색 ​​점'이 표시됩니다. 즉, TRUE음의 예가 있더라도 반경 1의 디스크를 예측합니다 .

데이터는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

이 가중치없이 일어나는 것이다 : (호출은 다음과 같습니다 randomForest(x = train[, .(x,y)],y = as.factor(train$z),ntree = 50))

여기에 이미지 설명을 입력하십시오

확인을 위해 음수 클래스를 다운 샘플링하여 관계가 다시 1 : 1이되도록 데이터 세트의 격렬한 균형을 잡을 때 발생하는 상황도 시도했습니다. 이것은 나에게 예상 결과를 제공합니다.

여기에 이미지 설명을 입력하십시오

그러나 클래스 가중치가 'FALSE'= 1, 'TRUE'= 50 인 모델을 계산하면 (포지티브보다 50 배 더 많은 네거티브가 있으므로 공정한 가중치입니다) 다음을 얻습니다.

여기에 이미지 설명을 입력하십시오

가중치를 'FALSE'= 0.05 및 'TRUE'= 500000과 같은 이상한 값으로 설정하면 의미있는 결과를 얻습니다.

여기에 이미지 설명을 입력하십시오

그리고 이것은 매우 불안정합니다. 즉 'FALSE'가중치를 0.01로 변경하면 모델이 다시 퇴화됩니다 (즉, TRUE모든 곳에서 예측 ).

질문 : 임의의 숲에 대해 좋은 학급 가중치를 결정하는 방법을 알고 있습니까?

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")

sampsize가 작동하면 왜 사용하지 않습니까? 또한 다른 사람들처럼 sampsize 가이 문제를 해결하는 데 더 효과적이라는 것을 알았습니다. 또한 stats.stackexchange.com/questions/157714/…
katya

daply는 plyr에 있습니다.
EngrStudent

classwt 수업의 우선 순위. 하나를 더할 필요가 없습니다. 회귀를 무시했습니다.
Diego

@Diego :이 매개 변수는 매우 문제가있는 것 같습니다.이 매개 변수의 동작을 이해하지 못합니다 (질문의 설명 참조!) ...
Fabian Werner

답변:


2

하드 컷오프를 사용하여 하드 멤버십을 분류하지 말고, 어려운 멤버쉽 예측에 의존하는 KPI를 사용하지 마십시오. 대신을 사용하여 확률 적 예측을 수행하고 predict(..., type="prob")적절한 사용하여이를 평가하십시오 .

이 초기 스레드가 도움이되어야합니다. 분류 모델을 평가할 때 정확도가 왜 최상의 측정 방법이 아닌가? 놀랍게도, 나는 나의 대답나의 초기 대답 처럼 특히 도움이 될 것입니다 (부끄러움에 대해 유감스럽게 생각합니다) .


1
이것이 오늘 말씀하신 주제입니다. 맞습니까? 나는 내 작품에서 이것을 찾을 것이다 :-)
Jonas Heidelberg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.