2017年5月22日月曜日

優れた予測モデルとは: SAS GLMSELECT プロシジャの紹介






関係のない説明変数をむやみに追加して決定係数 (= 説明力 ) を闇雲に増やしても、予測モデルとしてはつかえません。そのようなモデルはデータで見える範囲のものだけを都合よく解釈したものにすぎません。決定係数ではなく、情報量基準を用いる、交差検証 (クロスバリデーション) を行う、罰則付き回帰を用いる、といった方法で本当に意味のある変数だけを選ばなければ「良いモデル」にはなりえません。ここでいう「良いモデル」とは説明力ではなく「予測性能のよいモデル」のことです。闇雲に説明変数を追加したモデルがどうして良くないかは、以前書いた「 説明力のある回帰分析モデルは使えない?」をご覧ください。

KDNuggets より, Ted Goff の漫画
そこで、今回はこの問題を具体的に解決する方法の1つとして、GLMSELECT プロシジャの扱い方を説明したいと思います。まず、情報量基準と交差検証法、そして変数選択法を簡単に説明します。そのうえで、メジャーリーグ選手の成績データと年俸のデータを例にして、GLMSELECT プロシジャの使い方を解説します。単に GLMSELECT の使い方だけを知りたい方は、これらを飛ばして後半のGLMSELECTプロシジャの使い方から読み始めてください。

情報量規準とは

情報量規準とは、いくつかのモデルの候補があるとき、それらのうちどれがより良いモデルかを判断するための指標です。変数を入れ替えて何度も回帰モデルを計算し、情報量基準が小さいモデルを採用します。情報量基準にはいくつかバリエーションがあり、その中でも赤池の考案した赤池の情報量基準 (AIC) と Schwarz の考案したベイジアン情報量基準 (BIC, SIC) がよく利用されます。両者は用途と計算方法が違うので、必ずしも同じ結果になりません。BIC は AIC よりも少ない変数が選ばれる傾向があります。しかし、どちらがより優れた情報量基準か、ということは断言できないので、目的に応じて使い分けられます。AIC は「より予測性能がよいモデルを選ぶ」ことができ、BIC は「より正しいモデルが選ばれる確率を最大化する」指標です。「ベイジアン」という名前ですが、これはベイズの定理を利用して計算している、という程度の意味であり、いわゆるベイズ統計モデルだから BIC を使わなければならないとか、ベイズモデルじゃないから BIC を使ってはならない、ということではありません。他にも DIC, WAIC と呼ばれる情報量規準が有名ですが、前者はベイズ統計で、後者は一部の特殊なモデルで使用することを前提に作られたものなので今回は使用しません。

交差検証法とは

情報量規準のほかに、データセット全体を計算用と予測用に分けて予測性能を確認するという方法があります。これは「ホールドアウト検証」と呼ばれます。計算用の部分は「訓練データ」、予測性能の確認の部分は「テストデータ」とか「評価データ」とか呼ばれます。データセットのレコード数が十分にあるならばこれで良いのですが、少ない場合はこの分割によってさらに計算に使えるデータセットが減ってしまうので、交差検証法を使います。例えば 1 抜き交差検証(leave-one-out CV, LOOCV) と呼ばれる方法ならば、データセットから 1レコードだけ除いて計算し、その予測値と残り 1 レコードの値を誤差とします。つまりホールドアウト検証を繰り返しているようなものです。これをすべてのレコードについて繰り返します[1]。つまり、データセットが100レコードならば、99個のレコードで回帰モデルを計算するのを100回ぶん行うわけです。この100個すべての誤差の平均が、そのモデルで予測するときの誤差の大きさになります。この指標は「汎化誤差」と呼ばれたりします。よって、2つのモデル候補があったとして、この誤差の小さいほうが、より良いモデルになるということです。しかし、たとえばデータが数十万レコードもあるときは、計算量が膨大になってしまいます[2]。そこで、サンプルを幾つかのグループに分割し、グループ単位で計算と誤差の評価を繰り返す方法がよく取られます。この方法はk-分割交差検証といいます。たとえばレコードを10 個のグループに分けた場合、10回繰り返せば計算が終わります。

では、情報量規準と交差検証とどちらがよいのか、という点に疑問を持つ方が出てくると思います。交差検証法のうち LOOCV と情報量規準は、レコード数が十分に多ければ結果が一致します。しかし、情報量規準の多くは、使用するには条件があり、この条件を満たさない複雑なモデルには適用できません。逆に交差検証は原理が単純なので、どのような複雑なモデルに対しても原則として使用可能です。一方で、すでに述べたように交差検証法は計算量が多いです。GLMSELECT プロシジャがあつかう線形回帰モデルでは、情報量規準が使用可能なので、計算の簡単さの点で情報量規準が優位ですが、情報量規準も推定量の一種なので、結果には誤差があります。なので「どちらを使えばいいか」ではなく「どういうときに使ってはいけないか」だけを覚えておけばいいと思います。

変数選択法

交差検証法も情報量基準も与えられたモデルを評価する方法なので、そもそも、どうやって変数を取捨選択するか、ということを考える必要があります。変数の組み合わせを総当りでやっていたのでは大変です。例えば 10 個の変数があったとしたら、 \(2^{10}-1=1023\) 通りも計算しなければなりません。そこで、「増加法」「減少法」「ステップワイズ法」と呼ばれる変数選択法のルールに基づいて変数を選ぶのが一般的です。「増加法」の場合、\(K\) 種類の変数候補のうち 1 つだけを含んだモデルを計算し ( つまり \(K\) 個のモデルを計算します ) 、その中で一番情報量基準が小さいモデルを選びます。どの変数を追加しても情報量基準が増えてしまうなら、そこで終了です。こうして変数を 1 つ含んだモデルに対し、同様の手順で残った \(K-1\) 個の変数から 1 つ変数を選びます。このため、総当りで \(2^K-1\) 回計算するよりはだいぶ計算回数が減ります。「減少法」は逆に、変数候補をすべて含んだモデルを最初に計算し、そのなかから、除外することでモデルの情報量基準を一番小さくできる変数を順に除外していきます。「ステップワイズ法」は増加法と減少法の折衷のような方法で、「増減法」とも呼ばれます。ステップワイズ法では、増加法のように情報量基準で1つ変数を追加したら、今度はすでに含まれている変数から最も情報量基準を大きくしている変数を除外します。情報量規準ではなく、交差検証で求めた汎化誤差の一番小さい変数を選ぶ、という方法でもいいです[3]

野球選手の年俸はどうやって予測できるか ?

SAS の SASHELP ライブラリに、動作確認のための様々なデータセットがあるのはご存知でしょうか ? その中にある baseball データセット[4]には、 1986 年の MLB で活躍した約 400 名の野手の成績と通算成績、そして翌年の年俸が記録されています。選手の年俸がどのようにして決まるかは人気などもあるかもしませんが、成績の優秀な選手ほど高額な年俸を得られそうだと考えるのが自然です。よって、盗塁数、打点、本塁打数などの数字を説明変数として、それぞれの要素がどう年俸に影響しているか分析してみましょう[5]。野球は 1986 年以外の年にも行われていますし、収録されていない野手も存在するので、より広範囲で当てはまるモデルを作るにはデータに対するモデルの当てはまりの良さだけでなく、予測性能も考慮して説明変数を決めなければなりらないのは明らかです。まず、sashelp.baseballの変数名が分かりづらいので、名前を日本語にしておきます。


options validvarname=any;
data work.baseball(rename=(
            Name      =   '氏名'n
            Team      =   'チーム'n
            nAtBat    =   '打席数'n
            nHits     =   '安打'n
            nHome     =   '本塁打'n
            nRuns     =   '得点'n
            nRBI      =   '打点'n
            nBB       =   '四球'n
            YrMajor   =   'MLB年数'n
            CrAtBat   =   '通算打席数'n
            CrHits    =   '通算安打'n
            CrHome    =   '通算本塁打'n
            CrRuns    =   '通算得点'n
            CrRbi     =   '通算打点'n
            CrBB      =   '通算四球'n
            League    =   'リーグ'n
            Division  =   '地区'n
            Position  =   'ポジション'n
            nOuts     =   '刺殺'n
            nAssts    =   '補殺'n
            nError    =   'エラー'n
            Salary    =   '年俸(千ドル)'n
            Div       =   'リーグと地区'n
            logSalary =   '対数年俸'n
        ));
    set sashelp.baseball ;
run;
proc contents data=work.baseball varnum ;
run;

GLMSELECT プロシジャの使い方

GLMSELECT プロシジャは、 SAS/STAT 13 で追加されたプロシジャです。基本的な構文は REGGLM プロシジャと同じですが、 MODEL ステートメントのオプションで変数選択の方法をいろいろと細かく指定できます。REGGLM プロシジャにも変数選択の機能がありますが、 GLMSELECT はこれらの拡張版といえます。この GLMSELECT プロシジャを使って、メジャーリーガーの年俸予測式を作ってみましょう。

まず、ステップワイズ法+AICで回帰モデルに使用する変数を決めてみます。model 文の後に / selection=stepwise(select=AIC) というオプションを入れることで実行できます。これは、変数選択はステップワイズ法を用いて、選択の基準は AIC で判断する、ということです。増加法ならば forward, 減少法なら backward になります。



proc glmselect data=work.baseball plots=all ;
    class リーグ 地区 チーム ポジション ;
    model 対数年俸 = 打席数 安打 本塁打 得点 打点 四球 MLB年数 通算打席数 通算安打 通算本塁打 通算得点 通算打点 通算四球 刺殺 補殺 エラー リーグ ポジション 地区 チーム
            / selection=stepwise(select=AIC) details=all stats=(adjRsq AIC AICC SBC) ;
run ;

plots=alldetails=all は最小限の結果だけを見たい場合は不要です。さらに、stats= オプションで他の指標もグラフに表示させ、比較しています。 namelen=200 は、変数名を日本語にすることで表示がおかしくなるのを防ぐために追加しました。stats= オプションで表示しているのは、adjRsq は調整済みR2乗、AICC有限修正AICといい、レコード数が少ない場合にAICより精度が高くなるといわれています。SBC は BICのことです。紛らわしいのですが、 GLMSELECT では BIC と指定すると、シュワルツの BIC ではなく、佐和のベイジアン情報量規準が指定されてしまいます。佐和のBICは名前に反してむしろAICに近い指標ですが、ほとんど使われているのを見たことがないので、以降も文中でBICと言ったらシュワルツのことだと考えてください。修正済み R2 乗は通常の R2 乗よりも過剰適合に強い指標ですが、理論上、予測性能を保証するものではないので、理論的に裏付けのある情報量規準を使うべきです。

先のプログラムを実行すると、以下のようなグラフが表示されます。


ステップワイズ+AICの結果
変数の増加にともない、各指標がどう推移していったかがわかります。AICとAICCは増加に伴い小さくなっていくのに対し、BICは4つ目の変数追加のときに最小となっています。

次に、LOOCV で変数選択を行った場合は以下のようになります。

proc glmselect data=work.baseball plots=all namelen=200 ;
    class リーグ 地区 チーム ポジション ;
    model 対数年俸 = 打席数 安打 本塁打 得点 打点 四球 MLB年数 通算打席数 通算安打 通算本塁打 通算得点 通算打点 通算四球 刺殺 補殺 エラー リーグ ポジション 地区 チーム
            / selection=stepwise(select=press) stats=(adjRsq AIC AICC SBC) ;
run ;

ステップワイズ+LOOCVの結果
今度は 11個の変数が選ばれています。AICやBICを見ると違いがよくわかります。ホールドアウトの場合はオプションに selection=stepwise(select=validate) と指定します。また、データセットを訓練データと学習データに分ける必要があります。ここでは、無作為に3割のレコードをテストデータに割り当てる方法を紹介します。オプションではなく partition ステートメントを使うことで設定できます。

proc glmselect data=work.baseball plots=all namelen=200 ;
    class リーグ 地区 チーム ポジション ;
    model 対数年俸 = 打席数 安打 本塁打 得点 打点 四球 MLB年数 通算打席数 通算安打 通算本塁打 通算得点 通算打点 通算四球 刺殺 補殺 エラー リーグ ポジション 地区 チーム
            / selection=stepwise(select=validate) details=all ;
            partition fraction(validate=.3) ;
run ;

さらに10分割CVの場合は、

proc glmselect data=work.baseball plots=all namelen=200 ;
    class リーグ 地区 チーム ポジション ;
    model 対数年俸 = 打席数 安打 本塁打 得点 打点 四球 MLB年数 通算打席数 通算安打 通算本塁打 通算得点 通算打点 通算四球 刺殺 補殺 エラー リーグ ポジション 地区 チーム
            / selection=stepwise(select=cv) cvmethod=random(10) details=all ;
run ;

となります。cvmethod= はデータセットの分割方法の指定で、randam(10) は無作為に10グループに分けるという意味です。

なお、R2乗で変数選択した場合はこのようになります。
全変数
R2乗はどのような変数を追加しても値が改善されるため、すべての変数を含む結果になりました。明らかにLOOCVや情報量規準の結果とは異なります。

GLMSELECTでは他にもいろいろな方法を使えますが、今回は情報量規準と交差検証法を利用する方法だけを紹介しました。

2016/7/29 片桐

参考文献

  1. 赤池弘次 他 (2007)「赤池情報量規準 AIC―モデリング・予測・知識発見― 」共立出版
  2. 小西貞則・北川源四郎 (2004) 「情報量規準」朝倉書店
  3. Gelman, Andrew et al. (2009) Bayesian Data Analysis, 3rd Ed., CRC Press
  4. SAS Institute Inc. (2015) SAS/STAT(R) 14.1 User's Guide

  1. 少し詳しい方なら、ジャックナイフ法やブートストラップ法と同じ発想だとわかるでしょう。
  2. ただし、実はこの計算を簡単にする方法があります。
  3. 変数選択にはF統計量に対応するp値を使用するという伝統的なやり方がありましたが、現在ではこれは問題があることが分かっているので、使用しないほうがよいです。
  4. 最新のバージョンでないと入っていない可能性がありますが、SAS University Edition なら入っているはずです。
  5. 期待していたら申し訳ないのですが、株で儲ける方法をテーマにする予定はありません。

0 件のコメント:

コメントを投稿

ツイート数からみる"バーチャルYouTuber"ブーム

今や YouTuber の話題の半分を占めるほどのクチコミ数に 当社が提供するソーシャルビッグデータ検索ツールの「 beInsight (ビーインサイト)」を使って、話題の「バーチャル YouTuber 」について調べてみました。 「バーチャル YouTuber...