Yahoo! Finance APIとProphetを使ってとにかく素早くモデルをつくってみる
時系列データの分析を練習したい時、株価のデータはとてもおすすめです。
💡その理由は3つ!
- 長期で欠損の少ない、扱いやすいデータが多い
- 銘柄を変えるだけで変動傾向の異なるデータが手に入る
- グラフを書いた時に株価変動がわかって役に立った感じがする
実際には時系列データを解析するときは、欠損値補完、標準化、ノイズの除去、局所化など前処理に時間をかけます。モデル開発についても自己相関係数を調べたり、LSTMなどのモデルでは計算やパラメータ調整に時間を要します。
この記事では、素早くデータを得ること、素早くモデルをつくることを目的にしています。まずは目に見える制作物が欲しいです!
全体のコードはこちら
# パッケージのインストール
!pip install yfinance
import yfinance as yf
!pip install prophet
from prophet import Prophet
from prophet.diagnostics import cross_validation, performance_metrics
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error, mean_squared_error
# 株価の取得
target = "TSLA" # 好きな銘柄
stock = yf.Ticker(target)
hist = stock.history(period="max")
# Prophetでモデル作成
hist_recent = hist[hist['ds']>'2021'] # 期間を絞っています
model = Prophet(
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
model.fit(hist_recent)
future_df = model.make_future_dataframe(365)
forecast_df = model.predict(future_df)
model.plot(forecast_df)
plt.show()
# クロスバリデーション
df_cv = cross_validation(model, initial='730 days', period='180 days', horizon='365 days')
df_metrics = performance_metrics(df_cv)
# MAE, MSE, RMSE
mae = mean_absolute_error(df_cv['y'], df_cv['yhat'])
mse = mean_squared_error(df_cv['y'], df_cv['yhat'])
rmse = np.sqrt(mse)
print(f'Mean Absolute Error: {mae:.2f}')
print(f'Mean Squared Error: {mse:.2f}')
print(f'Root Mean Squared Error: {rmse:.2f}')
パッケージインストール(1分)
# Yahoo! finance API
!pip install yfinance
import yfinance as yf
!pip install prophet
from prophet import Prophet
from prophet.diagnostics import cross_validation, performance_metrics
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error, mean_squared_error
yfainance
のドキュメントはこちらです。
Yahoo! Finance APIで株価データ取得(1分)
Ticker()
を使って銘柄を取得します。今回はテスラ(TSLA)です。
info
で基本的な情報をまるっと手に入れられます。興味がなければ飛ばして問題ないです。
[in]
target = "TSLA" # 好きな銘柄
stock = yf.Ticker(target)
stock.info
[out]
{'address1': '1 Tesla Road',
'city': 'Austin',
'state': 'TX',
'zip': '78725',
'country': 'United States',
'phone': '512 516 8177',
'website': 'https://www.tesla.com',
'industry': 'Auto Manufacturers',
'industryKey': 'auto-manufacturers',
'industryDisp': 'Auto Manufacturers',
'sector': 'Consumer Cyclical',
'sectorKey': 'consumer-cyclical',
'sectorDisp': 'Consumer Cyclical',
'longBusinessSummary': 'Tesla, Inc. designs, develops, manufactures, leases, and sells electric vehicles, and energy generation and storage systems in the United States, China, and internationally. The company operates in two segments, Automotive, and Energy Generation and Storage. The Automotive segment offers electric vehicles, as well as sells automotive regulatory credits; and non-warranty after-sales vehicle, used vehicles, body shop and parts, supercharging, retail merchandise, and vehicle insurance services. This segment also provides sedans and sport utility vehicles through direct and used vehicle sales, a network of Tesla Superchargers, and in-app upgrades; purchase financing and leasing services; services for electric vehicles through its company-owned service locations and Tesla mobile service technicians; and vehicle limited warranties and extended service plans. The Energy Generation and Storage segment engages in the design, manufacture, installation, sale, and leasing of solar energy generation and energy storage products, and related services to residential, commercial, and industrial customers and utilities through its website, stores, and galleries, as well as through a network of channel partners; and provision of service and repairs to its energy product customers, including under warranty, as well as various financing options to its solar customers. The company was formerly known as Tesla Motors, Inc. and changed its name to Tesla, Inc. in February 2017. Tesla, Inc. was incorporated in 2003 and is headquartered in Austin, Texas.',
'fullTimeEmployees': 140473,
'companyOfficers': [{'maxAge': 1,
'name': 'Mr. Elon R. Musk',
'age': 51,
'title': 'Technoking of Tesla, CEO & Director',
'yearBorn': 1972,
.......
'grossMargins': 0.17778999,
'ebitdaMargins': 0.12945,
'operatingMargins': 0.054970004,
'financialCurrency': 'USD',
'trailingPegRatio': 3.4345}
ちなみにTickerというのは「TSLA」のようなシンボルのことを指します。日本の場合は数字が多く、例えばトヨタの場合は「7203.T」になります。
日付と株価のテーブルデータを得る(1分)
history()
を使ってPadasのデータフレームとして取得します。
[in]
hist = stock.history(period="max")
stock.history_metadata # メタデータ
[out]
{'currency': 'USD',
'symbol': 'TSLA',
'exchangeName': 'NMS',
'fullExchangeName': 'NasdaqGS',
'instrumentType': 'EQUITY',
'firstTradeDate': 1277818200,
.......
'validRanges': ['1d',
'5d',
'1mo',
'3mo',
'6mo',
'1y',
'2y',
'5y',
'10y',
'ytd',
'max']}
period="max"
で全期間のデータを取っています。
[in]
print(hist)
[out]
Open High Low Close Volume Dividends Stock Splits
Date
2010-06-29 00:00:00-04:00 1.266667 1.666667 1.169333 1.592667 281494500 0.0 0.0
2010-06-30 00:00:00-04:00 1.719333 2.028000 1.553333 1.588667 257806500 0.0 0.0
2010-07-01 00:00:00-04:00 1.666667 1.728000 1.351333 1.464000 123282000 0.0 0.0
2010-07-02 00:00:00-04:00 1.533333 1.540000 1.247333 1.280000 77097000 0.0 0.0
2010-07-06 00:00:00-04:00 1.333333 1.333333 1.055333 1.074000 103003500 0.0 0.0
... ... ... ... ... ... ... ...
2024-04-24 00:00:00-04:00 162.839996 167.970001 157.509995 162.130005 181178000 0.0 0.0
2024-04-25 00:00:00-04:00 158.960007 170.880005 158.360001 170.179993 126427500 0.0 0.0
2024-04-26 00:00:00-04:00 168.850006 172.119995 166.369995 168.289993 108896700 0.0 0.0
2024-04-29 00:00:00-04:00 188.419998 198.869995 184.539993 194.050003 241778200 0.0 0.0
2024-04-30 00:00:00-04:00 186.960007 189.940002 186.773102 187.544998 12834339 0.0 0.0
Prophetでモデル作成、描画(2分)
Prophetは可読性も高く、デフォルトの設定を調整する必要もほとんどなく使いやすいです。
ds
とy
という列を作成し、トレンドのパラメータを設定しモデルをつくります。
# dsに時間、yに株価を代入
hist['ds'] = hist.index.copy()
hist['ds'] = hist['ds'].dt.tz_localize(None)
hist['y'] = hist['Open'].copy()
# モデル作成
model = Prophet(
# 各周期のトレンドを考慮するか
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
model.fit(hist)
future_df = model.make_future_dataframe(365)
forecast_df = model.predict(future_df)
model.plot(forecast_df)
plt.show()
2020年前後で全く傾向が違うので、全期間のデータを使うとフィッティングが上手くいきませんでした。
そこで2021年からのデータに限定します。
hist_recent = hist[hist['ds']>'2021'] # 期間を絞っています
model = Prophet(
daily_seasonality=True,
weekly_seasonality=True,
yearly_seasonality=True
)
model.fit(hist_recent)
future_df = model.make_future_dataframe(365)
forecast_df = model.predict(future_df)
model.plot(forecast_df)
plt.show()
フィッティングは改善されました!今後は減少傾向を予測しています。
各スコアを出します。こちらもProphetのメソッドを使います。
[in]
# クロスバリデーション
df_cv = cross_validation(model, initial='730 days', period='180 days', horizon='365 days')
df_metrics = performance_metrics(df_cv)
# MAE, MSE, RMSE
mae = mean_absolute_error(df_cv['y'], df_cv['yhat'])
mse = mean_squared_error(df_cv['y'], df_cv['yhat'])
rmse = np.sqrt(mse)
print(f'Mean Absolute Error: {mae:.2f}')
print(f'Mean Squared Error: {mse:.2f}')
print(f'Root Mean Squared Error: {rmse:.2f}')
[out]
Mean Absolute Error: 89.54
Mean Squared Error: 9306.44
Root Mean Squared Error: 96.47
まとめ
短時間で株価データの取得から時系列モデルの作成までを行うことができました。Prophetは他にも周期の傾向を表示するコンポーネントなど便利な機能がたくさんあります。
model.plot_components(forecast_df)
plt.show()
リーマンショックなど経済的なイベントに対する考察やチャートの読み方など、株価予測に関してはドメイン知識も必要ですが、短いステップでフィッティングが上手くいくと嬉しいですね!