読者です 読者をやめる 読者になる 読者になる

FXボーグ | テクニカル実験室

テクニカル分析を使った自動売買プログラムの開発に挑戦!

スポンサーリンク

傾きと標準誤差を一緒に計算する方法。

最小二乗法で切片と傾きを計算しながら、同時に標準誤差まで計算できる方法がこちらの記事に載っています。とても簡単な計算なのでExcelでサンプルを作ってみました。

http://hachisue.blog65.fc2.com/?mode=m&no=106

今回、計算に使用するデータはxとyが5件ずつのシンプルなものです。

f:id:fxborg:20161211125429p:plain

  • x・・・[0,1,2,3,4]
  • y・・・[10,25,40,35,50] 

普通の解き方

標準誤差は「残差平方和/自由度」の平方根を取ったものなので、残差(y-ÿ)の二乗を合計して、自由度で割ります。自由度は単にデータ個数から2を引いたものです。

標準誤差 = (Σ(y-y’)^2 ÷ (n-2))の平方根  

f:id:fxborg:20161211140055p:plain

この結果、標準誤差が「 6.3245532033676」と求まりました。

効率良い解き方

堅い説明は抜きにして手順だけ記述します。(詳細は先程の記事を参照)

▼計算手順

以下の和を求めます。(これは切片と傾きの計算にも使えますね)

  • ・xの和
  • ・yの和
  • ・x*xの和
  • ・y*yの和
  • ・x*yの和

 これらの和を求めたら、以下の手順で計算していきます。

f:id:fxborg:20161211184122p:plain

 無事計算できました。傾きを知らなくても残差平方和が分かるなんてクールですよね。

プログラム化すると・・・

これを利用して傾きと標準誤差を同時に求めるにはこんな風にします。

/***
 * 最小二乗法で単回帰(複数期間対応)
 * src  ... 時系列データ
 * fits ... 計算結果をセットする配列
 * x0   ... 計算を開始するバー
 * min  ... 最小の期間
 * max  ... 最大の期間
 * span ... 期間の間隔
 */
void lm(const double &src[],double &fits[][5],int x0,int min,int max,int span)
  {
   //--- 変数を初期化
   double Xsum=0.0;
   double Ysum=0.0;
   double XYsum=0.0;
   double X2sum=0.0;
   double Y2sum=0.0;

   //---期間の数
   int sz=0;
   //--- 最大期間までカウントアップします。
   for(double x=0;x<max;x++)
     {
      //--- 計算開始位置から過去向きに進んできます。
      double y=src[x0-(int)x];
      //--- 最小二乗法の計算
      XYsum+=x*y;
      Xsum+=x;
      Ysum+=y;
      X2sum+=x*x;
      Y2sum+=y*y;
      //--- 対象期間以外はスキップします。
      if(x+1.0<min)continue;
      double n=(x+1.0);
      if((int(n)%span)==0)
        {
         //--- 計算結果配列を用意
         int rsv=1+(max-min)/span;
         ArrayResize(fits,sz,rsv);
         //--- 傾きと切片の計算
         double cnt=(double)x;
         double div=(n*X2sum-Xsum*Xsum);
         double b=(div==0)? 0.0 :(n*XYsum-Xsum*Ysum)/div; //slope
         double a=(div==0)? Ysum/n :(X2sum*Ysum-XYsum*Xsum)/div; //intercept
                                                                 //-- Se,Ve,Sa
         //--- 標準誤差の計算
         double syy = (n*Y2sum-Ysum*Ysum)/n;
         double sxx = (n*X2sum-Xsum*Xsum)/n;
         double sxy = (n*XYsum-Xsum*Ysum)/n;
         double se =sxx==0.0 ? 0.0 : syy-(sxy*sxy)/sxx;
         double ve=se/(n-2); // Ve^2

         //--- 傾きの標準誤差
         double sa=sxx==0.0 ? 0.0 : sqrt(ve/sxx); // Sa for slope
         //--- 傾きのt値
         double t=sa==0 ? 0.0 : b/sa;
         //--- 残差平方和/Nの平方根
         double range=sqrt(se/n);

         //--- 結果を格納
         ArrayResize(fits,sz+1,rsv);
         fits[sz][0]=x;
         fits[sz][1]=a;
         fits[sz][2]=b;
         fits[sz][3]=t;
         fits[sz][4]=range;
         //---
         sz++;

        }
     }
  }

最後に

今回は標準誤差の計算方法について調べてみました。自分が知らなかっただけなので「なーんだ知ってるよ」と思われた方も多いと思いますが、これまで諦めていたケースでも回帰分析が使えそうなのでちょっと楽しみです。