差分
このページの2つのバージョン間の差分を表示します。
次のリビジョン | 前のリビジョン次のリビジョン両方とも次のリビジョン | ||
mselab:2016:stat:week2 [2016/11/08 09:21] – created watalu | mselab:2016:stat:week2 [2016/11/08 12:56] – watalu | ||
---|---|---|---|
行 1: | 行 1: | ||
- | === 第2週 === | + | ==== 第2週 |
今週の{{: | 今週の{{: | ||
- | - より柔軟な学習機械と単純な学習機械との比較 | + | - 先週は「学習機械の当てはめ」によるデータの分析、今週は「学習機械による予測結果」を評価してどれを用いるかを検討 |
+ | - 各学習機械には様々な「パラメータ」があり、それを変えることで学習結果も予測精度も変わる | ||
+ | - 線形判別分析(lda)、二次判別分析(qda)、決定木(rpart)だけでなく、より柔軟な学習機械も用いる候補に含める | ||
- キャンペーンの提案書の作成 | - キャンペーンの提案書の作成 | ||
- | == 学習機械の予測精度の評価 == | + | === 学習と予測 === |
+ | == 学習 == | ||
+ | |||
+ | 例えばあるデータに回帰分析を行う。 | ||
+ | |||
+ | < | ||
+ | tic.lm <- lm(V86~., | ||
+ | </ | ||
+ | |||
+ | 学習理論の言葉では、これは「回帰分析」という学習機械を「最小二乗法」という学習アルゴリズムで学習させたことに相当する。 | ||
+ | そして学習の精度は、「実際の個々の観測値(tic.learn$V86)」と、モデルを推定した結果による個別の平均の推定値である「当てはめ値(fitted(tic.lm))」とを比較して検討する。 | ||
+ | |||
+ | まずは横軸を観測値、縦軸を当てはめ値にした散布図。 | ||
+ | < | ||
+ | plot(tic.learn$V86, | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | あまりよくわからないので、箱ひげ図に直してみる。 | ||
+ | < | ||
+ | plot(fitted(tic.lm)~as.factor(tic.learn$V86), | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ヒストグラムを描いてもいい。 | ||
+ | < | ||
+ | par(mfrow=c(2, | ||
+ | hist(fitted(tic.lm)[tic.learn$V86==0], | ||
+ | | ||
+ | | ||
+ | hist(fitted(tic.lm)[tic.learn$V86==1], | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | あまり変わらないように見える。 | ||
+ | 平均の差のt検定(Welchの検定)ぐらいをやってみると、この差に統計的な有意差はあることが分かる。 | ||
+ | |||
+ | < | ||
+ | t.test(fitted(tic.lm)[tic.learn$V86==0], | ||
+ | </ | ||
+ | さりとて、当てはめ値が0付近なのはあまりよい回帰分析とは言えない。 | ||
+ | |||
+ | 当てはまりの良さ(悪さ)は、残差という量でも検討できる。残差の定義は、「実際の個々の観測値(tic.learn$V86)-当てはめ値(fitted(tic.lm))」であり、データの個々の観測値の変動のうちのモデルで説明しきれなかった部分である。 | ||
+ | 関数residuals()を用いて計算させることができる。 | ||
+ | < | ||
+ | plot(residuals(tic.lm)) | ||
+ | </ | ||
+ | 単に、レコード番号順に残差を計算させるとこうなる。 | ||
+ | |||
+ | 残差の大きさや傾向を検討をするときには、観測値と残差の傾向をみる散布図 | ||
+ | < | ||
+ | plot(tic.learn$V86, | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | や、当てはめ値と残差の散布図 | ||
+ | < | ||
+ | plot(fitted(tic.lm), | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | を見て、何か説明できていない傾向が残っていないかどうかを検討する。 | ||
+ | 他に、てこ比を見たり、半正規プロットなどを検討することもある。 | ||
+ | |||
+ | 重回帰分析に限って、上で紹介したグラフの多くは | ||
+ | < | ||
+ | plot(tic.lm) | ||
+ | </ | ||
+ | で自動的に描画される。 | ||
+ | |||
+ | 他にも要約の出力 | ||
+ | < | ||
+ | summary(tic.lm) | ||
+ | </ | ||
+ | を見て、学習精度を検討する。 | ||
+ | |||
+ | == 予測 == | ||
+ | |||
+ | 予測とは、学習した結果(学習済みの学習機械)を別のデータに基づく予測に用いることを言う。 | ||
+ | そのためには、学習用データと同じ構造を持つ、別のデータを用意する。 | ||
+ | 予測精度を評価するので、ここでは評価用データと呼ぶ。 | ||
+ | 今年の実験ではtic.learnが学習用データ、tic.evalが評価用データであり、前回のデータ読み込みの手順で両方ともダウンロードされる。 | ||
+ | |||
+ | 予測値の算出には関数predictを用いる。学習済み機械tic.lmに、tic.evalの中の各レコードのV1からV85に基づいてV86を予測させるにはpredict()を | ||
+ | < | ||
+ | predict(tic.lm, | ||
+ | </ | ||
+ | と用いる。学習にtic.evalを用いていないことから、この結果は予測値として扱える。 | ||
+ | |||
+ | lmを用いて予測したので、 | ||
+ | < | ||
+ | v86.lm <- predict(tic.lm, | ||
+ | </ | ||
+ | と名付けておく。 | ||
+ | |||
+ | < | ||
+ | plot(tic.eval$V86, | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ヒストグラムを描いてもいい。 | ||
+ | < | ||
+ | par(mfrow=c(2, | ||
+ | hist(v86.lm[tic.learn$V86==0], | ||
+ | | ||
+ | | ||
+ | hist(v86.lm[tic.learn$V86==1], | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | なんかダメそうに見える。 | ||
+ | |||
+ | さて残差は「当てはめ値-観測値」だったが、予測の良さを測るには予測誤差を用いる。 | ||
+ | 予測誤差の定義は「予測値-正解」である。 | ||
+ | < | ||
+ | plot(tic.eval$V86, | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | 予測誤差にも傾向があり、とてもではないが、重回帰分析はこのままではよい予測を与えてくれる気がしない。 | ||
+ | 箱ひげ図を描くまでもないが、念のため。 | ||
+ | |||
+ | < | ||
+ | plot((v86.lm-tic.eval$V86)~as.factor(tic.eval$V86), | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | あまり変わらないように見える。 | ||
+ | 平均の差のt検定(Welchの検定)ぐらいをやってみると、この差に統計的な有意差はあることが分かる。 | ||
+ | |||
+ | < | ||
+ | t.test((v86.lm-tic.eval$V86)[tic.eval$V86==0], | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | まあだめそう。。。 | ||
+ | |||
+ | == 線形判別分析(lda)の場合 | ||
学習機械は予測精度が高くて初めて、有用性が認められる。そのためには「学習に用いなかったデータ」に関して予測を行い、精度を評価する必要がある。 | 学習機械は予測精度が高くて初めて、有用性が認められる。そのためには「学習に用いなかったデータ」に関して予測を行い、精度を評価する必要がある。 | ||
行 77: | 行 222: | ||
</ | </ | ||
のようにクロス集計を実行して、予測結果(v86.lda$class)と実際(tic.eval$V86)を比較する。 | のようにクロス集計を実行して、予測結果(v86.lda$class)と実際(tic.eval$V86)を比較する。 | ||
+ | |||
+ | == 二次判別分析(qda)の場合 == | ||
他の学習機械についても同様に | 他の学習機械についても同様に | ||
行 98: | 行 245: | ||
</ | </ | ||
のように最初の30変数を使って86番目を予測する、とするなどの工夫が必要になる。 | のように最初の30変数を使って86番目を予測する、とするなどの工夫が必要になる。 | ||
+ | |||
+ | == 決定木(rpart)の場合 == | ||
再帰的分割(rpart)を用いる場合は、次のようなデータの変換が必要になる。 | 再帰的分割(rpart)を用いる場合は、次のようなデータの変換が必要になる。 | ||
行 107: | 行 256: | ||
< | < | ||
tic.rpart <- rpart(V86~., | tic.rpart <- rpart(V86~., | ||
- | v86.rpart <- predict(tic.rpart, | + | v86.rpart <- predict(tic.rpart, |
table(v86.rpart$class, | table(v86.rpart$class, | ||
</ | </ | ||
行 124: | 行 273: | ||
サポートベクターマシン(ksvm)はkernlabパッケージに、バギング(bagging)はipredパッケージに、ブースト(ada)はadaパッケージに、ランダムフォレスト(randomForest)はrandomForestパッケージに、それぞれ含まれているので、まずは必要なパッケージをインストールする。 | サポートベクターマシン(ksvm)はkernlabパッケージに、バギング(bagging)はipredパッケージに、ブースト(ada)はadaパッケージに、ランダムフォレスト(randomForest)はrandomForestパッケージに、それぞれ含まれているので、まずは必要なパッケージをインストールする。 | ||
< | < | ||
- | bank <- read.table(" | ||
- | | ||
- | | ||
Sys.setenv(" | Sys.setenv(" | ||
install.packages(" | install.packages(" | ||
行 140: | 行 286: | ||
サポートベクターマシンに学習させる実行例: | サポートベクターマシンに学習させる実行例: | ||
< | < | ||
- | bank.svm <- ksvm(y~., data=bank, | + | tic.svm <- ksvm(V86~., data=tic.learn.2, |
| | ||
| | ||
- | bank.svm.p< | + | v86.svm <- predict(tic.svm, newdata=tic.eval) |
- | table(bank.svm.p, bank$y) | + | table(v86.svm,tic.eval$V86) |
</ | </ | ||
+ | kparの中身を変更しないと、全く予測精度が稼げない感じ。 | ||
バギングに学習させる実行例: | バギングに学習させる実行例: | ||
< | < | ||
- | bank.bag< | + | tic.bagging |
nbagg=40) | nbagg=40) | ||
- | bank.bag.p <- predict(bank.bag,type= " | + | v86.bagging |
- | table(bank.bag.p, bank$y) | + | table(v86.bagging, tic.eval$V86) |
</ | </ | ||
+ | これもバッグの数が40でいいか分からない微妙な感じ。 | ||
Adaブーストに学習させる実行例: | Adaブーストに学習させる実行例: | ||
< | < | ||
- | bank.ada <- ada(y~., data=bank, | + | tic.ada <- ada(V86~., data=tic.learn.2, |
iter=20) | iter=20) | ||
- | bank.ada.p <- predict(bank.ada,type= " | + | v86.ada <- predict(tic.ada, newdata=tic.eval, type= " |
- | table(bank.ada.p, bank$y) | + | table(v86.ada, tic.eval$V86) |
</ | </ | ||
+ | これも繰り返し数(iter)が20ではぜんぜんだめな感じ。 | ||
ランダムフォレストに学習させる実行例: | ランダムフォレストに学習させる実行例: | ||
< | < | ||
- | bank.rf <- randomForest(y~., data=bank) | + | tic.randomForest |
- | bank.rf.p <- predict(bank.rf) | + | v86.randomForest |
- | table(bank.rf.p, bank$y) | + | table(v86.randomForest, tic.eval$V86) |
</ | </ | ||
- | 以上は「弱い学習機械」の指定と、個々の学習機械の設定パラメータが、デフォルトのままであることとは注意しておく。パラメータのチューニングが必要なはずである。 | + | 以上は「弱い学習機械」の指定と、個々の学習機械の設定パラメータが、デフォルトのままであることとは注意しておく。それぞれの予測結果を見れば、パラメータのチューニングが必要なことは明らか。 |
なお、この課題では「過学習」について言及していないが、過学習は大事な問題であるので、各自、少し調べて気にすることを進める。 | なお、この課題では「過学習」について言及していないが、過学習は大事な問題であるので、各自、少し調べて気にすることを進める。 |