/// <summary> /// 重回帰分析を適用する. /// </summary> /// <param name="y">出力値のベクトル</param> /// <param name="xs">入力ベクトルのセット</param> public MultipleLinearRegressionAnalysis(IVector y, IVector[] xs) { if (y.Size != xs.Length) { throw new Exception.MismatchSizeException(); } ColumnVector Y = new ColumnVector(y); Matrix X = new Matrix(VectorType.RowVector, xs); int p = X.ColumnSize; // 変数の数 // 各変数の平均値を算出 IVector colAvgs = X.ColumnAverages; X.Rows.ForEach(delegate(IVector rv) { rv.ForEach(delegate(int i, ref double val) { val -= colAvgs[i]; }); }); // 第1列目に"1"を挿入 Matrix tmp = new Matrix(X.RowSize, X.ColumnSize + 1); for (int r = 0; r < tmp.RowSize; ++r) { tmp[r, 0] = 1.0; for (int c = 1; c < tmp.ColumnSize; ++c) { tmp[r, c] = X[r, c - 1]; } } X = tmp; // 係数の同定 Matrix tX = Matrix.Transpose(X); Matrix itXX = Matrix.Inverse(tX * X); IVector C = itXX * tX * Y; // 定数項を求める for (int i = 1; i < C.Size; ++i) { C[0] -= C[i] * colAvgs[i - 1]; } this.coefficients = C; // テコ比 Matrix H = X * itXX * tX; this.leverages = new Vector(H.ColumnSize); H.Rows.ForEach(delegate(int r, IVector v) { this.leverages[r] = v[r]; }); // 残差ベクトル ColumnVector e = Y - H * Y; this.residuals = new Vector(e); int phi_t = Y.Size - 1; // n - 1 int phi_e = Y.Size - p - 1; // n - p - 1 double Se = e * e; this.dofP = p; this.dofE = phi_e; double y_avg = Y.Average; double Syy = 0.0; Y.ForEach(delegate(double val) { Syy += (val - y_avg) * (val - y_avg); }); // 決定係数 this.r2 = 1.0 - Se / Syy; // 自由度補正済み決定係数 this.rc2 = 1.0 - (Se / phi_e) / (Syy / phi_t); // 各係数のt値 double Ve = Se / phi_e; IVector std_coeff = new Vector(this.coefficients.Size); std_coeff.ForEach(delegate(int i, ref double val) { val = Math.Sqrt(Ve * itXX[i, i]); }); // Sqrt(Ve/Sxx) // まだ,定数項の標準偏差は使えない(Yの平均値のものになっている) // 定数項の検定統計量を算出 double var0 = itXX[0, 0]; // 1/n for (int i = 1; i < p + 1; ++i) { for (int j = 1; j < p + 1; ++j) { var0 += colAvgs[i - 1] * colAvgs[j - 1] * itXX[i, j]; } } std_coeff[0] = Math.Sqrt(var0 * Ve); IVector t = new Vector(std_coeff.Size); t.ForEach(delegate(int i, ref double val) { val = Math.Abs(this.coefficients[i]) / std_coeff[i]; // 帰無仮説はβ=0 }); this.ts = t; }