• ベストアンサー

C/C++での最小二乗法について

いつもお世話になっております。 初めての質問で不備があるかと思われますがよろしくお願いします。 現在Excelのソルバー機能で、測定した値とは別に 計算式f(x)で求めた推定値との残差二乗和((測定値-推定値)^2の和)から 計算式f(x)の変数a,bを算出しています。(変数a,bの初期値は適当な値を設定) このソルバーでの最小二乗法の計算をc/c++にて実装するにはどのようにすれば良いのでしょうか。 (ソルバー機能では目的値を残差二乗和、変化対象を変数a,bとし、準ニュートン法より最小値を求めています。) 御教授よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

こんばんは. 前途多難ですね…このカテゴリにおられるC/C++の知識を持った方々に対する質問では無いような気がします. >おそらく非線型 企業秘密に抵触するとかでなければ,関数型を明示してください. 「変数(a,b)で記述できる未知の系にへx1を入れたら出力y1が出た. この系は y1 = a*x1/b なるモデルで記述できるはずだから…」 というようにです. このとき,パラメターに制約がついているかも記述してください. (例) min ||y1 - a*x1/b ||^2 subject to (a > 0, b > 0) 制約が非線型なのかそうでないのかでかなり話が違ってきます. >どんな手法を実装するのか? というのは具体的なアルゴリズムのことです. 最小二乗法とは,「ある観測モデルがあって」,「手元にある観測を生じるはずのパラメター」を求める,という「考えかた」のことです. これは「やりたこと」であって,断じて「そのための具体的な手段」を指すわけではありません. 欲しかった回答は最急降下法を使うとか,Gauss-Newton法を使うとか,Newton法を使うとか, 共役勾配法を使うとかです. 手段が複数あるのは関数の型や微分の利用可能性などによって, 「適した手段」が場合によって違うからです. どんな方法を使えば良いのかから知りたいならば, 評価関数の型に関する情報は「必要不可欠」です. >アタックは間違っているか? それは状況によるでしょう. 最大の問題は質問者様が概要だけでも基礎理論を習得する時間があるか, という点につきるのでは? とりあえず,「制約なしの非線型最小二乗法」であるとすれば (違う場合は補足をお願いします), Gauss-Newton法が最も一般的でしょう. この場合,必要なのは以下です. ・評価関数のJacobian (偏微分した量に関する行列です) ・行列ー行列乗算関数 ・n*n線型方程式を解く関数 ・(オプション)直線探索関数 計算効率を度外視すれば学部生でも実装できます.

shin0517
質問者

お礼

おはようございます。 度々のご指摘ありがとうございます。 御説明頂いた内容を踏まえた上で、圧倒的にこちらの知識不足が大きいという点と、 限られた時間的な面を考慮し、再度諸々に関して検討する必要があると思いました。 稚拙な私の質問に親切に答えて頂きありがとうございました。 参考として挙げて頂いた方法。考え方は、こちらで調べて活かせれるようにしたいと思います。 また何か進展、もしくは躓きがあった際に新たに質問をさせて頂く事に なると思われますが、その時はよろしくお願いします。 ありがとうございました。

その他の回答 (1)

回答No.1

こんにちは. 最小二乗法をC/C++で実装したいということですが, あまりにも質問内容が漠然としすぎています. ・評価関数は線型か非線型か? ・どんな手法を実装するのか? ・微分を用いる方法を使うのか? ・微分を使うならそれは解析的に与えるのか? について補足を行ってください. 参考までに述べると以下のような処理が必要となります. ・行列と行列の乗算 ・行列とベクトルの乗算 ・パラメタベクトルxと更新ベクトルdxに関して, alphaに関する最小化問題 min||f(x+alpha*dx)||^2を解く関数 (直線探索といいます) ・n*nの線型方程式の求解(Cholesky分解による方法など) ちなみにExcelソルバが採用する方法は素人が手出しできるようなものではないです. あれは,「いわゆる最小二乗法」ではなく, 「非線型計画法」というもっと一般的な分野に属する方法ですので.

shin0517
質問者

補足

お忙しい中ご回答ありがとうございます。 補足内容としまして以下の点があります。 >評価関数は線型か非線型か?  →おそらく非線形だと思われます。   数学関数を実装するのは初めてで自分で調べた結果   おそらく非線形だという感触は得ましたが確証は薄いです。   ※f(x)=a*(誤差関数(x/b))のような式です。 >どんな手法を実装するのか?  →手法と言うか流れは、計算ボタンを押下したタイミングで、今回求めている処理を   走らせ、変数(上記で言えばa,b)を得るという形です。   現時点では質問内容にある、初期値での計算結果より残差二乗和は出ましたが   ここからその残差二乗和の最小値を求め、変数a,bを求める方法が   分からないというところです。 >微分を用いる方法を使うのか? >微分を使うならそれは解析的に与えるのか?  →申し訳ありません、その点に関してはこちらの知識不足でご返答出来ません。   自分で調べた結果では、残差二乗和の最小値を求める処理には   偏微分が必要という内容も見ましたが、いずれに関しても   今回のケースに合っているかと言われると確証がもてません。 >ちなみにExcelソルバが採用する方法は素人が手出しできるようなものではないです. >あれは,「いわゆる最小二乗法」ではなく, >「非線型計画法」というもっと一般的な分野に属する方法ですので.  →と言うことは「非線形計画法」をC/C++で記述するという方向からの   アタックは間違っているということでしょうか。 こちらで調べた結果以下のサイト(hを抜いています)を見付けましたが 求めている内容とは違うに感じまして当質問をしました。 ・準ニュートン法 ttp://www.sist.ac.jp/~suganuma/kougi/other_lecture/SE/opt/nonlinear/DFP_BFGS/DFP_BFGS.htm ・最小二乗法 ttp://www.sist.ac.jp/~suganuma/kougi/other_lecture/SE/predict/least/C++/least.txt

関連するQ&A