2017-10-31 4 views
12

イベントレートが3%未満のデータセットがあります(クラス1の場合は約700レコード、クラス0の場合は27000レコード)。rpartの結果はルートですが、データには情報が表示されます

ID   V1 V2  V3 V5  V6 Target 
SDataID3 161 ONE  1 FOUR 0 0 
SDataID4 11 TWO  2 THREE 2 1 
SDataID5 32 TWO  2 FOUR 2 0 
SDataID7 13 ONE  1 THREE 2 0 
SDataID8 194 TWO  2 FOUR 0 0 
SDataID10 63 THREE 3 FOUR 0 1 
SDataID11 89 ONE  1 FOUR 0 0 
SDataID13 78 TWO  2 FOUR 0 0 
SDataID14 87 TWO  2 THREE 1 0 
SDataID15 81 ONE  1 THREE 0 0 
SDataID16 63 ONE  3 FOUR 0 0 
SDataID17 198 ONE  3 THREE 0 0 
SDataID18 9 TWO  3 THREE 0 0 
SDataID19 196 ONE  2 THREE 2 0 
SDataID20 189 TWO  2 ONE  1 0 
SDataID21 116 THREE 3 TWO  0 0 
SDataID24 104 ONE  1 FOUR 0 0 
SDataID25 5 ONE  2 ONE  3 0 
SDataID28 173 TWO  3 FOUR 0 0 
SDataID29 5 ONE  3 ONE  3 0 
SDataID31 87 ONE  3 FOUR 3 0 
SDataID32 5 ONE  2 THREE 1 0 
SDataID34 45 ONE  1 FOUR 0 0 
SDataID35 19 TWO  2 THREE 0 0 
SDataID37 133 TWO  2 FOUR 0 0 
SDataID38 8 ONE  1 THREE 0 0 
SDataID39 42 ONE  1 THREE 0 0 
SDataID43 45 ONE  1 THREE 1 0 
SDataID44 45 ONE  1 FOUR 0 0 
SDataID45 176 ONE  1 FOUR 0 0 
SDataID46 63 ONE  1 THREE 3 0 

私は決定木を使って分割を見つけようとしています。しかし、ツリーの結果は1つの根だけです。

> library(rpart) 
> tree <- rpart(Target ~ ., data=subset(train, select=c(-Record.ID)),method="class") 
> printcp(tree) 

Classification tree: 
rpart(formula = Target ~ ., data = subset(train, select = c(-Record.ID)), method = "class") 

Variables actually used in tree construction: 
character(0) 

Root node error: 749/18239 = 0.041066 

n= 18239 

    CP nsplit rel error xerror xstd 
1 0  0   1  0 0 

StackOverflowのリソースのほとんどを読んだ後、私は希望の決定木を与えた制御パラメータを緩めたり微調整したりしました。

> tree <- rpart(Target ~ ., data=subset(train, select=c(-Record.ID)),method="class" ,control =rpart.control(minsplit = 1,minbucket=2, cp=0.00002)) 
> printcp(tree) 

Classification tree: 
rpart(formula = Target ~ ., data = subset(train, select = c(-Record.ID)), 
    method = "class", control = rpart.control(minsplit = 1, minbucket = 2, 
     cp = 2e-05)) 

Variables actually used in tree construction: 
[1] V5   V2      V1   
[4] V3   V6 

Root node error: 749/18239 = 0.041066 

n= 18239 

      CP nsplit rel error xerror  xstd 
1 0.00024275  0 1.00000 1.0000 0.035781 
2 0.00019073  20 0.99466 1.0267 0.036235 
3 0.00016689  34 0.99199 1.0307 0.036302 
4 0.00014835  54 0.98798 1.0334 0.036347 
5 0.00002000  63 0.98665 1.0427 0.036504 

私はツリーを剪定して、単一のノードを持つツリーを作成しました。数学的に、与えられたノード(例えば、提供)に、我々は情報のゲインを得ているので、

> pruned.tree <- prune(tree, cp = tree$cptable[which.min(tree$cptable[,"xerror"]),"CP"]) 
> printcp(pruned.tree) 

Classification tree: 
rpart(formula = Target ~ ., data = subset(train, select = c(-Record.ID)), 
    method = "class", control = rpart.control(minsplit = 1, minbucket = 2, 
     cp = 2e-05)) 

Variables actually used in tree construction: 
character(0) 

Root node error: 749/18239 = 0.041066 

n= 18239 

      CP nsplit rel error xerror  xstd 
1 0.00024275  0   1  1 0.035781 

ツリーはルートノードのみを配ってはいけません。私が間違えをしているのか、低いイベントレートのデータセットを扱う際にrpartに問題があるのか​​分かりません。

NODE p  1-p  Entropy   Weights   Ent*Weight  # Obs 
Node 1 0.032 0.968 0.204324671  0.351398601  0.071799404  10653 
Node 2 0.05 0.95 0.286396957  0.648601399  0.185757467  19663 

Sum(Ent*wght)  0.257556871 
Information gain 0.742443129 
+0

情報獲得を示す最終的な要約表をどのように取得しましたか? – useR

+0

Excelで手動で計算しました。 –

+0

申し訳ありませんが、私はあなたが何をしたいのか、rpartライブラリの使用の動機を理解できません。あなたはそれを記述できますか? – Alex

答えて

2

(データセクションを参照してください)あなたが提供されたデータは、2つのターゲットクラスの比率を反映していないので、私はより良いものを反映するために、データを微調整しました:

> prop.table(table(train$Target)) 

     0   1 
0.96707581 0.03292419 

> 700/27700 
[1] 0.02527076 

比率は今比較的近い...

library(rpart) 
tree <- rpart(Target ~ ., data=train, method="class") 
printcp(tree) 

結果で:

Classification tree: 
rpart(formula = Target ~ ., data = train, method = "class") 

Variables actually used in tree construction: 
character(0) 

Root node error: 912/27700 = 0.032924 

n= 27700 

    CP nsplit rel error xerror xstd 
1 0  0   1  0 0 

最初のモデルのルートノードだけが表示される理由は、ターゲットクラスが非常に不均衡であるため、独立変数がツリーを拡張するのに十分な情報を提供できなかったためです。私のサンプルデータは3.3%のイベントレートを持っていますが、あなたのデータは約2.5%しかありません!

上記のとおり、rpartにツリーを強制的に拡大する方法があります。これは、デフォルトの複雑さパラメータ(cp)を上書きすることです。複雑さの尺度は、ツリーのサイズと、ツリーがターゲットクラスをどれくらいよく分割するかの組み合わせです。 ?rpart.controlから"全体の不足をcpだけ減少させない分割は試みられません"。これは、現時点でのモデルでは、rpartが考慮に入れるほど複雑なレベルを下げるルートノードを超えて分割されていないことを意味します。 cp(負のcpは、基本的にツリーをフルサイズに拡大させる)を設定することで、「十分」とみなされるこのしきい値を緩和することができます。中

tree <- rpart(Target ~ ., data=train, method="class" ,parms = list(split = 'information'), 
       control =rpart.control(minsplit = 1,minbucket=2, cp=0.00002)) 
printcp(tree) 

結果:

Classification tree: 
rpart(formula = Target ~ ., data = train, method = "class", parms = list(split = "information"), 
    control = rpart.control(minsplit = 1, minbucket = 2, cp = 2e-05)) 

Variables actually used in tree construction: 
[1] ID V1 V2 V3 V5 V6 

Root node error: 912/27700 = 0.032924 

n= 27700 

      CP nsplit rel error xerror  xstd 
1 4.1118e-04  0 1.00000 1.0000 0.032564 
2 3.6550e-04  30 0.98355 1.0285 0.033009 
3 3.2489e-04  45 0.97807 1.0702 0.033647 
4 3.1328e-04 106 0.95504 1.0877 0.033911 
5 2.7412e-04 116 0.95175 1.1031 0.034141 
6 2.5304e-04 132 0.94737 1.1217 0.034417 
7 2.1930e-04 149 0.94298 1.1458 0.034771 
8 1.9936e-04 159 0.94079 1.1502 0.034835 
9 1.8275e-04 181 0.93640 1.1645 0.035041 
10 1.6447e-04 193 0.93421 1.1864 0.035356 
11 1.5664e-04 233 0.92654 1.1853 0.035341 
12 1.3706e-04 320 0.91228 1.2083 0.035668 
13 1.2183e-04 344 0.90899 1.2127 0.035730 
14 9.9681e-05 353 0.90789 1.2237 0.035885 
15 2.0000e-05 364 0.90680 1.2259 0.035915 

あなたが見ることができるように、ツリーがcpの最小によって複雑さのレベルを低下させる大きさに成長しました。注意すべき二つのこと:ゼロnsplit

  1. CPが既に0と低いです。0004では、のデフォルトのcpが0.01に設定されています。
  2. nsplit == 0から始まって、交差検証エラー(xerrorは、分割数を増やすとに増えます。

これらの両方は、あなたのモデルに複数の独立変数を追加すると、クロスバリデーション誤差を低減するのに十分な情報(CPが不足削減)を追加しませんので、あなたのモデルは、nsplit == 0で超えにデータを過剰適合していることを示しています。これが言われると、ルートノードモデルです。この場合は、最初のモデルにルートノードのみがある理由が説明されています。中

pruned.tree <- prune(tree, cp = tree$cptable[which.min(tree$cptable[,"xerror"]),"CP"]) 
printcp(pruned.tree) 

結果:剪定部分については

Classification tree: 
rpart(formula = Target ~ ., data = train, method = "class", parms = list(split = "information"), 
    control = rpart.control(minsplit = 1, minbucket = 2, cp = 2e-05)) 

Variables actually used in tree construction: 
character(0) 

Root node error: 912/27700 = 0.032924 

n= 27700 

      CP nsplit rel error xerror  xstd 
1 0.00041118  0   1  1 0.032564 

0の分割を超えたツリーは、クロス検証エラーが増加しているので、あなたの剪定ツリーは、ルートノードのツリーである理由、それは今明確です。ツリーを最小値のxerrorにすると、ルートノードツリーが予想どおりに残ります。

基本的に情報のゲインは、各分割にどれだけの情報が追加されたかを示します。つまり、には、モデルに変数を追加しているので、ある程度の情報が得られます(情報のゲインは常に負ではありません)。あなたが考えなければならないのは、追加の利得(または利得なし)が、より複雑なモデルを保証するのに十分な誤差を減らすかどうかということです。したがって、バイアスと分散との間のトレードオフ。

この場合、cpを減らして後で結果ツリーをプルーニングすることは実際には意味がありません。 cpを低く設定すると、rpartには過ぎても分割が行われますが、枝刈りはオーバーフィットするすべてのノードを「カット」します。

データ:私は行インデックスをサンプリングするのではなく、各カラムと試料の行をシャッフルしてい

注意。これは、提供したデータが元のデータセットの無作為抽出サンプルではないためです(つまり、偏りがある可能性があります)ので、私は基本的にランダムに新しい観測データを作成します。

init_train = structure(list(ID = structure(c(16L, 24L, 29L, 30L, 31L, 1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 
17L, 18L, 19L, 20L, 21L, 22L, 23L, 25L, 26L, 27L, 28L), .Label = c("SDataID10", 
"SDataID11", "SDataID13", "SDataID14", "SDataID15", "SDataID16", 
"SDataID17", "SDataID18", "SDataID19", "SDataID20", "SDataID21", 
"SDataID24", "SDataID25", "SDataID28", "SDataID29", "SDataID3", 
"SDataID31", "SDataID32", "SDataID34", "SDataID35", "SDataID37", 
"SDataID38", "SDataID39", "SDataID4", "SDataID43", "SDataID44", 
"SDataID45", "SDataID46", "SDataID5", "SDataID7", "SDataID8"), class = "factor"), 
    V1 = c(161L, 11L, 32L, 13L, 194L, 63L, 89L, 78L, 87L, 81L, 
    63L, 198L, 9L, 196L, 189L, 116L, 104L, 5L, 173L, 5L, 87L, 
    5L, 45L, 19L, 133L, 8L, 42L, 45L, 45L, 176L, 63L), V2 = structure(c(1L, 
    3L, 3L, 1L, 3L, 2L, 1L, 3L, 3L, 1L, 1L, 1L, 3L, 1L, 3L, 2L, 
    1L, 1L, 3L, 1L, 1L, 1L, 1L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L 
    ), .Label = c("ONE", "THREE", "TWO"), class = "factor"), 
    V3 = c(1L, 2L, 2L, 1L, 2L, 3L, 1L, 2L, 2L, 1L, 3L, 3L, 3L, 
    2L, 2L, 3L, 1L, 2L, 3L, 3L, 3L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 
    1L, 1L, 1L), V5 = structure(c(1L, 3L, 1L, 3L, 1L, 1L, 1L, 
    1L, 3L, 3L, 1L, 3L, 3L, 3L, 2L, 4L, 1L, 2L, 1L, 2L, 1L, 3L, 
    1L, 3L, 1L, 3L, 3L, 3L, 1L, 1L, 3L), .Label = c("FOUR", "ONE", 
    "THREE", "TWO"), class = "factor"), V6 = c(0L, 2L, 2L, 2L, 
    0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 2L, 1L, 0L, 0L, 3L, 0L, 
    3L, 3L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 3L), Target = c(0L, 
    1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L 
    )), .Names = c("ID", "V1", "V2", "V3", "V5", "V6", "Target" 
), class = "data.frame", row.names = c(NA, -31L)) 

set.seed(1000) 
train = as.data.frame(lapply(init_train, function(x) sample(x, 27700, replace = TRUE))) 
関連する問題