はじめに
何となく、株価の予想をしてみたいと思いました。機械学習の種類についての勉強の記事で調べた通り、株価などの予想には回帰分析が有効であるとのことなので、今回は回帰分析の中で一番単純な単回帰分析について勉強しました。実装に使用した言語はpytohn3です。
回帰分析とは
参考にしたサイトでは回帰分析について、次のような説明がされていました。
回帰分析とは、説明変数 $x$によって目的変数$y$の変動を $y=f(x)$の形でどの程度説明できるかを分析する手法です。 この回帰分析を行う目的としては、例えば、気象データ(説明変数x)とソフトクリームの販売量(目的変数y)がどのような関係になっているかを調べることで、予測を行うものです。
①数値の予測(xの値からyの値を予測する)
②要因分析(yに影響を与えているxを探し、その影響量を測る)
が挙げられる。
①、②の具体例については引用元のサイトを見ていただけると分かりやすいです。
また、$y=f(x)$の式のことを回帰方程式や回帰式と呼ぶみたいです。
そして、回帰分析の中で、説明変数xが1つだけの回帰式のことを単回帰分析といいます。代表的なものとしては$y=ax+b$という1次関数があります。この$y=ax+b$という式を求める方法の一つに最小二乗法というものがあります。今回はこの最小二乗法について説明します。
最小二乗法
最小二乗法の考え方としては単回帰分析・最小二乗法の公式はどうすれば求められるのか。統計上の誤差と残差の違いの説明が分かりやすかったので、詳しく知りたい方は参考にしてください。簡単に株の例で説明すると、最小二乗法を使うことで、株価チャートの中に最もらしいy=ax+bの関数を見つけることが出来ます。このy=ax+bがわかることで、株価のトレンドが分かるのではないかと考えています。図1にイメージを示します。
図1:株価チャートとy=ax+bのイメージ |
(図1のy=ax+bは手書きのため、適当です)
傾き(aの値)がプラスだと、上昇トレンド、マイナスだと下降トレンド、0に近いと横ばいであることが分かります。また、傾きが分かることで、現在のトレンドの大きさについても定量的に評価することが出来ます。
株価データの準備
今回はquandlで提供されている日経平均株価を使います。このquandlですが、一日に利用できる回数に制限があるみたいなので、株価データを取得したらcsvなどに出力した方がいいかもしれないです。
~(補足)~
quandlに登録することで、この制限が解除されるみたいです。
~(補足)~
quandlに登録することで、この制限が解除されるみたいです。
また、quandlは別途インストールする必要があるので、コマンドライン上でpipを使ってインストールしてください。
>pip install Quandl
quandlの準備が出来たところで、実際に日経平均株価を取得し、中身の確認をしてみましょう。
中身を見てみると次のようになりました。
1950年から現在の株価までがあります。しかし、古いデータは一部NaNになっています。
とりあえず、終値はすべて載っていたので、終値だけで株価グラフを作成します。import quandl data = quandl.get("NIKKEI/INDEX")#日経平均株価の取得 print(data)
1950年から現在の株価までがあります。しかし、古いデータは一部NaNになっています。
import quandl import pandas as pd import matplotlib.pyplot as plt import seaborn data = quandl.get("NIKKEI/INDEX")#日経平均株価の取得 data_date = pd.to_datetime(data["Date"])#日付データが文字列だったので変換 data_close = data["Close Price"]#終値の取得 plt.plot( data_date,data_close) plt.xlabel("Year") plt.ylabel("Yen") plt.show()
図2:日経平均株価の終値(1950~2018年) |
株価データを用いて単回帰分析
最小二乗法
まず初めに、最小二乗法を使って単回帰分析をやってみます。
最小二乗法にはscipyの中にあるcurve_fit関数を使います。使い方は以下の通りです。
from scipy.optimize import curve_fit def func_liner(x,a,b): return a*x+b #ここに最小二乗法でフィッティングする関数を記述 param,cov = curve_fit(func_liner, x, y)
curvefitの返り値はaとbの値が入っているparamと、共分散が入っているcovがあります。
今回はparamのみ使います。実際に株価と最小二乗法で求めた直線をプロットしてみます。コードは以下の通りです。
図3の青線が日経平均株価で、緑色の線が最小二乗法で求めた直線です。
ちなみにこの時のaは1.2256746、bは-761.22523731でした。この結果より、1950年から2018年まで、上昇トレンドであることが分かります。ただ、1990年付近の値が求めた直線と大きく乖離していることから分かる通り、短期的な予測には向いていません。
今回はparamのみ使います。実際に株価と最小二乗法で求めた直線をプロットしてみます。コードは以下の通りです。
import quandl import pandas as pd import matplotlib.pyplot as plt import seaborn from scipy.optimize import curve_fit def func_liner(x,a,b): return a*x+b #ここに最小二乗法でフィッティングする関数を記述 data = quandl.get("NIKKEI/INDEX")#日経平均株価の取得 data_date = pd.to_datetime(data["Date"]) data_close = data["Close Price"] data_num = range(0,16997)#最小二乗法で使うx軸の値(data_closeの要素数と一致) param,cov = curve_fit(func_liner, data_num, data_close)#最小二乗法によるフィッティング fitting = param[0]*data_num+param[1]#求めたa、bの値を元にy=ax+bの直線を作成 plt.plot(data_date,data_close,label="NIKKEI") plt.plot(data_date,fitting,label="fitting",lw=5) plt.legend() plt.xlabel("Year") plt.ylabel("Yen") plt.show()
図3:日経平均株価と最小二乗法で求めた直線 |
ちなみにこの時のaは1.2256746、bは-761.22523731でした。この結果より、1950年から2018年まで、上昇トレンドであることが分かります。ただ、1990年付近の値が求めた直線と大きく乖離していることから分かる通り、短期的な予測には向いていません。
Scikit-learnのLinerRegression
Scikit-learn内にあるLinerRegressionを使うことで単回帰分析を行うことが出来ます。
sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False,copy_X=True, n_jobs=1)
ここで一つ注意しなければいけないのは、LinerRefressionに用いるデータはdataframe型にする必要があります。実際にLinerRegressionを用いて回帰分析したコードを下に示します。
import pandas_datareader.data as web import quandl import pandas as pd import matplotlib.pyplot as plt import seaborn from sklearn import linear_model data = quandl.get("NIKKEI/INDEX") data_date = pd.to_datetime(data["Date"]) data_num_df = pd.DataFrame(list(range(0,16997)))#data_closeと同じデータ数をdataframe型で用意 # data_close = data["Close Price"]#こっちはseriesシリーズ data_close_df = data[["Close Price"]]#これでdataframe型となる model = linear_model.LinearRegression()#モデルを作成 model.fit(data_num_df, data_close_df)#学習 py = model.predict(data_num_df) plt.plot(data_date,data_close,label="NIKKEI") plt.plot(data_date,py,label="LinearRegression",lw=5) plt.legend() plt.xlabel("Year") plt.ylabel("Yen") plt.show()
図4:日経平均株価とLinerRegressionで求めた直線 |
LinerRegressionでは次のようにすることで傾きなどが分かります。
print(model.coef_)#編回帰係数(傾き) print(model.intercept_)#切片 print(model.score(data_num_df,data_close_df))#決定係数
傾きについては先ほどの値と一致していますが、切片は若干異なるものとなりました(気にするほどの違いではないですが)。また、決定係数は0.5124441166033344となりました。この決定係数は予測した直線と元のデータがどのくらい一致しているかを表しているものみたいで、1に近いほどいいみたいです。
まとめ
今回は日経平均株価を最小二乗法とScikit-learn内にあるLinerRegressionを用いて単回帰分析を行いました。とりあえず、株価のトレンドが分かるようになったので、今後はもう少し詳しく株価の分析を行ってみたいと思います。
0 件のコメント :
コメントを投稿