私は平凡なcコードインタープリターであることを告白しますが、この古いコードはユーザーフレンドリーではありません。そうは言っても、私はソースコードを調べてこれらの観察を行ったので、「rpartは文字通り、最初の最適な変数列を選択する」と確信することができました。列1と2は下位の分割を生成するため、この列はdata.frame / matrixのpetal.widthの前にあるため、petal.lengthは最初に分割変数になります。最後に、petal.withが最初に分割変数になるように列の順序を逆にすることでこれを示します。
Cソースファイルの「bsplit.c」のrpartのソースコードで、 38行目から引用します。
* test out the variables 1 at at time
me->primary = (pSplit) NULL;
for (i = 0; i < rp.nvar; i++) {
...したがって、i = 1からrp.nvarで始まるforループで反復すると、1つの変数ですべての分割をスキャンするために損失関数が呼び出されます。新しい分割の方が良い場合は更新されます。(これは、ユーザー定義の損失関数の場合もあります)
if (temp < best) {
best = temp;
where = i;
direction = lmean < rmean ? LEFT : RIGHT;
}
最後の行323では、変数による最良の分割の改善が計算されます...
*improve = total_ss - best
... bsplit.cに戻って、以前に見られたよりも大きい場合は改善がチェックされ、大きい場合にのみ更新されます。
if (improve > rp.iscale)
rp.iscale = improve; /* largest seen so far */
これに対する私の印象は、新しいブレークポイントがより良いスコアを持っている場合にのみ保存されるため、(可能なタイの)最初で最良のものが選択されるということです。これは、最初に見つかった最高のブレークポイントと最初に見つかった最高の変数の両方に関係します。ブレークポイントは、gini.cで単純に左から右にスキャンされていないようです。そのため、最初に見つかった結合ブレークポイントは、予測が難しい場合があります。ただし、変数は最初の列から最後の列までスキャンすることで非常に予測可能です。
この動作は、classTree.cで次のソリューションが使用されるrandomForest実装とは異なります。
/* Break ties at random: */
if (crit == critmax) {
if (unif_rand() < 1.0 / ntie) {
*bestSplit = j;
critmax = crit;
*splitVar = mvar;
}
ntie++;
}
最後に、petal.widthが最初に選択されるように、アイリスの列を反転してこの動作を確認します
library(rpart)
data(iris)
iris = iris[,5:1] #flip/flop", invert order of columns columns
obj = rpart(Species~.,data=iris)
print(obj) #now petal width is first split
1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)
2) Petal.Width< 0.8 50 0 setosa (1.00000000 0.00000000 0.00000000) *
3) Petal.Width>=0.8 100 50 versicolor (0.00000000 0.50000000 0.50000000)
6) Petal.Width< 1.75 54 5 versicolor (0.00000000 0.90740741 0.09259259) *
7) Petal.Width>=1.75 46 1 virginica (0.00000000 0.02173913 0.97826087) *
...そして再び元に戻す
iris = iris[,5:1] #flop/flip", revert order of columns columns
obj = rpart(Species~.,data=iris)
print(obj) #now petal length is first split
1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)
2) Petal.Length< 2.45 50 0 setosa (1.00000000 0.00000000 0.00000000) *
3) Petal.Length>=2.45 100 50 versicolor (0.00000000 0.50000000 0.50000000)
6) Petal.Width< 1.75 54 5 versicolor (0.00000000 0.90740741 0.09259259) *
7) Petal.Width>=1.75 46 1 virginica (0.00000000 0.02173913 0.97826087) *