RandomForest और वर्ग वजन


11

एक वाक्य में प्रश्न: क्या कोई जानता है कि एक यादृच्छिक जंगल के लिए अच्छे वर्ग के वज़न का निर्धारण कैसे किया जाता है?

स्पष्टीकरण: मैं असंतुलित डेटासेट के साथ खेल रहा हूँ। मैं बहुत कम सकारात्मक उदाहरण और कई नकारात्मक उदाहरणों के साथ एक बहुत तिरछे डेटासेट पर एक मॉडल को प्रशिक्षित करने के लिए Rपैकेज का उपयोग करना चाहता हूं randomForest। मुझे पता है, अन्य विधियां हैं और अंत में मैं उनका उपयोग करूंगा लेकिन तकनीकी कारणों से, एक यादृच्छिक जंगल का निर्माण एक मध्यवर्ती कदम है। इसलिए मैंने पैरामीटर के साथ खेला classwt। मैं त्रिज्या 2 के साथ डिस्क में 5000 नकारात्मक उदाहरणों का एक बहुत ही कृत्रिम डेटासेट स्थापित कर रहा हूं और फिर मैं त्रिज्या के साथ डिस्क में 100 सकारात्मक उदाहरणों का नमूना लेता हूं। मुझे संदेह है कि क्या है

1) मॉडल को भारित किए बिना कक्षा 'पतित' हो जाती है, यानी FALSEहर जगह भविष्यवाणी होती है।

2) एक उचित वर्ग भार के साथ मैं बीच में एक 'ग्रीन डॉट' देखूंगा, अर्थात यह त्रिज्या 1 के साथ डिस्क की भविष्यवाणी करेगा, TRUEहालांकि नकारात्मक उदाहरण हैं।

यह डेटा जैसा दिखता है:

यहाँ छवि विवरण दर्ज करें

(कॉल है: यह वही है भार के बिना होता है 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हर जगह भविष्यवाणी करता है)।

प्रश्न: क्या कोई जानता है कि एक यादृच्छिक जंगल के लिए अच्छे वर्ग के वज़न का निर्धारण कैसे किया जाता है?

आर कोड:

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

यदि नमूना काम करता है तो उसका उपयोग क्यों नहीं किया जाता है? मुझे यह भी पता चला कि इसे हल करने के लिए बेहतर काम करता है, जैसा कि दूसरों ने किया। साथ ही यहां एक शानदार उत्तर देखें। सांख्यिकी ।stackexchange.com
katya

daply plyr में है, आपको इसे कॉल करना चाहिए।
EngrStudent

कक्षाओं के वर्गवाचक पुरोहित। एक को जोड़ने की आवश्यकता नहीं है। प्रतिगमन के लिए नजरअंदाज कर दिया।
डिएगो

@ डिगो: यह पैरामीटर बहुत समस्याग्रस्त लगता है, मुझे समझ नहीं आता कि यह पैरामीटर कैसे व्यवहार करता है (प्रश्न में टिप्पणी देखें!) ...
फेबियन वर्नर

जवाबों:


2

एक हार्ड सदस्यता को वर्गीकृत करने के लिए एक हार्ड कटऑफ का उपयोग न करें, और KPI का उपयोग न करें जो इस तरह की हार्ड सदस्यता भविष्यवाणी पर निर्भर करता है। इसके बजाय, predict(..., type="prob")उचित का उपयोग करके , एक संभाव्य भविष्यवाणी के साथ काम करें , और इनका आकलन करें ।

यह पहले धागा सहायक होना चाहिए: वर्गीकरण मॉडल का आकलन करने के लिए सटीकता सबसे अच्छा उपाय क्यों नहीं है? अप्रत्याशित रूप से पर्याप्त है, मेरा मानना ​​है कि मेरा उत्तर विशेष रूप से मददगार होगा (बेशर्मी के लिए खेद है), जैसा कि मेरा पहले का जवाब होगा ।


1
यह वह विषय है जिसके बारे में आपने आज बात की है, है ना? मैं अपने काम में इसके लिए बाहर
जोनास हीडलबर्ग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.