« CANVASクリック位置取得:IE8でもfirefoxでも | トップページ | ♪メロディーの曖昧記憶と記号化と音痴と »

■二次回帰曲線、直線回帰:係数算出アルゴリズムとコード

 二次回帰曲線、直線回帰線を出す


 上の水色ブロック内をクリックすると点が打たれ、回帰線が出力されます。

二次回帰係数 a= b= c=
直線回帰係数 a= b=

左下がx=0,y=0で、1ドットが1です。


 二次回帰曲線係数算出アルゴリズム/ソースコード

二次回帰曲線の係数は次のコードで得ています。

// 二次回帰曲線( a * X^2 + b * X +c )の係数(a,b,c)を求める
// 使い方
//    var kaiki= new NijiKaiki();
//    // 元データをセットする
//    kaiki.set(data_x,data_y);          <--繰り返し
//    // 計算する
//    kaiki.calculate(); // 係数はkaiki.a,kaiki.b,kaiki.cに得られる
//    // 回帰曲線上のyを得る
//    var y_on_line= kaiki.y(new_x_val); <-- 繰り返し
//-- 構築子
function NijiKaiki(){
   this.reset();
   }
//-- 初期化関数
NijiKaiki.prototype.reset = function(){
   this.a     = 0;
   this.b     = 0;
   this.c     = 0;
   this.n     = 0;
   this.Sx2   = 0;
   this.Sx    = 0;
   this.Sxy   = 0;
   this.Sy    = 0;
   this.Sx3   = 0;
   this.Sx2y  = 0;
   this.Sx4   = 0;
   }
//-- ポイント情報設定
NijiKaiki.prototype.set = function(x_,y_){
   ++this.n;
   var _x2    = x_*x_;
   this.Sx2  += _x2;
   this.Sx   += x_;
   this.Sxy  += x_*y_;
   this.Sy   += y_;
   this.Sx3  += _x2*x_;
   this.Sx2y += _x2*y_;
   this.Sx4  += _x2*_x2;
   return this;
   }
//-- 係数算出
NijiKaiki.prototype.calculate =function(){
   var _SSxx  = this.Sx2  - this.Sx*this.Sx/this.n;
   var _SSxy  = this.Sxy  - this.Sx*this.Sy/this.n;
   var _SSxx2 = this.Sx3  - this.Sx*this.Sx2/this.n;
   var _SSx2y = this.Sx2y - this.Sx2*this.Sy/this.n;
   var _SSx2x2= this.Sx4  - this.Sx2*this.Sx2/this.n;
   var _D     = _SSxx*_SSx2x2-_SSxx2*_SSxx2;
   //
   this.a = (_SSx2y*_SSxx-_SSxy*_SSxx2)  /_D;
   this.b = (_SSxy*_SSx2x2-_SSx2y*_SSxx2)/_D;
   this.c = this.Sy/this.n-this.b*this.Sx/this.n-this.a*this.Sx2/this.n;
   }
//-- 曲線上の位置を得る
NijiKaiki.prototype.y =function(x_){
   return this.a*x_*x_ + this.b*x_ + this.c;
   }

 直線回帰係数算出アルゴリズム/ソースコード

直線回帰線の係数は次のコードで得ています。

// 直線回帰( a * X +b )の係数(a,b)を求める
// 使い方
//    var kaiki= new LinearKaiki();
//    // 元データをセットする
//    kaiki.set(data_x,data_y);          <--繰り返し
//    // 計算する
//    kaiki.calculate(); // 係数はkaiki.a,kaiki.bに得られる
//    // 回帰曲線上のyを得る
//    var y_on_line= kaiki.y(new_x_val); <-- 繰り返し
//-- 構築子
function LinearKaiki(){
   this.reset();
   }
//-- 初期化関数
LinearKaiki.prototype.reset = function(){
   this.a     = 0;
   this.b     = 0;
   this.c     = 0;
   this.n     = 0;
   this.Sx2   = 0;
   this.Sx    = 0;
   this.Sxy   = 0;
   this.Sy    = 0;
   }
//-- ポイント情報設定
LinearKaiki.prototype.set = function(x_,y_){
   ++this.n;
   var _x2    = x_*x_;
   this.Sx2  += _x2;
   this.Sx   += x_;
   this.Sxy  += x_*y_;
   this.Sy   += y_;
   return this;
   }
//-- 係数算出
LinearKaiki.prototype.calculate =function(){
   var _D = this.n*this.Sx2-this.Sx*this.Sx;
   this.a = (this.Sxy*this.n-this.Sx*this.Sy)/_D;
   this.b = (this.Sx2*this.Sy-this.Sxy*this.Sx)/_D;
   }
//-- 直線上の位置を得る
LinearKaiki.prototype.y =function(x_){
   return this.a*x_ + this.b;
   }

 canvas描画コード

あまり綺麗なコードではありませんが、参考までにcanvas出力のコードも載せます。
canvas以外の留意点(直ぐ忘れてしまう点)としては<span>に文字列をセットするにはinnerHTMLを使うこと、 数値の表示精度を指定するのはtoFixed()などがあります。

 ###

二次回帰曲線は単なる統計処理だけでなく画像処理での輝度スムージング や、色々なデータでの連続した欠損の補正など広い範囲で使えるものです。
画像の歪みを推定することや、途中の隠蔽された複数の図形要素の連続性を見つける ためなどにも使ってきました。

このコードははるか昔に作成しずっと色々な場面で使っているものです。 当初はC++で、 その後Javaでも使いました。今回はJavasriptにしています。
コードはほぼそのままJavaにもC++にもできるはずです。

表示にはcanvasを用いています。。。。。いやあ、大変でした。 Flashは良く出来ているなあとつくづく感じました。
canvasでクリック位置を得る方法に関して CANVASクリック位置取得:IE8でもfirefoxでもに記事を書きました。

3次以上の回帰計算はここで上げたような形ではなくマトリクス演算で 行います。何れ。

|

« CANVASクリック位置取得:IE8でもfirefoxでも | トップページ | ♪メロディーの曖昧記憶と記号化と音痴と »

トラックバック


この記事へのトラックバック一覧です: ■二次回帰曲線、直線回帰:係数算出アルゴリズムとコード:

« CANVASクリック位置取得:IE8でもfirefoxでも | トップページ | ♪メロディーの曖昧記憶と記号化と音痴と »