6
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】スケールの異なる時系列データの類似度をMAEで比較する

Last updated at Posted at 2021-04-14

形が似ているグラフ(時系列データ)を見つけたいときってありますよね.

今回は,スケールが違うけど形は似ている時系列データを見つけるために,スケールを正規化してMAE(平均絶対誤差)で比較する方法を書きます.

#動機

普段はこちらの記事で株式投資について書いていますが,形が似ている銘柄をスクリーニングしたいと考えました(例えば,コロナショックで大きく変動した銘柄を抽出する).

形が似ている銘柄をスクリーニングするメリットとして,

・形が同じような銘柄は避け,分散投資に役立てる
・形が同じような銘柄を買い,ひとつの個別銘柄の不調を補う
・形が同じような銘柄の共通点を分析することで投資に役立てる

などがあります.

しかし,株価というものは形が似ていてもスケールがバラバラです.

例えば,以下のUAL(ユナイテッド・エアライン・ホールディングス)とDAL(デルタ航空)はコロナショックで大きく下落したので形は似ていますが,スケールが違うのでスクリーニングするときに何を基準に比較するか困ってしまいます.

simlar_chart1.png

そこでこの記事では,スクリーニングの準備のために同じスケールに正規化して比較するコードを用意します.

#株価データの準備
すでに比較したいデータがある場合は,この章は飛ばしてください.

今回は,Pythonのpandas-datareaderでUAL,DAL,AAPLの株価を取得します.
※今回の内容には関係ないですが,取得したらCSVなどに保存することをおすすめします.APIのサーバーの負担になるからです.

import datetime
import pandas_datareader.data as web

start = datetime.date(2018,1,1)
end = datetime.date.today()

ual = web.DataReader('UAL', 'yahoo', start, end)['Adj Close']
dal = web.DataReader('DAL', 'yahoo', start, end)['Adj Close']
aapl = web.DataReader('AAPL', 'yahoo', start, end)['Adj Close']

※調整後終値(Adj Close)のみを取得しています.

これらの株価データはpandasのDataFrameで与えられます.

この時点では,以下のデータようなデータになっています.

simlar_chart1.png

#正規化する

データの形だけを比較するために,スケールを0~1に正規化します.

正規化には,Min-Max Normalizationを使います.

mmn(x) = \frac{x_i-\min(x)}{\max(x)-\min(x)}

pandasのDataFrameは,以下で正規化できます.

def mmn(ticker):
    mmn = (ticker - ticker.min()) / (ticker.max() - ticker.min())
    return mmn

ual = mmn(ual)
dal = mmn(dal)
aapl = mmn(aapl)

これで,以下のようにデータが0~1に正規化されていると思います.

simlar_chart2.png

UALとDALの株価の形が似ていることが分かりやすくなりました.

#MAEで比較する

最後に,類似度を定量的に計算します.

類似度には平均絶対誤差(MAE)を使うことにします.

MAE = \frac{1}{N}\sum_{i=1}^{N}|x_{1i} - x_{2i}|

今回の場合,MAEは小さいほど似ている形のデータ系列といくことになります.MAEが0だと完全に一致していることになります.

MAEは以下で計算できます.

from sklearn.metrics import mean_absolute_error

MSE_dal_ual = mean_absolute_error(dal, ual)
MSE_ual_aapl = mean_absolute_error(ual, aapl)
MSE_aapl_dal = mean_absolute_error(aapl, dal)
MSE_dal_ual =  0.08767186335370042
MSE_ual_aapl =  0.5756471586956278
MSE_aapl_dal =  0.5380791440469056

UALとDALが似ていることが確認できました.

#むすび
今回はそのま比較しましたが,移動平均を取ってからMAEで比べたほうが傾向で比較できるかもしれません.その場合は,TA-Libを使うと簡単に移動平均が作れるのでおすすめです.

では後日,本記事の内容を使って「似た形の株価チャートをスクリーニング」したいと思います.

6
16
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
6
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?