24

少し前にこの質問をしました。これを回答として投稿するか、新しい質問として投稿するかがわかりません。答えはありませんが、nls.lmRを使用してLevenberg-Marquardtアルゴリズムを適用することで問題を「解決」し、解決策が境界にある場合は、信頼領域反射アルゴリズム(Rで実装されたTRR)を実行してステップを実行しますそれから離れてください。今、私は新しい質問があります。

私の経験から、この方法でプログラムは最適に到達し、開始値にそれほど敏感ではありません。しかし、これは、私が遭遇した問題やRの他の最適化関数を回避するための実用的な方法にすぎません。境界制約のある最適化問題に対して がこのように動作する理由と、実際に使用するときに境界制約を処理する方法をnls.lm知りたいです。.nls.lmnls.lm

次に、 を使用して 2 つの問題を説明する例を示しましたnls.lm

  1. 開始値に敏感です。
  2. 一部のパラメータが境界に達すると停止します。

再現可能な例: フォーカス データセット D

library(devtools)
install_github("KineticEval","zhenglei-gao")
library(KineticEval)
data(FOCUS2006D)
km <- mkinmod.full(parent=list(type="SFO",M0 = list(ini   = 0.1,fixed = 0,lower = 0.0,upper =Inf),to="m1"),m1=list(type="SFO"),data=FOCUS2006D)
system.time(Fit.TRR <- KinEval(km,evalMethod = 'NLLS',optimMethod = 'TRR'))
system.time(Fit.LM <- KinEval(km,evalMethod = 'NLLS',optimMethod = 'LM',ctr=kingui.control(runTRR=FALSE)))
compare_multi_kinmod(km,rbind(Fit.TRR$par,Fit.LM$par))
dev.print(jpeg,"LMvsTRR.jpeg",width=480)

LM フィット vs TRR フィット

モデル/システムを記述する微分方程式は次のとおりです。

"d_parent = - k_parent * parent"                                                 
"d_m1 = - k_m1 * m1 + k_parent * f_parent_to_m1 * parent" 

左側のグラフは初期値を使用したモデル、中央は "TRR" (Matlablsqnonlin関数のアルゴリズムと同様) を使用した近似モデル、右側は "LM" を使用した近似モデルnls.lmです。適合した parameters( ) を見ると、1 つの適合した parameter( ) が境界にFit.LM$parあることがわかります。1 つのパラメーターの開始値を0.1 から 100 に変更すると、 and を使用して同じ結果が得られました。このようなケースがたくさんあります。f_parent_to_m11M0_parentnls.lmlsqnonlin

newpars <- rbind(Fit.TRR$par,Fit.LM$par)
rownames(newpars)<- c("TRR(lsqnonlin)","LM(nls.lm)")
newpars

                   M0_parent   k_parent        k_m1 f_parent_to_m1
TRR(lsqnonlin)  99.59848 0.09869773 0.005260654       0.514476
LM(nls.lm)      84.79150 0.06352110 0.014783294       1.000000

上記の問題を除いて、によって返されるヘッセ行列がnls.lm可逆でないことがよくあります (特に、いくつかのパラメーターが境界上にある場合)。そのため、共分散行列の推定値を取得できません。一方、"TRR" アルゴリズム (Matlab 内) は、ほとんどの場合、解点でヤコビアンを計算することによって推定を行います。これは便利だと思いますが、R 最適化アルゴリズム (私が試したもの) が何らかの理由でこれを行わなかったことも確かです。パラメータ推定値の標準誤差を得るために共分散行列を計算する Matlab の方法を使用して、私が間違っているかどうかを知りたいです。

最後の注意点として、私は以前の投稿で、ほぼすべてのケースで Matlablsqnonlinが R の最適化関数よりも優れていると主張しました。私は間違っていた。上記の例からわかるように、Matlab で使用される「Trust-Region-Reflective」アルゴリズムは、R でも実装されている場合、実際には遅くなります (場合によってははるかに遅くなります)。ただし、R の基本的な最適化アルゴリズムよりも安定しており、より優れたソリューションに到達します。

4

2 に答える 2

1

まず、私は Matlab と最適化の専門家ではなく、R を使用したことがありません。

あなたの実際の質問が何であるかはわかりませんが、あなたの困惑に光を当てることができるかもしれません:

LM は、わずかに拡張されたガウス-ニュートン アプローチです。いくつかの極小値を持つ問題では、初期状態に非常に敏感です。境界を含めると、通常、これらの最小値がより多く生成されます。

TRR は LM に似ていますが、より堅牢です。悪い極小値から「飛び出す」ための優れた機能があります。LM よりも優れた動作をする可能性がありますが、LM よりもパフォーマンスが低下する可能性があります。実際に理由を説明するのは非常に難しいです。アルゴリズムを詳細に調べて、この状況でどのように動作するかを調べる必要があります。

Matlab と R の実装の違いを説明することはできませんが、TRR には、Matlab が使用し、R が使用しない拡張機能がいくつかあります。LM と TRR を交互に使用するアプローチは、TRR のみを使用するよりも収束しやすいですか?

于 2013-11-11T10:26:06.800 に答える
0

mkin パッケージを使用すると、"Port" アルゴリズム (ドキュメントからわかる限り、TRR アルゴリズムの一種でもあります)、または nls.lm を使用する "Marq" アルゴリズムを使用してパラメーターを見つけることができます。背景。次に、「通常の」開始値または「悪い」開始値を使用できます。

library(mkin)
packageVersion("mkin")

最近の mkin バージョンでは、システムでコンパイラが使用可能な場合 (たとえば、Debian/Ubuntu に r-base-dev がインストールされているか、Windows に Rtools がインストールされている場合)、自動生成された C コードからモデルをコンパイルするため、プロセスが大幅に高速化されます。

これはモデルを定義します:

m <- mkinmod(parent = mkinsub("SFO", "m1"),
             m1 = mkinsub("SFO"),
             use_of_ff = "max")

微分方程式が正しいことを確認できます。

cat(m$diffs, sep = "\n")

次に、M0 が 0.1 に固定されているかどうかに関係なく、Port と LM の 4 つのバリアントに適合します。

f.Port = mkinfit(m, FOCUS_2006_D)
f.Port.M0 = mkinfit(m, FOCUS_2006_D, state.ini = c(parent = 0.1, m1 = 0))
f.LM = mkinfit(m, FOCUS_2006_D, method.modFit = "Marq")
f.LM.M0 = mkinfit(m, FOCUS_2006_D, state.ini = c(parent = 0.1, m1 = 0),
               method.modFit = "Marq")

次に、結果を見てみましょう。

results <- sapply(list(Port = f.Port, Port.M0 = f.Port.M0, LM = f.LM, LM.M0 = f.LM.M0),
  function(x) round(summary(x)$bpar[, "Estimate"], 5))

どれが

                   Port  Port.M0       LM    LM.M0
parent_0       99.59848 99.59848 99.59848 39.52278
k_parent        0.09870  0.09870  0.09870  0.00000
k_m1            0.00526  0.00526  0.00526  0.00000
f_parent_to_m1  0.51448  0.51448  0.51448  1.00000

したがって、Port アルゴリズムが (私の知る限りでは) 開始値が不適切な場合でも最適なソリューションを見つけることがわかります。より複雑なモデルで発生する可能性がある速度の問題は、C コードの自動生成を使用して軽減されます。

于 2016-10-19T15:10:48.913 に答える