重回帰分析     Last modified: May 15, 2002

 データファイルは,「複数個の独立変数,1個の従属変数」の順とします。inv 関数を呼ぶまでは,pca.awk とほとんど同じです。このスクリプトをほんの少し手直しすると,多項式回帰分析を行うことができます。

 また,偏回帰係数の検定,分散分析表の検定の有意確率を求めるためには txp 関数fxp 関数を使用できます。

 使用法は jgawk -f mreg.awk -f inv.awk test.dat のようになっています。


# mreg.awk

BEGIN { # 環境設定
   FS = "[, \t]+" # 数値の区切りは,カンマ,空白,タブ
   epsinv = 1e-8  # 特異度の判定値
}

{ # データファイル処理
   if (NR == 1) { # データファイルの 1 行目の変数の個数を記憶
       nv = NF
   }
   else if (NF != nv) { # 2 行目以降の変数の個数のチェック
       printf "1ケースあたりの変数の個数が違います!\n\n" > "/dev/stderr"
       error = 1
       exit(1)
   }
   nc++
   for (i = 0; i < nv; i++) { # 平均値,変動の積算
       temp[i] = vx = $(i+1)-mean[i]
       mean[i] += vx/nc
       for (k = 0; k <= i; k++) {
           a[i,k] += (nc-1)*temp[k]*vx/nc
       }
   }
}

END { # 前処理が終了したら,本処理
   if (error) {
       exit(1)
   }
   nc = NR
   printf "ケース数: %i  変数の個数: %i\n\n", nc, nv
   printf "%4s%14s%15s%15s\n", "変数", "平均値", "不偏分散", "標準偏差"
   for (i = 0; i < nv; i++) {
       ss[i] = a[nv-1,i]
       sd[i] = sqrt(var = a[i,i]/(nc-1))
       printf "X%02i%15.7g%15.7g%15.7g\n", i+1, mean[i], var, sd[i]
   }
   printf "\n\n相関係数行列\n\n"
   for (i = 0; i < nv; i++) {
       printf "X%02i", i+1
       for (j = 0; j <= i; j++) {
           if (sd[i]*sd[j] == 0) {
               exit(1)
           }
           else {
               a[i,j] /= sd[i]*sd[j]*(nc-1)
           }
           printf "%9.5f", a[j,i] = a[i,j]
       }
       printf "\n"
   }
   printf "   "
   for (i = 1; i <= nv; i++) {
       printf "      X%02i", i
   }
   printf "\n\n"
   nv1 = nv-1
   nc1 = nc-1
   if (inv(a, nv1, epsinv) == 0) { # 逆行列
       b0 = mean[nv1]
       se = syy = ss[nv1]
       for (i = 0; i < nv1; i++) {
           temp2 = 0
           for (j = 0; j < nv1; j++) {
               temp2 += a[i,j]*a[j,nv1]
           }
           b1[i] = temp2
           b[i] = temp2*sd[nv1]/sd[i]
           b0 -= b[i]*mean[i]
           se -= b[i]*ss[i]
       }
       sr = syy-se
       rhoy = se/syy
       seb0 = 0
       df2 = nc-nv1-1
       for (i = 0; i < nv1; i++) {
           seb = a[i,i]*rhoy/df2*(sd[nv1]^2/sd[i]^2)
           seb0 += (mean[i]^2)*seb
           stde[i] = sqrt(seb)
       }
       seb = 0
       for (i = 0; i < nv1; i++) {
           temp2 = 2*mean[i]/sd[i]
           for (j = i+1; j < nv1; j++) {
               seb += a[j,i]*temp2*mean[j]/sd[j]
           }
       }
       seb0 = sqrt(seb0+(seb+nc1/nc)*sd[nv1]^2*rhoy/df2)
       printf "%6s%15s%15s%15s%18s\n",
              "変数", "偏回帰係数", "標準誤差", "t値", "標準化偏回帰係数"
       for (i = 0; i < nv1; i++) {
           printf "   X%02i%15.5f%15.5f%15.5f%15.5f\n",
                  i+1, b[i], stde[i], b[i]/stde[i], b1[i]
       }
       printf "定数項%15.5f%15.5f%15.5f\n", b0, seb0, b0/seb0
       printf "\n分散分析表\n\n%4s%15s%8s%15s%15s\n",
              "要因", "平方和", "自由度", "平均平方", "F値"
       printf "回帰%15g%8i%15g%15g\n", sr, nv1, sr/nv1, sr*df2/nv1/se
       printf "残差%15g%8i%15g\n", se, df2, se/df2
       printf "全体%15g%8i%15g\n\n", syy, nc1, syy/nc1
       printf "重相関係数 = %.5f   決定係数 = %.5f", sqrt(1-rhoy), 1-rhoy
   }
}


・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI