.-- --

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
スポンサー広告 comment(-) trackback(-)
.19 2013

Eigenを使って最小2乗法を解いてみた

こんにちわ。Uedaです。

前回はEigenを使って固有値問題を解きました。今回は最小2乗法を解いてみます。

最小2乗法はフィッティング問題の常套方法だと思います。
問題へのアプローチが、誤差の2乗和を最小にするというもので直感的なので筆者は大好きです。

今回はストーリー仕立てでお送りします。

Aさんがどんなお味噌汁が好きか調査します。
お味噌汁の味付けは塩・味噌・鰹だしとし、Aさんはどの割合で調理したお味噌汁が好みか調べます。
それぞれの調味料の分量を変えたお味噌汁を飲んでもらっておいしかったかどうか聞きます。
例えば、
塩 1g, 味噌 0g, 鰹だし 0g. Aさんの評価→最悪 (そらそうだw
塩 1g, 味噌 1g, 鰹だし 0g. Aさんの評価→さっきよりはまし!
みたいなことを繰り返し行います。

塩がx, 味噌がy, 鰹だしがz, Aさんの評価をwとします。
ちょっとはしょりますが、
最小2乗法でAさんの好みを推定するプログラムは以下になります!
当然、Aさんの評価や調味料の分量には誤差が含まれるので、これらにはノイズを乗せてます。
それでは調査のためにAさんにはお味噌汁を100杯飲んでもらいましょう〜w



・・・・・

const double ANS_A = 1.0;
const double ANS_B = 2.0;
const double ANS_C = 3.0;
const double ANS_D = 4.0;
const int DATA_COUNT = 100;
const double NOISE = 1.0;

double* xArr = new double[DATA_COUNT];
double* yArr = new double[DATA_COUNT];
double* zArr = new double[DATA_COUNT];
double* wArr = new double[DATA_COUNT];

// Aさんに100杯お味噌汁を飲んでもらって、実験開始!! ------------------
for (int i = 0; i < DATA_COUNT; i++) {
double x = 0.5 - random() / 1000000000.0;
double y = 0.5 - random() / 1000000000.0;
double z = 0.5 - random() / 1000000000.0;
double noize = (0.5 - random() / 1000000000.0) * NOISE;
double w = x * ANS_A + y * ANS_B + z * ANS_C + ANS_D + noize;
wArr[i] = w; // Aさんの評価
xArr[i] = x; // 塩の分量
yArr[i] = y; // 味噌の分量
zArr[i] = z; // 鰹だしの分量
NSLog(@"%f, %f, %f, %f, %f", x, y, z, w, noize);
}
// Aさんご苦労様 ------------------

// Eigen使って最小2乗法 ------------
MatrixXd X(DATA_COUNT, 4);
MatrixXd Y(DATA_COUNT, 1);
for (int i = 0; i < DATA_COUNT; i++) {
X(i, 0) = xArr[i];
X(i, 1) = yArr[i];
X(i, 2) = zArr[i];
X(i, 3) = 1.0;
Y(i, 0) = wArr[i];
}
MatrixXd Xt = X.transpose();
MatrixXd ans = (Xt * X).inverse() * Xt * Y;

// 出力 ------------
NSLog(@"正解 %f, %f, %f, %f", ANS_A, ANS_B, ANS_C, ANS_D);
// → 正解 1.000000, 2.000000, 3.000000, 4.000000
NSLog(@"推定 %f, %f, %f, %f", ans(0, 0), ans(1, 0), ans(2, 0), ans(3, 0));
// → 推定 0.891576, 2.057038, 3.063395, 3.384292

・・・・・


結果は、
正解 1.000000, 2.000000, 3.000000, 4.000000
推定 0.891576, 2.057038, 3.063395, 3.384292
ですかー。
Aさんには少し塩っけの足りないみそ汁になっちゃいそうですが、おおむね推定できてると思います。

今回はEigenを使って最小2乗法を解くということで、
最小2乗法の計算方法の中身の紹介ができませんでした。
以下のサイトが詳しいです。
http://itmath.blog60.fc2.com/blog-entry-111.html

MatrixXd Xt = X.transpose();
MatrixXd ans = (Xt * X).inverse() * Xt * Y;

このサイト上の a = (Gt G)^-1 Gt Y
が味噌です! (お後がよろしいようで
関連記事
スポンサーサイト

Comment

Post comment

  • comment
  • secret
  • 管理者にだけ表示を許可する

Trackback

trackbackURL:http://appteam.blog114.fc2.com/tb.php/247-b45d5aad

ブログ内検索

関連リンク

製品情報

最新記事

カテゴリ

プロフィール

neoxneo



NEXT-SYSTEM iOS Developers Blog


  • UTO:
    カナダ版iPhone4Sは、マナーモードでシャッター音がならない…


  • Ehara:
    ...


  • Hayate:
    ...


  • Tasaki:
    Developer登録完了...したのはいいけど


  • Ueda:
    ...



リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。