重回帰分析による米雇用統計の予測モデルを作成してみる

Python
スポンサーリンク

この記事はPython その2 Advent Calendar 2015 の17日目の記事です。

1 はじめに

雇用統計のモデルで有名なにほんばっしー(現在活動停止中?)が公開していた予想方法を元に、雇用統計の数値を予想するモデルを作成してみます。

2 モデル作成

2.1 使用する指標

ザイのリンクからにほんばっしーが使っていた指標は以下となっています。

このうち、無料では入手が困難だったカンファレンスボード関連の消費者信頼感指数の「雇用不十分」、「雇用困難」を除いた指標を使うことにします。まとめたデータを公開したいのですが、二次公開には色々と成約が付きまとうので今回は残念ながら公開できません。代わりにリンクをまとめておきます。

ここでは、"Summery Of Indexes.xlsx"というエクセルファイルにデータを保存しました。

2.2 単純に重回帰分析をしてみる

"Summery Of Indexes.xlsx"のファイルのTrainというシートのデータを取得します。

import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt

data_table = pd.read_excel("Summary Of Indexes.xlsx", sheetname="Train")
data_table.head()

statsmodels.api.OLSを使えば、簡単に重回帰分析をした結果を取得できます。

# Read Data
y = data_table[u"新規失業保険申請者数"]
x = data_table[[u"NY連銀雇用", u"フィラデルフィア連銀雇用", u"ミシガン大指数", u"カンザスシティ連銀雇用", 
                u"ダラス連銀雇用", u"リッチモンド連銀雇用", u"ISM製造雇用", u"S&P500 変化率1ヶ月遅行", u"ADP雇用統計", 
                u"チャレンジャー人員削減数"]]model = sm.OLS(y, x)
model = sm.OLS(y, x)
results = model.fit()
results.summary()

結果をプロットしてみます。

import matplotlib.pyplot as plt
plt.plot(results.predict(), "r")
plt.plot(y, "b")

chart1

青が実際の値で、赤が予測値です。

パッと見でなんとなくいけてなさそうですが、訓練データとしてしか使っていないのでこれだけでは実際の予測能力の評価ができません。

2.3 交差検証(Cross Validation)する

訓練データとテストデータに分けて評価してみます。あまりデータ数がないので、Leave One Out Cross Validation を用いることにします。

Leave One Out はscikit-learnに便利な module LeaveOneOut が提供されているのでそれを用いることにします。

from sklearn.cross_validation import LeaveOneOut

LeaveOneOut検証を行った後の結果を返す method を作成します。targetに予想したい結果を入れて、予想に使う要素をinputsに入れます。

def make_prediction(target, inputs):
    loo = LeaveOneOut(len(data_table))
    predict_results = []
    for train, test in loo:
        train_table = data_table.iloc[train]
        test_table = data_table.iloc[test]
        y_train = train_table[target]
        x_train = train_table[inputs]

        y_test = test_table[target]
        x_test = test_table[inputs]

        model = sm.OLS(y_train, x_train)
        result = model.fit()
        calc_prediction = (result.params * x_test)
        prediction = calc_prediction.sum().sum()
        predict_results.append(prediction)
    return predict_results
target = u"雇用統計結果"
inputs = [u"新規失業保険申請者数", u"NY連銀雇用", u"フィラデルフィア連銀雇用", u"ミシガン大指数", u"カンザスシティ連銀雇用", 
          u"ダラス連銀雇用", u"リッチモンド連銀雇用", u"ISM製造雇用", u"S&P500 変化率1ヶ月遅行", u"ADP雇用統計", 
          u"チャレンジャー人員削減数"]

predicts = make_prediction(target, inputs)
actuals = data_table[u"雇用統計結果"]
forecasts = data_table[u"雇用統計予想値"]
import matplotlib.pyplot as plt
plt.plot(predicts, "r")
plt.plot(actuals, "b")
plt.plot(forecasts, "g")

chart2

predicts にはLeaveOneOut検証によって得られた結果だけを格納されています。全然いけてないですね・・。

2.4 アナリスト予想に対する方向性の精度を検証

一応、アナリストの予想値と結果の方向性をどのぐらい予想出来ているかを計算してみます。

# calc predictive accuracy
def accurates_and_faults(predicts, actuals, forecasts):
    accurates = 0
    faults = 0
    for p, a, f in zip(predicts, actuals, forecasts):
        if (f  p):
                faults += 1
        elif(f > a):
            if(f > p):
                accurates += 1
            elif(f 
accurates, faults = accurates_and_faults(predicts, actuals, forecasts)
print "accurates: %d, faults: %d accurate ratio: %f"%(accurates, faults, accurates * 1.0 / (accurates + faults))
# accurates: 59, faults: 52 accurate ratio: 0.531532

予想値と結果のずれの方向性を59回的中させ、52回失敗し、的中率は53%となりました。

2.5 アナリスト予測に対する精度を検証

これもまた一応ですが、結果とのずれ具合を検証してみます。

def calc_diff(inputs, targets):
    diff_sum = 0
    for i, t in zip(inputs, targets):
        diff_sum += abs(t - i)
    return diff_sum

sum_diff_predict = calc_diff(predicts, actuals)
sum_diff_forecast = calc_diff(forecasts, actuals)
print "difference against forecasts: %f"%(sum_diff_predict*1.0 / sum_diff_forecast)
# difference against forecasts: 3.394691

アナリストの予想に対し、今回のモデルの予想精度は約3.4倍劣る結果となりました。

3 作りこんでいけば・・

Cross Validation で使うべき要素を選別、精度を高めていけば、それなりに予測能力を持つモデルを作成できるようになります。下が実際に作成しているモデルから得られた出力例です。独自に追加した要素などを使えば、このぐらいの精度までは出せました。今のところ、2回連続的中しています。

WS000005_1

3.1 実際に予想した結果

11月

https://twitter.com/fx_kirin/status/662107829646417920

https://twitter.com/okasanman/status/662622972822224896

12月

https://twitter.com/fx_kirin/status/672617841145741312

https://twitter.com/okasanman/status/672769835625922560

ipython データ

NFP Linear Reguression

あとがき

なんか書いてみるとあんまりPython関係ないのかなと思ったり思わなかったり。こういう情報って使えるもの出すと色々怖いので、丁度いい案配だったんじゃないかなぁと思います。

コメント

タイトルとURLをコピーしました