CalLS2_ver2

概要

移動最小2乗2次式近似値を計算する.
具体的には,移動平均のように平均値を移動させるのではなく,最小二乗法を引いて二次式近似線をひき,その近似線で算出される値を移動させる.

引数

数値(float型)を縦方向にベクトル表記したもの

戻り値

N個の数値からなるベクトルをy軸(引数そのもの)とし,-(N-1),-(N-2),…0で構成されるベクトルをx軸としたときの,二次式近似線の各係数.

  1. 2次の係数(a2)
  2. 1次の係数(a1)
  3. 0次の係数(a0…二次式近似値そのものに相当)

コード

import numpy as np

# 移動最小2乗2次式近似値を計算させる
def CalLS2_ver2(y_Y):
    N=len(y_Y)
    x_Y=np.array(list(range(N-1,-1,-1))).reshape(N,1)#データに対応するxベクトル(N-1,N-2,…1,0)を作った

    #本当は計算の安定化のため,x_Yの絶対値を減らしておいた方が良いけど,一応下記でバグなく動いている
    # 3次式近似やるなら,計算安定化のためのとした処置をいれるかしらね…
    s_4=((0.1*x_Y)**4).sum()#信じがたいことに,.sum()は積算値に上限があるらしい…しかたないので,.sum前は0.1がけして,積算終わってから10^4する
    s_4 =round(s_4*10**4)
    s_3=(x_Y**3).sum()
    s_2 = (x_Y ** 2).sum()
    s_1 = x_Y.sum()
    s_x2y=(x_Y ** 2*y_Y).sum()
    s_xy = (x_Y * y_Y).sum()
    s_y = (y_Y).sum()

    A_XY=[[s_4,s_3,s_2],[s_3,s_2,s_1],[s_2,s_1,N]]
    X_Y=[[s_x2y],[s_xy],[s_y]]
    [[a2],[a1],[a0]]=np.linalg.inv(A_XY)@X_Y

    #最終的には,切片a0そのものが,最小二乗法による二次式近似値となる.-a1は,微分値なので傾き=トレンド推定値となる(数学的には)
    return(a2,-a1,a0)

トレンドを把握するための移動平均を計算させるのは良くある話だが,長期トレンドを把握するために,移動平均を計算させるデータのN数を増やすと,平均値線がリアルタイム値動きから遅れてしまう.これを何とかしたいと思い,単純な平均値ではなく,最小二乗法による二次近似線を書いて,そこから得られる値を移動させたら,遅れはマシになるのでは?と思い,作成した.

実際に,単純移動平均に対し,リアルタイム値動きからのタイムラグはだいぶん解消される.このタイムラグこそが,移動平均の最大の弱点のはずなので,使いようによっては便利なんじゃなかろうか…

コメント

タイトルとURLをコピーしました