LoginSignup
2
4

時系列データの代表格!株価のデータの取得と推論モデルの開発を5分で行う

Last updated at Posted at 2024-04-30

image.png

Yahoo! Finance APIとProphetを使ってとにかく素早くモデルをつくってみる

時系列データの分析を練習したい時、株価のデータはとてもおすすめです。

💡その理由は3つ!

  1. 長期で欠損の少ない、扱いやすいデータが多い
  2. 銘柄を変えるだけで変動傾向の異なるデータが手に入る
  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は可読性も高く、デフォルトの設定を調整する必要もほとんどなく使いやすいです。

dsyという列を作成し、トレンドのパラメータを設定しモデルをつくります。

# 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()

image.png

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()

フィッティングは改善されました!今後は減少傾向を予測しています。
image.png

各スコアを出します。こちらも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()

image.png

リーマンショックなど経済的なイベントに対する考察やチャートの読み方など、株価予測に関してはドメイン知識も必要ですが、短いステップでフィッティングが上手くいくと嬉しいですね!

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4