重回帰分析を行います
では、今回は、株価(時価総額)を予測するために重回帰分析を利用してみます。
入力変数としては、時価総額に影響を与えそうな項目を適当に選んでみました。
項目名 | 説明 |
---|---|
営業利益(百万円) | 会社が本業で稼いだ利益のこと |
PBR(実績) | 会社の純資産と株価の関係 |
BPS(実績) | 1株当たり純資産 |
自己資本(百万円) | 出資者から調達した資本金と,内部留保 (剰余金) から成る。 |
ROE | 株主資本に対する当期純利益の割合 |
ROA | 総資産に対してどれだけの利益が生み出されたのかを示す |
では、ここから実際にソースを書いていきます。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.set_printoptions(precision=3, suppress=True) #指数表示の禁止
データの読み込み
今回使用するデータは、時価総額があるCSVと経常利益があるCSVが別々なのでそれぞれ別に読み込みます。
df1 = pd.read_csv(filepath_or_buffer="~\japan-all-stock-data.csv", encoding="ms932", engine="python", sep=",")
df2 = pd.read_csv(filepath_or_buffer="~\japan-all-stock-financial-results.csv", encoding="ms932", engine="python", sep=",")
df1.head(3)
SC | 名称 | 市場 | 業種 | 時価総額(百万円) | 発行済株式数 | 配当利回り | 1株配当 | PER(予想) | PBR(実績) | EPS(予想) | BPS(実績) | 最低購入額 | 単元株 | 高値日付 | 年初来高値 | 安値日付 | 年初来安値 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 日経225(日経平均株価) | 東証 | 株価指数 | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
1 | 2 | TOPIX(東証株価指数) | 東証 | 株価指数 | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
2 | 1301 | 極洋 | 東証一部 | 水産・農林 | 42948 | 10928283 | 1.53 | 60.00 | 15.29 | 1.49 | 257.01 | 2644.98 | 393000 | 100 | 2018/1/10 | 4460 | 2017/1/18 | 2681 |
df2.head(3)
SC | 名称 | 決算期 | 決算発表日(本決算) | 売上高(百万円) | 営業利益(百万円) | 経常利益(百万円) | 当期利益(百万円) | 総資産(百万円) | 自己資本(百万円) | 資本金(百万円) | 有利子負債(百万円) | 自己資本比率 | ROE | ROA | 発行済株式数 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2788 | アップルインターナショナル | 2017/12 | 2018/02/19 | 13634 | 325 | 335 | 204 | 8230 | 7357 | 4322 | 1476 | 89.40 | 2.86 | 2.58 | 13841400 |
1 | 5101 | 横浜ゴム | 2017/12 | 2018/02/19 | 668049 | 51933 | 52887 | 35217 | 929029 | 383925 | 38909 | 315916 | 41.30 | 9.61 | 3.84 | 169549081 |
2 | 6278 | ユニオンツール | 2017/12 | 2018/02/19 | 23188 | 3698 | 3718 | 2655 | 57605 | 52440 | 2998 | - | 91.00 | 5.22 | 4.81 | 20788590 |
# 結合
df_merged = pd.merge(df1, df2, how='inner', on='SC')
df_merged.head(3)
SC | 名称_x | 市場 | 業種 | 時価総額(百万円) | 発行済株式数_x | 配当利回り | 1株配当 | PER(予想) | PBR(実績) | ... | 経常利益(百万円) | 当期利益(百万円) | 総資産(百万円) | 自己資本(百万円) | 資本金(百万円) | 有利子負債(百万円) | 自己資本比率 | ROE | ROA | 発行済株式数_y | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1301 | 極洋 | 東証一部 | 水産・農林 | 42948 | 10928283 | 1.53 | 60.00 | 15.29 | 1.49 | ... | 3709 | 2422 | 97391 | 24976 | 5664 | 50919 | 25.60 | 10.19 | 2.52 | 10928283 |
1 | 1332 | 日本水産 | 東証一部 | 水産・農林 | 171524 | 312430277 | 1.46 | 8.00 | 8.55 | 1.22 | ... | 24884 | 14216 | 451876 | 120973 | 30685 | 207749 | 26.80 | 13.17 | 3.17 | 312430277 |
2 | 1333 | マルハニチロ | 東証一部 | 水産・農林 | 169292 | 52656910 | 1.24 | 40.00 | 10.92 | 1.46 | ... | 27874 | 15446 | 501303 | 100664 | 20000 | 272208 | 20.10 | 16.62 | 3.13 | 52656910 |
3 rows × 33 columns
# 欠損値を削除していきます。
# 対象のデータでは、欠損値が「-」で登録されているので「-」以外の行を対象にします。
df_removed = df_merged[df_merged['経常利益(百万円)'] != '-']
df_removed = df_removed[df_removed['営業利益(百万円)'] != '-']
df_removed = df_removed[df_removed['当期利益(百万円)'] != '-']
df_removed = df_removed[df_removed['PBR(実績)'] != '-']
df_removed = df_removed[df_removed['BPS(実績)'] != '-']
df_removed = df_removed[df_removed['自己資本(百万円)'] != '-']
df_removed = df_removed[df_removed['ROE'] != '-']
df_removed = df_removed[df_removed['ROA'] != '-']
len(df_removed)
3553
# 各カラムを数値に変換します。
df_removed = df_removed.astype({'SC':'object', '経常利益(百万円)':'int', '営業利益(百万円)':'int', '当期利益(百万円)':'int', '時価総額(百万円)':'int','経常利益(百万円)':'int','PBR(実績)':'float','BPS(実績)':'float','自己資本(百万円)':'int','ROE':'float','ROA':'float'})
df_removed.dtypes [['経常利益(百万円)', '営業利益(百万円)', '当期利益(百万円)', '時価総額(百万円)','経常利益(百万円)','PBR(実績)','BPS(実績)','自己資本(百万円)','ROE','ROA']]
経常利益(百万円) int32
営業利益(百万円) int32
当期利益(百万円) int32
時価総額(百万円) int32
経常利益(百万円) int32
PBR(実績) float64
BPS(実績) float64
自己資本(百万円) int32
ROE float64
ROA float64
dtype: object
# 営業利益がマイナスでないデータのみを対象とする
df_target = df_removed[df_removed['営業利益(百万円)'] > 0]
from sklearn.linear_model import LinearRegression
モデルを作成し予測する
線形回帰を実施するために、「LinearRegression」というモデルを利用します。
各引数は、このような意味があります。
引数名 | 説明 | デフォルト |
---|---|---|
fit_intercept | 切片を求める計算を行うかどうか設定します。Falseを設定する場合は、すでに中心化されたデータを扱う必要があります。 | True |
normalize | 正規化するかどうか | False |
copy_X | メモリにデータをコピーしてから読み込むかどうか | True |
n_jobs | 使用するジョブの数 | 1 |
# モデルを作成
model = LinearRegression(fit_intercept=True, normalize=True, copy_X=True, n_jobs=1)
準備したデータの半分を訓練用データとします。
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df_target[['営業利益(百万円)','PBR(実績)','BPS(実績)','自己資本(百万円)','ROE','ROA']], df_target['時価総額(百万円)'], test_size=0.5)
len(X_train), len( X_test)
(1647, 1648)
# モデルを訓練する
# 第一引数は、説明変数で行列で指定する必要があります。
# 第二引数は、目的変数です。
model.fit(X_train, y_train)
intercept_で計算した切片を確認できます。
model.intercept_
-41125.320910887734
coef_で偏回帰係数を確認可能です。
この値が0より離れている項目ほど、予測するためにより影響を与えます。
この結果を見る限り、自己資本単体ではほとんど影響を与えていないので削除しても問題ないかもしれませんね。
model.coef_
array([ 5.035, 4466.039, 24.673, 0.553, -2509.848,
12703.519])
modelのpredictで予測を実施します。
df_target.loc[:,'predict'] = model.predict(df_target[['営業利益(百万円)','PBR(実績)','BPS(実績)','自己資本(百万円)','ROE','ROA']])
df_target
SC | 名称_x | 市場 | 業種 | 時価総額(百万円) | 発行済株式数_x | 配当利回り | 1株配当 | PER(予想) | PBR(実績) | ... | 当期利益(百万円) | 総資産(百万円) | 自己資本(百万円) | 資本金(百万円) | 有利子負債(百万円) | 自己資本比率 | ROE | ROA | 発行済株式数_y | predict | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1301 | 極洋 | 東証一部 | 水産・農林 | 42948 | 10928283 | 1.53 | 60.00 | 15.29 | 1.49 | ... | 2422 | 97391 | 24976 | 5664 | 50919 | 25.60 | 10.19 | 2.52 | 10928283 | 6.979233e+04 |
1 | 1332 | 日本水産 | 東証一部 | 水産・農林 | 171524 | 312430277 | 1.46 | 8.00 | 8.55 | 1.22 | ... | 14216 | 451876 | 120973 | 30685 | 207749 | 26.80 | 13.17 | 3.17 | 312430277 | 1.635729e+05 |
2 | 1333 | マルハニチロ | 東証一部 | 水産・農林 | 169292 | 52656910 | 1.24 | 40.00 | 10.92 | 1.46 | ... | 15446 | 501303 | 100664 | 20000 | 272208 | 20.10 | 16.62 | 3.13 | 52656910 | 2.058015e+05 |
3 | 1352 | ホウスイ | 東証一部 | 卸売 | 9812 | 8379000 | 1.71 | 20.00 | 22.80 | 1.63 | ... | 706 | 33620 | 5692 | 2485 | 19140 | 16.90 | 13.04 | 2.24 | 8379000 | -1.323026e+04 |
4 | 1376 | カネコ種苗 | 東証一部 | 水産・農林 | 18860 | 11772626 | 1.62 | 26.00 | 12.97 | 1.05 | ... | 1489 | 43369 | 17686 | 1491 | - | 40.80 | 8.79 | 3.44 | 11772626 | 4.273245e+04 |
5 | 1377 | サカタのタネ | 東証一部 | 水産・農林 | 175489 | 48410750 | 0.69 | 25.00 | 30.21 | 1.66 | ... | 6112 | 116169 | 93933 | 13500 | 4192 | 80.90 | 6.69 | 5.43 | 48410750 | 1.631828e+05 |
3295 rows × 34 columns
評価を行う。
最後に評価を行います。
先ほど分割した、テスト用データの方でどれだけ、予測できているかチェックします。
だいたい、82%ほど予測ができていることが分かります。
# テスト用データで評価する
model.score(X_test, y_test)
0.82604803373912083
最後に
今回は、なんとなく重回帰分析をやってみたかっただけなのでこの結果が正しいのか、何も検証できていません。
説明変数の選択も適当だったので、より影響を与える項目を選択できればもっと良い結果を得ることができると思います。
もっと勉強して、重回帰分析以外の方法も試してみたいと思います。