回答:
RFは非線形性を処理できますが、係数を提供できないため、ランダムフォレストを使用して最も重要な特徴を収集し、それらの特徴を多重線形回帰モデルにプラグインして説明するのが賢明でしょうか?
OPの1文の質問は、OPが次の分析パイプラインの望ましさを理解することを望んでいることを意味すると解釈します。
このパイプラインはあなたが望むものを達成するとは思わない。ランダムフォレストで重要な変数は、必ずしも結果と線形的に相加的な関係にあるとは限りません。この発言は驚くべきことではありません。それは、非線形の関係を発見する際にランダムフォレストを非常に効果的にするものです。
以下に例を示します。10個のノイズフィーチャ、2つの「信号」フィーチャ、および循環判定境界を持つ分類問題を作成しました。
set.seed(1)
N <- 500
x1 <- rnorm(N, sd=1.5)
x2 <- rnorm(N, sd=1.5)
y <- apply(cbind(x1, x2), 1, function(x) (x%*%x)<1)
plot(x1, x2, col=ifelse(y, "red", "blue"))
lines(cos(seq(0, 2*pi, len=1000)), sin(seq(0, 2*pi, len=1000)))
また、RFモデルを適用すると、これらの機能がモデルによって重要なものとして簡単に選択されることに驚くことはありません。(注:このモデルはまったく調整されていません。)
x_junk <- matrix(rnorm(N*10, sd=1.5), ncol=10)
x <- cbind(x1, x2, x_junk)
names(x) <- paste("V", 1:ncol(x), sep="")
rf <- randomForest(as.factor(y)~., data=x, mtry=4)
importance(rf)
MeanDecreaseGini
x1 49.762104
x2 54.980725
V3 5.715863
V4 5.010281
V5 4.193836
V6 7.147988
V7 5.897283
V8 5.338241
V9 5.338689
V10 5.198862
V11 4.731412
V12 5.221611
しかし、これらの2つの便利な機能だけをダウン選択すると、結果の線形モデルはひどくなります。
summary(badmodel <- glm(y~., data=data.frame(x1,x2), family="binomial"))
要約の重要な部分は、残留偏差とヌル偏差の比較です。モデルは、逸脱を「移動」するために基本的に何もしないことがわかります。さらに、係数の推定値は本質的にゼロです。
Call:
glm(formula = as.factor(y) ~ ., family = "binomial", data = data.frame(x1,
x2))
Deviance Residuals:
Min 1Q Median 3Q Max
-0.6914 -0.6710 -0.6600 -0.6481 1.8079
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.398378 0.112271 -12.455 <2e-16 ***
x1 -0.020090 0.076518 -0.263 0.793
x2 -0.004902 0.071711 -0.068 0.946
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 497.62 on 499 degrees of freedom
Residual deviance: 497.54 on 497 degrees of freedom
AIC: 503.54
Number of Fisher Scoring iterations: 4
2つのモデルの大きな違いを説明するものは何ですか?明らかに、学習しようとしている決定境界は、2つの「信号」機能の線形関数ではありません。回帰を推定する前に決定境界の関数形式を知っていれば、明らかに、回帰が発見できる方法でデータをエンコードするために何らかの変換を適用できます...この場合、2つの信号特徴(クラスラベルにノイズのない合成データセット)のみを使用しているため、プロット間のクラス間の境界は非常に明白です。ただし、現実的な数の次元で実際のデータを操作する場合は、それほど明確ではありません。
さらに、一般に、ランダムフォレストは異なるモデルをデータの異なるサブセットに適合させることができます。より複雑な例では、単一のプロットから何が起こっているのかはまったく明らかではなく、同様の予測力の線形モデルを構築するのはさらに難しくなります。
私たちは2つの次元のみに関心があるため、予測サーフェスを作成できます。予想どおり、ランダムモデルは、原点の周辺が重要であることを学習します。
M <- 100
x_new <- seq(-4,4, len=M)
x_new_grid <- expand.grid(x_new, x_new)
names(x_new_grid) <- c("x1", "x2")
x_pred <- data.frame(x_new_grid, matrix(nrow(x_new_grid)*10, ncol=10))
names(x_pred) <- names(x)
y_hat <- predict(object=rf, newdata=x_pred, "vote")[,2]
library(fields)
y_hat_mat <- as.matrix(unstack(data.frame(y_hat, x_new_grid), y_hat~x1))
image.plot(z=y_hat_mat, x=x_new, y=x_new, zlim=c(0,1), col=tim.colors(255),
main="RF Prediction surface", xlab="x1", ylab="x2")
深層モデルの出力が示すように、可変変数ロジスティック回帰モデルの予測曲面は基本的に平坦です。
bad_y_hat <- predict(object=badmodel, newdata=x_new_grid, type="response")
bad_y_hat_mat <- as.matrix(unstack(data.frame(bad_y_hat, x_new_grid), bad_y_hat~x1))
image.plot(z=bad_y_hat_mat, x=x_new, y=x_new, zlim=c(0,1), col=tim.colors(255),
main="Logistic regression prediction surface", xlab="x1", ylab="x2")
「ランダムフォレストに適した」問題に適切に実行されたランダムフォレストは、ノイズを除去するフィルターとして機能し、他の分析ツールへの入力としてより有用な結果を作成できます。
免責事項:
「スパイダー」を作った「のぞき見」に「叫ぶ」必要があります。(リンク)彼らの問題例が私のアプローチを知らせてくれました。(リンク)Theil-Senの推定量も大好きです。TheilとSenに小道具を渡すことができたらと思います。
私の答えは、それをどのように間違えるかということではなく、もしあなたが大部分が正しいとしたらどうなるかということです。私は「些細な」ノイズを使用しますが、「非些細な」または「構造化された」ノイズについて考えてほしいです。
ランダムフォレストの長所の1つは、高次元の問題にどれだけうまく適用できるかです。きれいな視覚的な方法で2万列(別名2万次元の空間)を表示することはできません。簡単な作業ではありません。ただし、20k次元の問題がある場合、他のほとんどの人が「顔」を平らにすると、ランダムフォレストが良いツールになる可能性があります。
これは、ランダムフォレストを使用して信号からノイズを除去する例です。
#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))
ここで何が起こっているのか説明しましょう。次の画像は、クラス「1」のトレーニングデータを示しています。クラス「2」は、同じドメインと範囲にわたって一様なランダムです。「1」の「情報」はほとんどがスパイラルですが、「2」の素材で破損していることがわかります。データの33%が破損していることは、多くのフィッティングツールにとって問題になる可能性があります。Theil-Senは約29%で劣化し始めます。(リンク)
ここで情報を分離し、ノイズとは何かを把握するだけです。
#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")
フィッティング結果は次のとおりです。
まともな方法の長所と短所の両方を同時に難しい問題に示すことができるので、私はこれが本当に好きです。中心付近を見ると、フィルタリングが少ないことがわかります。情報の幾何学的な規模は小さく、ランダムフォレストにはそれがありません。クラス2のノード数、ツリー数、およびサンプル密度に関する情報があります。また、(-50、-50)の近くに「ギャップ」があり、いくつかの場所に「ジェット」があります。ただし、一般に、フィルタリングは適切です。
比較とSVM
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))
次の画像が表示されます。
これはまともなSVMです。灰色は、SVMによってクラス「1」に関連付けられているドメインです。青い点は、RFによってクラス「1」に関連付けられているサンプルです。 RFベースのフィルターは、明示的に課された基礎なしでSVMと同等に機能します。 スパイラルの中心付近の「厳密なデータ」は、RFによって「厳密に」解決されることがわかります。また、RFがSVMにはない関連付けを見つける「テール」に向かう「島」もあります。
私は楽しまれています。背景がなくても、私は初期の仕事の1つを、この分野の非常に優れた貢献者によって行いました。元の著者は「参照分布」(link、link)を使用しました。
編集:
ランダムフォレストをこのモデルに適用する:
user777は、CARTがランダムフォレストの要素であるという良い考えを持っていますが、ランダムフォレストの前提は「弱い学習者のアンサンブル集約」です。CARTは既知の弱学習器ですが、「アンサンブル」の近くには何もありません。ランダムフォレスト内の「アンサンブル」は、「多数のサンプルの制限内」を意図しています。散布図のuser777の答えは、少なくとも500個のサンプルを使用しており、この場合の人間の可読性とサンプルサイズについて何かを述べています。人間の視覚システム(それ自体が学習者の集合体)は驚くべきセンサーとデータプロセッサであり、その値は処理を容易にするのに十分であることがわかります。
ランダムフォレストツールで既定の設定を使用する場合でも、最初のいくつかのツリーで分類エラーが増加し、約10本の木になるまで1ツリーレベルに到達しないという動作を観察できます。最初はエラーが大きくなり、エラーの減少は60本の木あたりで安定します。安定とは
x <- cbind(x1, x2)
plot(rf,type="b",ylim=c(0,0.06))
grid()
「最小弱学習器」ではなく、ツールのデフォルト設定の非常に短いヒューリスティックによって示唆される「最小弱学習器」を見ると、結果は多少異なります。
注:「線」を使用して、近似上のエッジを示す円を描画します。不完全であることがわかりますが、単一の学習者の質よりもはるかに優れています。
元のサンプリングには88個の「内部」サンプルがあります。サンプルサイズが増加すると(アンサンブルを適用できるようになる)、近似の品質も向上します。20,000サンプルの同じ数の学習者は、驚くほど優れた適合性を発揮します。
入力情報の品質がはるかに高いため、適切な数のツリーを評価することもできます。収束を調べると、この特定のケースでは、データを適切に表すために20本の木が十分な最小数であることが示唆されます。