decision tree
TRANSCRIPT
第34回R勉強会@東京(#TokyoR)
決定木
@gepuro
自己紹介● 電気通信大学大学院修士一年
● 早川 敦士(@gepuro)
● 専攻:信頼性工学、品質管理
● 興味:マーケティング、生存時間解析、テキストマイニング
● 著作物:データサイエンティスト養成読本(技術評論社)
● 好きな物:ラーメン、りんごジュース、花火
ブログをやってます
http://blog.gepuro.net
おなじみのirisデータを使います
setosa versicolor verginica
Sepal Length: がく片の長さSepal Width: がく片の幅Petal Length: 花びらの長さPetal Width: 花びらの幅Species: 品種
品種毎に50レコードで、計150レコードのデータセットを利用します。
画像データ:http://en.wikipedia.org/wiki/Iris_flower_data_set より
決定木って?
葉節点
決定節点
根節点決定節点:変数の値をチェックする根節点:決定節点のうち最初の決定節点葉節点:ラベルが割りあてられる。
Pepal.Length<2.45は、setosa,versicolor,virginicaがそれぞれ50,0,0となる。
Pepal.Length>2.45かつPetal.Width>=1.75は、setosa,versicolor,virginicaがそれぞれ0,1,45となる。
教師あり学習の一つで、目的変数と説明変数を設定する必要がある。木構造で表現される事から、決定木と呼ばれている。
節点にある条件を満たすと、左側へ行く。
決定木の説明は以上です。
折角なので、もう少し詳しく勉強します。
まずは、描き方をrpart()を利用します。rpart(目的変数~説明変数)
グラフを描く時に、par(xpd=NA)を忘れずに
各ラベルのn数も表示しよう
これだけ簡単ならば、目をつぶっても出来る?
どうやって、決定節点を求めるの?
決定節点
ジニ係数を用います。
節点tにおける誤り率
誤り率が最小になるように、決定節点を求める。
決定木の大きさは?
小さい決定木
小さすぎる決定木では、正しく分類できない。
決定木が大きすぎると過学習を起こす。(訓練データに適応しすぎる)
剪定しよう
交差検証法(10
セット)
による誤り率
決定木の複雑度
決定木の大きさ
誤りの最小値とその点の標準偏差を加えた値
棒線を越えない最大のCPが良いとされている。(1標準偏差ルール)
prune.rpart(model, cp=0.5)で剪定できる。
予測しようカテゴリデータの予測は、
type=”class”を忘れずに
真値と予測結果
訓練データと検証データは同一であるが、そこそこの精度で分類出来ていることが分かる。
決定木で回帰分析
● 決定木の回帰バージョンは、回帰木と呼ばれる。
サンプルデータ: スポーツテストデータ説明: 中学生104人の運動能力テスト6種と体力測定5種の計測のデータデータ数:104レコードhttp://mo161.soci.ous.ac.jp/@d/DoDStat/sports/sports_dataJ.xmlでデータをダウンロード出来ます。
50m走のタイムを予測する
分岐後の50m走のタイムの平均
走り幅跳びの成績の良さが50m走のタイムに好影響を与えている。
枝きりタイム
大きな木を見て、剪定する。
残差のヒストグラム
hist(sports$X50mRun - predict(model, sports))
真の値と予測結果がどれほどズレているか。
決定木に親しもう
決定木の使い所は、予測だけじゃない!!
● どの変数に注目すれば良いか?● 目的変数と関係が深そうな変数は?● 層別解析のヒントを得る。
予測モデルとしては精度が低い時もあるが、分析のヒントを得られるかも!
分析のヒントとは?
疑問:50m走が早い人は、どんな人だろうか?答え:走り幅跳びが得意な人
時間に余裕が出来たので、
● Rでデータを加工する時の方法を紹介します。● 独断と偏見のランキング形式で。
第十位
● cumsum
累積和を求める
cumsum(iris$Sepal.Length)
第九位
● colMeans,colSums, rowMeans, rowSums
列毎、行毎に平均や合計を求める
> colMeans(iris[,1:4])Sepal.Length Sepal.Width Petal.Length Petal.Width 5.843333 3.057333 3.758000 1.199333
第八位
● reshape
データを横に展開する
> iris$ID <- 1:150> reshape(iris[,c(1,5,6)], idvar="ID", timevar="Species", direction="wide")
ID Sepal.Length.setosa Sepal.Length.versicolor Sepal.Length.virginica1 1 5.1 NA NA2 2 4.9 NA NA3 3 4.7 NA NA4 4 4.6 NA NA5 5 5.0 NA NA6 6 5.4 NA NA
第七位
● aggregate
集計を行う
> aggregate(iris[,1:4], by=list(iris$Species), mean) Group.1 Sepal.Length Sepal.Width Petal.Length Petal.Width1 setosa 5.006 3.428 1.462 0.2462 versicolor 5.936 2.770 4.260 1.3263 virginica 6.588 2.974 5.552 2.026
第六位
● apply
慣れれば便利。for文でも代用可
apply(iris[,1:4], 1, sum) # 行毎に合計を求めるapply(iris[,1:4], 2, sum) # 列毎に合計を求める
第五位
● ifelse
条件分岐を一行で書く
ifelse(条件, 条件が真の時返す値, 偽の時返す値)> ifelse(sports$X50mRun < 8, "1", "0")
第四位
● rbind
テーブルを縦に結合する
> df3 <- data.frame(a=1:3, b=2:4)> df4 <- data.frame(a=4:6, b=5:7)> rbind(df3, df4) a b1 1 22 2 33 3 44 4 55 5 66 6 7
第三位
● merge
テーブルを横に結合する。> df1 <- data.frame(a=1:5, b=2:6)> df2 <- data.frame(a=c(1,2,4,6), c=c(2,3,4,5))> merge(df1, df2, by=c("a")) # df1とdf2のaが共通
> merge(df1, df2, all.x=T, by=c("a")) # df1のaを残す
> merge(df1, df2, all=T, by=c("a")) # 全てのaを残す
a b c1 1 2 22 2 3 33 4 5 4
a b c1 1 2 22 2 3 33 3 4 NA4 4 5 45 5 6 NA
a b c1 1 2 22 2 3 33 3 4 NA4 4 5 45 5 6 NA6 6 NA 5
第二位
● table
クロス集計を作成する。> table(iris$Species)
setosa versicolor virginica 50 50 50 > table(iris$Species, iris$Petal.Width) 0.1 0.2 0.3 0.4 0.5 0.6 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 setosa 5 29 7 7 1 1 0 0 0 0 0 0 0 0 0 versicolor 0 0 0 0 0 0 7 3 5 13 7 10 3 1 1 virginica 0 0 0 0 0 0 0 0 0 0 1 2 1 1 11 1.9 2 2.1 2.2 2.3 2.4 2.5 setosa 0 0 0 0 0 0 0 versicolor 0 0 0 0 0 0 0 virginica 5 6 6 3 8 3 3
第一位
● subset
条件に一致するデータを抽出する
# 50m走が8秒未満のレコードを抽出subset(sports, X50mRun < 8)
# setosaもしくはversicolorのレコードを抽出subset(iris, Species %in% c("setosa", "versicolor"))
● 気分を盛り上げるために、ランキングで紹介しましたが、深く考えた結果では無いです。
● あまり気にしないでください。
参考
● R-tips,http://cse.naro.affrc.go.jp/takezawa/r-tips/r.html
● はじめてのパターン認識,森北出版
● 入門 自然言語処理,オライリー
ご清聴ありがとうございました。