14分SHAREツイートシェアはてブLINEPocketこんにちは、データサイエンティストのたぬ(@tanuhack)です!重回帰分析は『数字の予測』や『優先順位付け』に強く、ビジネスシーンにおけるデータ分析の中で、最も多用されている分析手法です。定数項(切片)数式だけだとわかりにくいと思うので、具体例を踏まえ考えてみましょう。説明変数として、重回帰分析を行った結果、次のような回帰式が得られました。築年数10年だったとすると...。77,000(円)上のように重回帰分析によって得られた回帰式によって、77,000円くらいと大まかな家賃を予測することができます。Pythonで重回帰分析をする方法として、scikit-learnを用いる方法とStatsModelsを用いる方法の2つが存在しますが、前者の方法では解析の結果から得られた重回帰式の精度を表す各指標が見れないので使いません。さいごにStatsModelsモジュールの使い方まず、ターミナルからStatsModelsモジュールをインストールします。statsmodels以下のプログラムは、StatsModelsを使う上でのテンプレです。変数名を入れ替えて見て下さい。重回帰分析の結果を表示result.summary()それでは、実際にデータセットを用いてStatsModelsモジュールの挙動を確かめてみましょうデータセットの確認データセットは、SIGNATE(シグネイト)と呼ばれる日本版kaggleの勉強用に提供されているお弁当の需要予測データを使用します。気温また、このCSVファイル名をtrain.csvとして保存し、pandas.DataFrameのメソッドread_csv()でdf変数に取り込んだものとします。時系列に沿った、お弁当の販売個数の推移を折れ線グラフで確認しておきましょう。title='時系列に沿ったお弁当の販売個数推移')StatsModelsで重回帰分析STEP1:複数の説明変数を選ぶまず手始めに、説明変数『week』と『temperature』が、目的変数の『お弁当の販売個数』に影響があるのか、重回帰分析してみます。重回帰分析を行う前に確認しないといけないのが、説明変数の中に質的データが含まれているかどうかです。今回のパターンでは、説明変数『week』が質的データでした。選んだ説明変数の中に質的データが含まれる場合、そのままでは重回帰分析できないので、ダミー変数化という処理を行います。ダミー変数化とは質的な説明変数を表現するための0か1かの二値変換させることSTEP3:質的データをダミー変数化させる質的データをダミー化させる方法として、pandas.DataFrameのメソッドget_dummies()を用います。pd.get_dummies(df[['temperature','week']])get_dummies()の偉いところは、質的だった場合ダミー変数化して量的だった場合そのまま、自動でやってくれることですね。重回帰分析の結果を表示するresult.summary()(わあ、何かいっぱい出てきましたね...!)結果の見方summary()によって、解析結果が表示されたら、まず最初に見るべき3つの指標があります。R-squared:自由度調整済み決定係数』を確認するこの値は、一般的に『自由度調整済み決定係数』と呼ばれ、回帰式全体の精度、説明力を示しています。R-squared)』の方を使いましょう。今回の自由度調整済み決定係数は0.447で、なんとも言えない精度ですね。目標は0.85くらいだと言われています。この数値の結果から、説明変数の選定が十分ではないことが分かります。STEP2:『t:各説明変数ごとの統計量』を確認するこの数値の絶対値が大きければ大きいほど、目的変数に与える影響が大きいという指標になります。sm.add_constant(x)で生成した『y切片』のことなので、無視して大丈夫です。時点でt値の絶対値が高いのは、temperatureであるのが分かります。『気温が上がればお弁当の販売個数は減る』ことに関係がありそうですね。STEP3:『p>|t|:各説明変数ごとのp値』を確認するこのカラムには、1つ1つの説明変数毎のp値が表示されています。p値の説明は不要だと思いますが、念のために...。p値は、0に近づけば近づくほど統計的な意味があり、逆に0.05よりも大きい値であればたまたまである可能性が高いとして、その説明変数は採用しないほうが良いとされています。今回はすべて、0.05より低い値なので、全部説明変数として採択しても大丈夫そうですね。結果から回帰式を作る今回選んだ説明変数の重回帰分析で得られた、自由度調整済み決定係数の値は44%と精度は低いですが、とりあえず結果から回帰式を作る方法を紹介します。『coef』に注目します。0)=93.17859999999999気温20度で月曜日だった場合、93個くらい売れそうだなと予測を立てることができます!(精度44%ですが、笑)ちなみに精度44.7%のグラフは下図のようになります。次からは、重回帰分析の精度を上げるためにした方がいい方法を紹介します。重回帰分析の精度を上げる精度が低いモデルを作成しても何の価値もありません。質の高いアウトカム(因果関係の推察、未来の予測)を実現するためには、モデリング(重回帰分析)にかける前のデータの質が大切になってきます。『データの質を上げる』とは、モデリングの精度を上げることであり、その精度を上げるためにはデータの整形すなわち『前処理』が大切です。データ分析の8割は、前処理だと言っても過言ではないでしょう。この泥臭い前処理を怠らず分析の精度の質を高めていくことこそが、データ分析する人の使命であり、力量が試されます。説明変数の候補がたくさんあれば、『とりあえずすべての説明変数を重回帰分析にかけてp値が小さく、t値の絶対値が大きいものを探索する』というやり方をステップワイズ法と言います。このときのp値は0.05以下ではなく、0.1以下で見ることが慣例のようです。重回帰分析の結果を表示するresult.summary()説明変数を闇雲に増やすと重回帰式の精度は、44%→63%まで向上しました。重回帰分析の結果を表示するresult.summary()不要な説明変数を削除すると重回帰式の精度は、63%→71%まで向上しました。title='精度71.6%のグラフ')ステップワイズ法で重回帰分析の精度を上げていく様子が何となく掴めたのではないでしょうか。説明変数が多いと、ステップワイズ法だけ使っても精度の高いモデルを作ることは中々できません。そこでおすすめしたいのが、ステップワイズ法に『仮説』を取り入れた方法です。具体的にどうやって仮説を思いつくかと言うと、『データの可視化』を行い、傾向や偏り、変曲点、スパイクを目で捉えます。STEP1:データの可視化により仮説を立てる下の折れ線グラフからどういう仮説を立てられるでしょうか。時間が経つに連れ、販売個数は減少傾向→気温や天候で販売個数に影響がある?お弁当が異常なまでに売れている日がある→この日は何かいつもと違うことがあったのでは?4月以降スパイクが目立つがそれ以前はそれほどではない→4月以降に始まった新しい施策がある?などなど...。これら以外にもいろんなことが考えられます。正解なんてないので、考えられる限りを書き出してみてくださいね。他にもいろんなデータの可視化の手段があります。2変量の相関関係を知りたいSTEP2:仮説から販売個数に影響がありそうなものを見つける仮説を元に説明変数を探していると、どうやらメニュー名に『カレー』が含まれるか否かで販売個数に影響がありそうです。メニュー名に『カレー』を含まないdf[df['name'].str.match('^(?!.*カレー).*$')]['y'].mean()STEP3:説明変数に追加する今回でいうと、name列にカレーという文字があれば1を無ければ0を返すcurry列を作ります。pandas.Seriesのメソッドapply()を使って、1行ずつ追加させます。重回帰分析の結果を表示するresult.summary()ステップワイズ法+仮説で、重回帰式の精度は71%→78%まで向上しました。『ステップワイズ法+仮説』を使って、モデルの精度が高く目的変数に影響がある複数の説明変数を見つけることができました。絶対値が大きいものだと紹介しましたね。絶対値が大きいから」といって、それが一番重要な説明変数かと言われると、そうではありません。7例えば、上の表のような結果が得られたとします。『どれぐらい説明変数を動かせる余地があり、また実際に説明変数をどれくらい動かせる手段があるのか』を考えなければなりません。「temperatureとかweekとかweatherが統計量が高いので、これらが重要な説明変数です。」と報告されても、人間である以上天候や曜日を自在に操ることはできないので、果たしてこの分析結果は正しいと言えるでしょうか?どう考えても、言えないですよね。この結果の場合の重要な説明変数は、name(お弁当の名前)です。メニューを分析して、明らかに好まれているメニューとそうではないメニューを見つけ出し、変えていくことがお弁当の販売個数に対して、『最大効果』は低いかもしれませんが、確実にインパクトを与えられますね。重回帰分析で注意することステップワイズ法と仮説を組み合わせて、重回帰分析の精度を上げる方法を紹介しました。精度だけ上げればそれでいいか、と言われればそうでもありません!!!重回帰分析には、これから紹介する落とし穴が2つ存在します。それぞれ見てみましょう。過学習(オーバーフィッティング)多重共線性(マルチコ)過学習(オーバーフィッティング)基本的に説明変数が増えれば増えるほど、重回帰式の精度は高くなると紹介しましたが、それだけがいいことばかりとは限りません。当てはめの精度は高いのに、予測精度が低くなることを過学習(オーバーフィッティング)と言います。過学習になる原因は、『手持ちデータ』に過剰に適合しすぎたモデルを構築してしまったことです。なると、いまある『検証用データには当てはまりが良い』が『予測したい新しいデータに回帰式を当てはめると、当てはまりが悪くなる』といった減少が起きてしまいます。過学習を回避するためには一般的に次に紹介する『クロスバリデーション法』を用います。使用したデータセットには、回帰式を求める『train.csv』と当てはまりの良さを確認する『test.csv』の2つが用意されているので、test.csvを使います。テスト用のデータセットがない場合1つのデータを完全ランダムに半分抽出し、片方のデータで回帰式を求め、もう片方のデータで当てはまりの良さを検証するやり方を用います。(回帰式60%、テスト40%とかでも大丈夫です。df.drop(train.index)ただ、完全ランダムだと『時間の経過』などを説明変数に入れたい場合、不向きです。時系列データの場合は、時間順にソートされているのを確認して半分にデータを分けた方が良いかもしれませんね。df.drop(train.index)重回帰式で得られた予測値をテストデータに代入させるStatsModelsのメソッドformula.api.OLS().fit().predict()を使えば、予測値を求めることができます。ステップワイズ法+仮説で作ったプログラムで試してみます。重回帰分析の結果を表示するresult.summary()テストデータと回帰式を作るデータは、全く同じ説明変数を揃えなければいけません。(ここでエラーが発生したら説明変数が足りていません。predこの例で言うと、予測値がずれまくってることは無いと判断できます。(ひどいときはマイナスがついたり、桁がおかしかったりします)こんな感じで、回帰式を求めるデータとテストデータ間で大きな乖離が無いか確認すれば、過学習に気づいて、より精度の高い重回帰式を作ることができるでしょう!多重共線性(マルチコ)多重共線性とは、説明変数間で非常に強い相関があることを指し、この値が大きいと回帰係数の分散が大きくなり、モデルの予測結果が悪くなることが知られています。重回帰分析を行う目的が『因果関係の洞察』ではなく、『予測』であれば、気にしなくて大丈夫です。No.が多重共線性をチェックする指標になります。非常に大きい数字になっているので、多重共線性の可能性が大いにありえます。Factor)というものがあります。Pythonでは、StatsModelsのメソッドstatsmodels.stats.outliers_influence.variance_inflation_factorを使って、VIFを計算できます。columns=['VIF'])一般的にVIFの値が10(公式のリファレンスでは、5)を超えると、依存関係が強いため、適切な重回帰分析ができないと言われています。今回でいうと、ダミー変数化で作成した『week』の列のVIF値がすべて『inf』となっており、依存関係が非常に強いです。繰り返しになりますが、重回帰分析の目的が『因果関係の洞察』であれば説明変数から除外したほうが無難であり、『予測』が目的であれば除外しなくても大丈夫です。さいごに今回はPythonのStatsModelsモジュールで重回帰分析をして、その精度を上げていく方法を紹介しました。説明変数の選択は、ステップワイズ法+仮説で行い、過学習と多重共線性に気を付けていれば、概ねうまくいきます。:Pythonこの記事を書いた人たぬ効率沼ブロガールーチンワークを自動化で瞬殺することに人生の楽しさを見つけた効率沼ブロガーです。本業は「データ分析」と「作業の効率化」を生業としているデータアナリスト。PythonとGASに人生救われました。当ブログは、おかげさまで月間12万PV。2020年までに30万PV目指して頑張ってます。