データ科学特論

データ科学特論
その 3: 決定木
今回行う分析
1
1. タイタニックの生存者データ
2. ボストンの不動産価格
3. 大学教員の年収
これらを決定木学習を行うことで予測モデルを作ってみる。
決定木学習
2
決定木学習は教師あり学習に分類される。
2.1
教師あり学習の復習と補足
X = {x1 , x2 , · · · , xn }
Y = {y1 , y2 , · · · , yn }
というそれぞれ n 個の要素からなる集合が与えられたとする。
それぞれの xi ,yi の対 (xi , yi ) はデータアイテムとも呼ばれ,xi は
xi = (xi1 , xi2 , xi3 , · · · , xim )
というように m 次元のベクトルで表されているものとする.
(yi については簡単のために
1 次元とする。)
1
この時,X および Y から,
yi = F (xi )
をできるだけ精度よく満たす関数 F を自動的に求めることを,教師あり学習と呼び,求めら
れた F を,なんとかモデルと呼ぶ(ニューラルネットワークモデルとか分類モデルとか)。
別の書き方をすれば, F : X → Y となる.
(厳密には,X や Y をそれぞれ含む X ,Y につい
て F : X → Y.)
予測変数と基準変数
X,Y の呼び名は学習モデルの種類によって変わってくる。以下では,X のことを予測変
数,Y のことを基準変数と呼ぶ。(できるだけ,X,Y も併記する。)
ただし,以下では例えば予測変数 3 を選ぶといった表現を使うが,これは,X = {x1 , · · · , xn }
から x3 を取り出すのではなく,X の個々のデータアイテムベクトルから軸を取り出す,つ
まり 1 ≤ i ≤ n において xi = (xi1 , xi2 , xi3 , · · · , xim ) というベクトルから,xi3 という要素を
取り出すという意味であることに注意。
学習と予測と精度
機械学習には,
1. 学習データからモデルを構築する学習
2. モデルにデータを適用する
という 2 つのフェーズがある。特に教師あり学習においては,2 のステップを,教師デー
タを当てるという意味で予測1 とも呼ぶ。そして,それには,例えば,
予測に成功したデータアイテム数
全てのデータアイテム数
のような式で,精度2 が定義できる。
2.2
木とは
木とは,数学的に以下のように定義される。
• グラフ: 点とそれらを結ぶ線の集合.点はノード,線は枝と呼ばれる.
1
2
識別,判別などとも呼ばれる.
分子は True Positive というもので,True Negative や他の指標も定義できる。
2
• 経路 :枝によって結ばれているノードの列.
• 連結 :グラフのどのノード間にも経路が存在するとき,グラフは連結であるという.
• 巡回 :始まりのノードと終わりのノードが同一である経路
• 単純巡回 : 3 つ以上のノードがあり,かつ両端のノードのみが重複する場合
• 木 : 連結であって単純巡回を持たないグラフのこと
• 根 :木においてある特定のノードを根と名付けることがある.
• 葉 :木のノードのうち,1 つの枝にのみ属するノード.
• 根付き木において,根に枝でつながるあるノード A を根からみて子と言い,根はノー
ド A から見て親と言う.
• また,ノード A の親以外で枝でつながるあるノード B を A の子と言い,ノード A は
ノード B の親という.同様にして全ての枝の両端に 親子 を定義できる.
• あるノードの子どうしをきょうだいとも呼ぶ.
2.3
決定木
決定木における木は,多次元データが以下のように対応している。
1. 根ノードは,全データに対応する。
2. 全データを 2 つに分割し,2 つの子ノードに対応させる。このときに,分岐条件が予測
変数を使って表現できる。
3. 子ノードについても同様に分割することで,どんどん子孫が増えていく。
分岐した子ノードが,全て一つの基準変数値を持つとは限らない。最多の基準変数値以外
をもつデータアイテムは,誤分類されたと呼ぶ。
決定木は,基準変数 Y がカテゴリ変数のときは分類木,連続変数のときは回帰木とも呼ば
れる。
3
2.4
学習
ここでは学習によるノードの分岐の方法を示す。基本的にはまずは全データを根ノードに
対応させ,適切な予測変数を探し,その変数の値によりデータを 2 つに分割にすることで子
ノードを 2 つ作る.さらにそれぞれの子ノードに対して再帰的に同様の分割を繰り返すこと
で,子孫を増やしていく。
基準変数が連続変数の場合の分岐
データアイテムの平均値との差を偏差といい,全てのデータにおける偏差を二乗して和を
取った物を偏差平方和と呼ぶ。(これをデータ数で割れば分散になる。)
基準変数 Y = {y1 , · · · , yn } の偏差平方和は
S(Y ) =
n
∑
(yi − ȳ)2
i=1
である.ただし ȳ は Y の平均値.
このデータを 2 つに分割し,対応して基準変数も YL ,YR に分かれたとすると,
分割しないときの分散から分割したときの分散の和を引いた値
S(Y ) − {S(YL ) + S(YR )}
が最大となる予測変数およびその値を探し,その変数と値で分岐を行う。
直感的には,この値は,分割された基準変数がコンパクトにまとまっていれば大きな値と
なる。
基準変数がカテゴリ変数の場合の分岐
基準変数 Y がカテゴリ変数としても,分散を基準に考える。
基準変数 Y が,c1 , c2 , · · · , cj , · · · , cJ のいずれかの値を持つとする。この時,基準変数 Y に
属するデータアイテムから任意に 1 つ選んでその値が cj である確率を pj とすると,その分
布は多項分布に従い,分散は pj (1 − pj ) であることが知られている.
c1 , · · · , cJ についての分散の和をジニ係数とよび,
I(Y ) =
J
∑
pj (1 − pj ) = 1 −
j=1
J
∑
j=1
で表す。
4
p2j
データを 2 つに分割して,対応して基準変数も YL ,YR に分かれたとする.このとき Y ,YL ,
YR のデータの個数をそれぞれ |Y |,|YL |,|YR | で表すと,分割しないときのジニ係数から分割
したときのジニ係数に個数の割合をかけた和を引いた値
I(Y ) − {
|YL |
|YR |
I(YL ) +
I(YR )}
|Y |
|Y |
が最大となるような予測変数を探し,その変数で分岐を行う。
ジニ係数の代わりに,以下のように定義される情報量を使うこともある。情報量は情報工
学の分野でよく使う量である。
I=−
J
∑
pj log pj
j=1
R による決定木(分類木)の例
3
タイタニックの生存者のデータの解析を試みる。
パッケージの読み込み:
> library(mvpart)
読み込み
データの読み込みと最初の方の行の表示:
> タイタニックデータ <- read.csv("chap3/タイタニック.csv", header=TRUE)
> head(タイタニックデータ)
等級 大人子ども 性別 生死
1 1等
大人 男性 生還
2 1等
大人 男性 生還
3 1等
大人 男性 生還
4 1等
大人 男性 生還
5 1等
大人 男性 生還
6 1等
大人 男性 生還
学習
> タ イ タ ニック 木 <- rpart(生 死 ~ 等 級 + 大 人 子 ど も + 性 別, data=タ イ タ ニック デ ー
タ, method="class")
最初の引数は,
5
基準変数 ~ 説明変数 1 + 説明変数 2 + ・
・
・
という書式.基準変数以外が全て説明変数なら,
基準変数 ~ .
のようにピリオドでもよい.
method="class"というのは,基準変数がカテゴリ変数である分類木を示している.省略
可能。
ジニ係数の代わりに情報エントロピーを分岐基準にしたければ,params=list(split=’information’)
という引数を追加する。
結果
結果の表示:
> print(タイタニック木)
n= 2201
node), split, n, loss, yval, (yprob)
* denotes terminal node
1) root 2201 711 死亡 (0.6769650 0.3230350)
2) 性別=男性 1731 367 死亡 (0.7879838 0.2120162)
4) 大人子ども=大人 1667 338 死亡 (0.7972406 0.2027594) *
5) 大人子ども=子ども 64 29 死亡 (0.5468750 0.4531250)
10) 等級=3 等 48 13 死亡 (0.7291667 0.2708333) *
11) 等級=1 等,2 等 16
0 生還 (0.0000000 1.0000000) *
3) 性別=女性 470 126 生還 (0.2680851 0.7319149)
6) 等級=3 等 196 90 死亡 (0.5408163 0.4591837) *
7) 等級=1 等,2 等, 乗務員 274 20 生還 (0.0729927 0.9270073) *
書式:
node), split, n, loss, yval, (yprob)
* denotes terminal node
とあるが,これは,以下のような意味となる。
• node: ノード番号
• split: 分岐の条件
6
• n: そのノードのデータ数
• loss: 誤分類のデータ数
• yval: ノードの基準変数
• yprob: 各ノードの適合確率??
• *: これがついているノードは葉ノード.
例えばノード 6 を見ると,親はノード 3 で,分岐条件は「性別=女性」.ノード 6 はそのう
ち 3 等乗客が 196 人,そのうち誤分類されている人は 90 人,つまり生還した人は 90 人.さ
らに,括弧の中を見ると,死亡と生還の割合がそれぞれ,54%, 46%となる.
プロット
図示するには:
> plot(タイタニック木, uniform=TRUE, branch=0.6, margin=0.15)
> text(タイタニック木, all=TRUE, use.n=TRUE, pretty=0)
これら print, plot, text は本当は, print.rpart, plot.rpart, text.rpart という関数
だが,省略可能である。(どのように省略可能かは,私にもまだ不明.
)
plot 関数の引数は,
• uniform:ノード同士の間隔を一定にするかどうか,
• branch:は枝の角度を 0 から 1 の間で指定,
• margin:図の周りの余白を指定
また,text 関数の引数は,
• all.leaves: 全てのノードにラベルをつける (T) か葉ノードのみにつける (F) か (こ
こでは all と省略),
• use.n:T にすると,ラベルに個体数を表示している。
• pretty=0 とすると,変数名をアルファベットではなくそのまま表示するようになる。
7
適用
次に,出来上がったモデルに学習データを適用して,その分類精度を調べてみる。predict
という関数で適用できる。
> 判別 <- predict(タイタニック木, newdata=タイタニックデータ, type="class")
> table(判別, タイタニックデータ$生死)
判別 死亡 生還
死亡 1470 441
生還
20 270
type="class"の場合,結果がカテゴリ変数として,名前で返される。type="vector"と
した場合,結果が数値で返される。ただしカテゴリ変数にも数値として使用できる.
table 関数は,同じ要素数を持つ 2 つのベクトルの値を X,Y 軸にして集計(クロス表と呼
ぶ)関数である。この例だと,例えば本当は死亡したのに生還と判別されるのが 20 名となる.
4
交差妥当化と枝刈り(プルーニング)
前回説明したように,学習しすぎる(過学習)と,学習データ以外のデータに対しては性
能が悪くなる。そこで,学習によって出来たモデルを少し退化させることで,他のデータへ
の性能(汎化能力)を確保する。これを枝刈り(プルーニング)と呼ぶ。
枝刈りには,
• 学習データだけを用いる方法
• 別の 2 セットのデータ(交差妥当化データ,検証用データと呼ぶ)を併用する方法
の 2 つがある。データが多い場合には後者が良い。後者の,基本的な流れは以下の通り。
1. 十分に精度が良くなるまで,十分に学習する。
2. 葉を持つ枝の中で,学習データに対して成績の良くない部分に注目し,その枝がある
場合とない場合の成績を交差妥当化用データで計算する。
3. 交差妥当化用データに関して成績の落ちる枝はプルーニングする。
4. プルーニングした部分は新たに葉になるので,さらに 2,3 を繰り返す。
5. どの葉を持つ枝をプルーニングしても,交差妥当化用データによる成績が下がるよう
になれば,終了.
8
6. この過程で出来た決定木と,交差妥当化用データは互いに統計的に独立ではなくなっ
ているので,新たに独立したデータである検証用データを用意する。
7. 検証用データを用いて計算した最終的な決定木の精度を,最終的な精度とする。
4.1
R による回帰木と枝刈りの例
ボストンの不動産の価格を分類する例.今度は,連続変数を基準変数とする,回帰木を例
とする.
読み込み
データの読み込みと表示:
> ハウスデータ <- read.csv("chap3/ハウス.csv",header=TRUE, fileEncoding="sjis")
> head(ハウスデータ)
犯罪率 邸宅率 非小売 川沿い NX 濃度 部屋数 古さ率 安定所 高速道 資産税
1 0.00632
18
2.31
0 0.538 6.575
65.2 4.0900
1
296
2 0.02731
0
7.07
0 0.469 6.421
78.9 4.9671
2
242
3 0.02729
0
7.07
0 0.469 7.185
61.1 4.9671
2
242
4 0.03237
0
2.18
0 0.458 6.998
45.8 6.0622
3
222
5 0.06905
0
2.18
0 0.458 7.147
54.2 6.0622
3
222
6 0.02985
0
2.18
0 0.458 6.430
58.7 6.0622
3
222
生徒数 黒人率 下層率 家価格
1
15.3 396.90
4.98
24.0
2
17.8 396.90
9.14
21.6
3
17.8 392.83
4.03
34.7
4
18.7 394.63
2.94
33.4
5
18.7 396.90
5.33
36.2
6
18.7 394.12
5.21
28.7
学習
学習と結果の表示:
> ハウス木 <- rpart(家価格 ~ ., data=ハウスデータ, method="anova")
> print(ハウス木)
n= 506
node), split, n, deviance, yval
* denotes terminal node
1) root 506 42716.3000 22.53281
9
2) 部屋数< 6.941 430 17317.3200 19.93372
4) 下層率>=14.4 175 3373.2510 14.95600
8) 犯罪率>=6.99237 74 1085.9050 11.97838 *
9) 犯罪率< 6.99237 101 1150.5370 17.13762 *
5) 下層率< 14.4 255 6632.2170 23.34980
10) 安定所>=1.38485 250 3721.1630 22.90520
20) 部屋数< 6.543 195 1636.0670 21.62974 *
21) 部屋数>=6.543 55
643.1691 27.42727 *
11) 安定所< 1.38485 5
390.7280 45.58000 *
3) 部屋数>=6.941 76 6059.4190 37.23816
6) 部屋数< 7.437 46 1899.6120 32.11304
12) 犯罪率>=7.393425 3
27.9200 14.40000 *
13) 犯罪率< 7.393425 43
864.7674 33.34884 *
7) 部屋数>=7.437 30 1098.8500 45.09667
14) 生徒数>=18.3 3
223.8200 33.30000 *
15) 生徒数< 18.3 27
411.1585 46.40741 *
今度は回帰木なので書式が少し異なる。
• deviance: 2.4 節で説明した,ノード内の偏差平方和。
• yval: 同じく 2.4 節で出た,ノード内の平均となる.
学習の程度
学習のときの rpart 関数の引数 cp=0.01(complexity parameter)が小さいほど,複雑な
木が出来上がる。デフォルトは 0.01.
cp の値によって性能がどう変わるかをグラフに表示してみる。
> plotcp(ハウス木)
ここでグラフを見ると,X 軸(下)は cp, X 軸(上)が木のサイズ(葉の数),Y 軸が予測
変数の相対誤差を表している。ここでの相対誤差とは,全く枝分かれしない木における誤分
類の回数に対する,この木の誤分類の回数の割合.木が茂れば茂ほど小さくなる.リスクと
いうらしい.
水平に引かれた直線 Min+1SE は,交差妥当化検証の結果から求められる相対誤差の最小
値に標準偏差を足した値。通常はこれを越さない最大の相対誤差が妥当とされる。オレンジ
の点は直線 Min+1SE 以下の最も近い点,赤い点はリスクの最小値。
(交差妥当化検証はラン
ダムに行うので,毎回値が一定とは限らない。)
10
Size of tree
2
3
4
●
●
●
5
6
7
8
9
●
●
●
●
●
●
●
●
0.016
0.01
0.6
0.8
●
●
●
●
0.4
X−val Relative Error
1.0
1
●
0.2
●
●
Min + 1 SE
●
●
Inf
0.28
0.11
0.065
0.045
0.03
0.025
cp
枝刈り
ここではグラフを見ながら,cp=0.03 のところで枝刈りを行ってみる:
> ハウス木 2 <- prune(ハウス木, cp=0.03)
> print(ハウス木 2)
n= 506
node), split, n, deviance, yval
* denotes terminal node
1) root 506 42716.3000 22.53281
2) 部屋数< 6.941 430 17317.3200 19.93372
4) 下層率>=14.4 175 3373.2510 14.95600 *
5) 下層率< 14.4 255 6632.2170 23.34980
10) 安定所>=1.38485 250 3721.1630 22.90520
20) 部屋数< 6.543 195 1636.0670 21.62974 *
21) 部屋数>=6.543 55
643.1691 27.42727 *
11) 安定所< 1.38485 5
390.7280 45.58000 *
3) 部屋数>=6.941 76 6059.4190 37.23816
6) 部屋数< 7.437 46 1899.6120 32.11304 *
7) 部屋数>=7.437 30 1098.8500 45.09667 *
先ほどよりノード数が減っている。
図示:
11
> plot(ハウス木 2, uniform=TRUE, branch=0.6, margin=0.1)
> text(ハウス木 2, all=TRUE, use.n=TRUE)
5
相関で性能を測る
今度は,大学教員の属性から年収を分類してみる。
> 年収データ <- read.csv(’chap3/年収.csv’,header=TRUE,fileEncoding=’sjis’)
> 年収木 <- rpart(年収 ~ . , data=年収データ)
> print(年収木)
n= 52
node), split, n, deviance, yval
* denotes terminal node
1) root 52 1785730000 23797.65
2) 地位=講師, 助教 32 358933500 20134.34
4) 学位年数< 6.5 13
21458820 16849.54 *
5) 学位年数>=6.5 19 101231700 22381.84
10) 地位=講師 5
23777960 20158.40 *
11) 地位=助教 14
43907230 23175.93 *
3) 地位=教授 20 310265600 29658.95
6) 現職年数< 12.5 12 143875300 27628.67
12) 現職年数< 6.5 4
706875 25062.50 *
13) 現職年数>=6.5 8 103657100 28911.75
26) 性別=男性 6
7516661 27745.67 *
27) 性別=女性 2
63506450 32410.00 *
7) 現職年数>=12.5 8
42728800 32704.38
14) 学位年数< 21.5 3
6298026 30513.00 *
15) 学位年数>=21.5 5
13380570 34019.20 *
> plot(年収木, uniform=TRUE, branch=0.6, margin=0.05)
> text(年収木, all=TRUE, use.n=TRUE, pretty=0)
これより,現職年数が 12.5 年以上の教授の場合,学位を早く取っているかどうかが年収に
影響していることがわかる。
次に,学習データを用いて年収を予測し,それと実際の相関を見てみよう.相関とは,2
変数が似ているかどうかを見る統計量であり,-1 から 1 の値をとる.大きい方が似ている。
> 年収予測 <- predict(年収木, newdata=年収データ, type="vector")
> cor(年収データ$年収, 年収予測)
[1] 0.9480989
> plot(年収データ)
> plot(年収データ$年収, 年収予測)
12
cor は相関係数を求める関数であり,今回は約 0.95 と,非常に近い。ただし今回は学習
データを適用しているので,実際には他のデータを使うのが汎化の観点から望ましい。
6
宿題
今回 R で行った内容を,自分の計算機環境で再現してください。
13