R のデシジョン ツリー: 例を含む分類ツリー
ディシジョン ツリーとは何ですか?
決定木 は、分類と回帰の両方のタスクを実行できる多目的な機械学習アルゴリズムです。これらは非常に強力なアルゴリズムであり、複雑なデータセットに適合させることができます。さらに、決定木はランダムフォレストの基本コンポーネントであり、現在利用可能な最も強力な機械学習アルゴリズムの 1 つです。
R でのデシジョン ツリーのトレーニングと視覚化
R サンプルで最初のデシジョン ツリーを構築するには、このデシジョン ツリー チュートリアルで次のように進めます。
- ステップ 1: データをインポートする
- ステップ 2: データセットをクリーンアップする
- ステップ 3: トレーニング/テスト セットを作成する
- ステップ 4: モデルを構築する
- ステップ 5: 予測を立てる
- ステップ6:パフォーマンスを測定する
- ステップ 7: ハイパーパラメータを調整する
ステップ 1) データをインポートする
タイタニック号の運命に興味がある場合は、このビデオをご覧ください。 Youtube。 このデータセットの目的は、氷山との衝突後にどの人が生き残る可能性が高いかを予測することです。 データセットには 13 の変数と 1309 の観測値が含まれています。 データセットは変数 X によって順序付けされます。
set.seed(678) path <- 'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/titanic_data.csv' titanic <-read.csv(path) head(titanic)
出力:
## X pclass survived name sex ## 1 1 1 1 Allen, Miss. Elisabeth Walton female ## 2 2 1 1 Allison, Master. Hudson Trevor male ## 3 3 1 0 Allison, Miss. Helen Loraine female ## 4 4 1 0 Allison, Mr. Hudson Joshua Creighton male ## 5 5 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female ## 6 6 1 1 Anderson, Mr. Harry male ## age sibsp parch ticket fare cabin embarked ## 1 29.0000 0 0 24160 211.3375 B5 S ## 2 0.9167 1 2 113781 151.5500 C22 C26 S ## 3 2.0000 1 2 113781 151.5500 C22 C26 S ## 4 30.0000 1 2 113781 151.5500 C22 C26 S ## 5 25.0000 1 2 113781 151.5500 C22 C26 S ## 6 48.0000 0 0 19952 26.5500 E12 S ## home.dest ## 1 St Louis, MO ## 2 Montreal, PQ / Chesterville, ON ## 3 Montreal, PQ / Chesterville, ON ## 4 Montreal, PQ / Chesterville, ON ## 5 Montreal, PQ / Chesterville, ON ## 6 New York, NY
tail(titanic)
出力:
## X pclass survived name sex age sibsp ## 1304 1304 3 0 Yousseff, Mr. Gerious male NA 0 ## 1305 1305 3 0 Zabour, Miss. Hileni female 14.5 1 ## 1306 1306 3 0 Zabour, Miss. Thamine female NA 1 ## 1307 1307 3 0 Zakarian, Mr. Mapriededer male 26.5 0 ## 1308 1308 3 0 Zakarian, Mr. Ortin male 27.0 0 ## 1309 1309 3 0 Zimmerman, Mr. Leo male 29.0 0 ## parch ticket fare cabin embarked home.dest ## 1304 0 2627 14.4583 C ## 1305 0 2665 14.4542 C ## 1306 0 2665 14.4542 C ## 1307 0 2656 7.2250 C ## 1308 0 2670 7.2250 C ## 1309 0 315082 7.8750 S
先頭と末尾の出力から、データがシャッフルされていないことがわかります。 これは大きな問題です! データをトレイン セットとテスト セットに分割する場合、次を選択します。 の クラス 1 と 2 の乗客 (クラス 3 の乗客は観測結果の上位 80% に含まれていません)。これは、アルゴリズムがクラス 3 の乗客の特徴を決して認識しないことを意味します。この間違いにより、予測が不十分になります。
この問題を解決するには、sample() 関数を使用します。
shuffle_index <- sample(1:nrow(titanic)) head(shuffle_index)
決定木Rコード 説明
- sample(1:nrow(titanic)): 1 ~ 1309 (つまり、最大行数) のインデックスのランダムなリストを生成します。
出力:
## [1] 288 874 1078 633 887 992
このインデックスを使用して、タイタニック データセットをシャッフルします。
titanic <- titanic[shuffle_index, ] head(titanic)
出力:
## X pclass survived ## 288 288 1 0 ## 874 874 3 0 ## 1078 1078 3 1 ## 633 633 3 0 ## 887 887 3 1 ## 992 992 3 1 ## name sex age ## 288 Sutton, Mr. Frederick male 61 ## 874 Humblen, Mr. Adolf Mathias Nicolai Olsen male 42 ## 1078 O'Driscoll, Miss. Bridget female NA ## 633 Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren) female 39 ## 887 Jermyn, Miss. Annie female NA ## 992 Mamee, Mr. Hanna male NA ## sibsp parch ticket fare cabin embarked home.dest## 288 0 0 36963 32.3208 D50 S Haddenfield, NJ ## 874 0 0 348121 7.6500 F G63 S ## 1078 0 0 14311 7.7500 Q ## 633 1 5 347082 31.2750 S Sweden Winnipeg, MN ## 887 0 0 14313 7.7500 Q ## 992 0 0 2677 7.2292 C
ステップ 2) データセットをクリーンアップする
データの構造を見ると、いくつかの変数に NA があることがわかります。 データのクリーンアップは次のように実行します
- 変数 home.dest、cabin、name、X、ticket をドロップします
- pclass の因子変数を作成して生き残った
- NAをドロップする
library(dplyr) # Drop variables clean_titanic <- titanic % > % select(-c(home.dest, cabin, name, X, ticket)) % > % #Convert to factor level mutate(pclass = factor(pclass, levels = c(1, 2, 3), labels = c('Upper', 'Middle', 'Lower')), survived = factor(survived, levels = c(0, 1), labels = c('No', 'Yes'))) % > % na.omit() glimpse(clean_titanic)
コードの説明
- select(-c(home.dest, Cabinet, name, X, ticket)): 不要な変数を削除します
- pclass =actor(pclass,levels=c(1,2,3),label=c('Upper', 'Middle', 'Lower')): 変数 pclass にラベルを追加します。 1 が上、2 が中、3 が下になります
- 因子(生存、レベル = c(0,1)、ラベル = c('いいえ'、'はい')): 変数生存にラベルを追加します。 1 は「いいえ」になり、2 は「はい」になります。
- na.omit(): NA 観察を削除します。
出力:
## Observations: 1,045 ## Variables: 8 ## $ pclass <fctr> Upper, Lower, Lower, Upper, Middle, Upper, Middle, U... ## $ survived <fctr> No, No, No, Yes, No, Yes, Yes, No, No, No, No, No, Y... ## $ sex <fctr> male, male, female, female, male, male, female, male... ## $ age <dbl> 61.0, 42.0, 39.0, 49.0, 29.0, 37.0, 20.0, 54.0, 2.0, ... ## $ sibsp <int> 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 1, 1,... ## $ parch <int> 0, 0, 5, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 4, 0,... ## $ fare <dbl> 32.3208, 7.6500, 31.2750, 25.9292, 10.5000, 52.5542, ... ## $ embarked <fctr> S, S, S, S, S, S, S, S, S, C, S, S, S, Q, C, S, S, C...
ステップ 3) トレーニング/テスト セットを作成する
モデルをトレーニングする前に、次の XNUMX つの手順を実行する必要があります。
- トレーニング セットとテスト セットを作成する: トレーニング セットでモデルをトレーニングし、テスト セットで予測をテストします (つまり、未確認のデータ)。
- コンソールから rpart.plot をインストールします
一般的な方法は、データを 80/20 に分割し、データの 80 パーセントをモデルのトレーニングに使用し、20 パーセントを予測に使用することです。 XNUMX つの別々のデータ フレームを作成する必要があります。 モデルの構築が完了するまでは、テスト セットには触れたくないでしょう。 XNUMX つの引数を取る関数名 create_train_test() を作成できます。
create_train_test(df, size = 0.8, train = TRUE) arguments: -df: Dataset used to train the model. -size: Size of the split. By default, 0.8. Numerical value -train: If set to `TRUE`, the function creates the train set, otherwise the test set. Default value sets to `TRUE`. Boolean value.You need to add a Boolean parameter because R does not allow to return two data frames simultaneously.
create_train_test <- function(data, size = 0.8, train = TRUE) { n_row = nrow(data) total_row = size * n_row train_sample < - 1: total_row if (train == TRUE) { return (data[train_sample, ]) } else { return (data[-train_sample, ]) } }
コードの説明
- function(data, size=0.8, train = TRUE): 関数に引数を追加します
- n_row = nrow(data): データセット内の行数をカウントします。
- total_row = size*n_row: 列車セットを構築するために n 番目の行を返します。
- train_sample <- 1:total_row: XNUMX行目からn行目までを選択
- if (train ==TRUE){ } else { }: 条件が true に設定されている場合は、トレーニング セットを返し、それ以外の場合はテスト セットを返します。
機能をテストして寸法を確認できます。
data_train <- create_train_test(clean_titanic, 0.8, train = TRUE) data_test <- create_train_test(clean_titanic, 0.8, train = FALSE) dim(data_train)
出力:
## [1] 836 8
dim(data_test)
出力:
## [1] 209 8
トレーニング データセットには 1046 行があり、テスト データセットには 262 行があります。
関数 prop.table() を table() と組み合わせて使用して、ランダム化プロセスが正しいかどうかを確認します。
prop.table(table(data_train$survived))
出力:
## ## No Yes ## 0.5944976 0.4055024
prop.table(table(data_test$survived))
出力:
## ## No Yes ## 0.5789474 0.4210526
どちらのデータセットでも、生存者の数は同じで、約 40 パーセントです。
rpart.plot をインストールする
rpart.plot は conda ライブラリからは利用できません。 コンソールからインストールできます。
install.packages("rpart.plot")
ステップ 4) モデルを構築する
モデルを構築する準備ができました。 Rpart デシジョン ツリー関数の構文は次のとおりです。
rpart(formula, data=, method='') arguments: - formula: The function to predict - data: Specifies the data frame- method: - "class" for a classification tree - "anova" for a regression tree
クラスを予測するため、クラス メソッドを使用します。
library(rpart) library(rpart.plot) fit <- rpart(survived~., data = data_train, method = 'class') rpart.plot(fit, extra = 106
コードの説明
- rpart(): モデルに適合する関数。 引数は次のとおりです。
- 生き残った ~.: ディシジョン ツリーの公式
- data = data_train: データセット
- Method = 'class': バイナリ モデルを当てはめる
- rpart.plot(fit, extra= 106): ツリーをプロットします。 追加の特徴は、101 番目のクラスの確率を表示するために 2 に設定されています (二値応答に役立ちます)。 を参照できます。 ビネット 他の選択肢について詳しくは、こちらをご覧ください。
出力:
ルート ノード (深さ 0 から 3、グラフの上部) から開始します。
- 一番上は全体的な生存確率です。 事故で生き残った乗客の割合を示します。 乗客の41パーセントが生存した。
- このノードは、乗客の性別が男性であるかどうかを尋ねます。 「はい」の場合は、ルートの左側の子ノード (深さ 2) に進みます。 63%は男性で、生存確率は21%です。
- 3.5 番目のノードでは、男性乗客の年齢が 19 歳以上かどうかを尋ねます。 もしそうなら、生存の可能性はXNUMXパーセントです。
- どのような特徴が生存の可能性に影響を与えるかを理解するために、このような作業を続けます。
デシジョン ツリーの多くの特徴の XNUMX つは、データの準備がほとんど必要ないことです。 特に、フィーチャのスケーリングやセンタリングは必要ありません。
デフォルトでは、rpart() 関数は ジーニ ノートを分割するための不純物メジャー。 ジニ係数が高いほど、ノード内の異なるインスタンスが多くなります。
ステップ 5) 予測を立てる
テスト データセットを予測できます。 予測を行うには、predict() 関数を使用できます。 R デシジョン ツリーの予測の基本的な構文は次のとおりです。
predict(fitted_model, df, type = 'class') arguments: - fitted_model: This is the object stored after model estimation. - df: Data frame used to make the prediction - type: Type of prediction - 'class': for classification - 'prob': to compute the probability of each class - 'vector': Predict the mean response at the node level
テスト セットから、衝突後にどの乗客が生き残る可能性が高いかを予測したいと考えています。 つまり、209 人の乗客のうち、誰が生き残るかどうかがわかるということです。
predict_unseen <-predict(fit, data_test, type = 'class')
コードの説明
- detect(fit, data_test, type = 'class'): テスト セットのクラス (0/1) を予測します。
到着できなかった乗客と到着した乗客を検査する。
table_mat <- table(data_test$survived, predict_unseen) table_mat
コードの説明
- table(data_test$survived, detect_unseen): R の正しいデシジョン ツリー分類と比較して、生存者として分類され死亡した乗客の数をカウントするテーブルを作成します。
出力:
## predict_unseen ## No Yes ## No 106 15 ## Yes 30 58
モデルは 106 人の死亡乗客を正確に予測しましたが、15 人の生存者を死亡として分類しました。 類推すると、モデルは 30 人の乗客を生存者として誤分類しましたが、彼らは死亡していることが判明しました。
ステップ 6) パフォーマンスを測定する
分類タスクの精度尺度を計算するには、 混同行列:
この 混同行列 分類パフォーマンスを評価するには、これがより良い選択です。 一般的な考え方は、True インスタンスが False に分類される回数をカウントすることです。
混同行列の各行は実際のターゲットを表し、各列は予測されたターゲットを表します。 この行列の最初の行では、死亡した乗客 (False クラス) が考慮されます。106 人が死亡したと正しく分類されました (真陰性)、残りの XNUMX 人は誤って生存者として分類されました (偽陽性)。 58 行目は生存者を考慮しており、陽性クラスは XNUMX 人でした (真陽性)、 真陰性 30でした。
計算できます 精度テスト 混同行列から:
これは、行列の合計に対する真の陽性と真の陰性の割合です。 R を使用すると、次のようにコーディングできます。
accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
コードの説明
- sum(diag(table_mat)): 対角線の合計
- sum(table_mat): 行列の合計。
テスト セットの精度を出力できます。
print(paste('Accuracy for test', accuracy_Test))
出力:
## [1] "Accuracy for test 0.784688995215311"
テストセットのスコアは 78% です。 トレーニング データセットを使用して同じ演習を複製できます。
ステップ 7) ハイパーパラメータを調整する
Rの決定木には、フィットのさまざまな側面を制御するさまざまなパラメータがあります。rpart決定木ライブラリでは、rpart.control()関数を使用してパラメータを制御できます。次のコードでは、調整するパラメータを導入しています。 ビネット 他のパラメータについては。
rpart.control(minsplit = 20, minbucket = round(minsplit/3), maxdepth = 30) Arguments: -minsplit: Set the minimum number of observations in the node before the algorithm perform a split -minbucket: Set the minimum number of observations in the final note i.e. the leaf -maxdepth: Set the maximum depth of any node of the final tree. The root node is treated a depth 0
以下のように進めていきます。
- 精度を返す関数を構築する
- 最大深度を調整する
- ノードを分割する前にノードに必要なサンプルの最小数を調整します。
- リーフノードに必要なサンプルの最小数を調整する
精度を表示する関数を作成できます。 以前に使用したコードをラップするだけです。
- 予測:predict_unseen <- 予測(fit, data_test, type = 'class')
- テーブルの生成: table_mat <- table(data_test$survived, detect_unseen)
- 精度の計算:accuracy_Test <- sum(diag(table_mat))/sum(table_mat)
accuracy_tune <- function(fit) { predict_unseen <- predict(fit, data_test, type = 'class') table_mat <- table(data_test$survived, predict_unseen) accuracy_Test <- sum(diag(table_mat)) / sum(table_mat) accuracy_Test }
パラメーターを調整して、モデルをデフォルト値よりも改善できるかどうかを確認できます。 0.78 より高い精度を得る必要があることに注意してください。
control <- rpart.control(minsplit = 4, minbucket = round(5 / 3), maxdepth = 3, cp = 0) tune_fit <- rpart(survived~., data = data_train, method = 'class', control = control) accuracy_tune(tune_fit)
出力:
## [1] 0.7990431
次のパラメータを使用します。
minsplit = 4 minbucket= round(5/3) maxdepth = 3cp=0
前モデルよりもさらに高いパフォーマンスが得られます。 おめでとうございます!
まとめ
決定木アルゴリズムを訓練するための関数をまとめると、 R
図書室へようこそ | DevOps Tools Engineer試験のObjective | 演算 | CLASS | 計測パラメータ | 詳細 |
---|---|---|---|---|---|
パーツ | R で分類ツリーを訓練する | rpart() | class | 式、DF、メソッド | |
パーツ | 回帰ツリーを訓練する | rpart() | 分散分析 | 式、DF、メソッド | |
パーツ | 木を植える | rpart.plot() | フィットモデル | ||
ベース | 予測する | predict() | class | 適合モデル、タイプ | |
ベース | 予測する | predict() | PROB | 適合モデル、タイプ | |
ベース | 予測する | predict() | ベクトル | 適合モデル、タイプ | |
パーツ | 制御パラメータ | rpart.control() | ミンスプリット | アルゴリズムが分割を実行する前に、ノード内の観測の最小数を設定します。 | |
最小バケット | 最後のノート、つまりリーフに観測値の最小数を設定します。 | ||||
最大深度 | 最終ツリーのノードの最大深さを設定します。 ルートノードは深さ0として扱われます | ||||
パーツ | 制御パラメーターを使用してモデルをトレーニングする | rpart() | 数式、DF、メソッド、コントロール |
注: トレーニング データでモデルをトレーニングし、目に見えないデータセット、つまりテスト セットでパフォーマンスをテストします。