Rでのnlsモデルの正しい開始値の取得


12

次のようなデータセットに単純なべき乗則モデルを適合させようとしています。

mydf

rev     weeks
17906.4 1
5303.72 2
2700.58 3
1696.77 4
947.53  5
362.03  6

目標は、電力線を通過させ、それを使用してrev、今後数週間の値を予測することです。たくさんの研究の結果、私はこのnls機能にたどり着きました。その機能を次のように実装しました。

newMod <- nls(rev ~ a*weeks^b, data=modeldf, start = list(a=1,b=1))
predict(newMod, newdata = data.frame(weeks=c(1,2,3,4,5,6,7,8,9,10)))

これはlmモデルで機能しsingular gradientますが、エラーが発生します。これは、開始値aとに関係していることを理解していますb。私はさまざまな値を試しましたが、これをExcelでプロットし、1つを渡し、方程式を取得し、方程式の値を使用しましたが、それでもエラーが発生しました。私はこのような答えをたくさん見て、2番目の答えを試しました(最初の答えは理解できませんでした)が、結果はありませんでした。

ここで、適切な開始値を見つける方法について、いくつかのヘルプを実際に使用できます。または、nlsの代わりに使用できる他の関数。

mydf簡単に再作成したい場合:

mydf <- data.frame(rev=c(17906.4, 5303.72, 2700.58 ,1696.77 ,947.53 ,362.03), weeks=c(1,2,3,4,5,6)) 

1
Rの観点から述べられていますが(実際にはいくつかの言語で述べる必要があります)、非線形モデルフィットの適切な開始値を見つける方法は、ここでのトピックであるIMOになるほど十分統計的です。たとえば、プログラミングQではありません。
ガン-モニカの回復

回答:


13

これは、非線形最小二乗モデルの一般的な問題です。開始値が最適値から非常に離れている場合、最適値の近くで正常に動作する場合でも、アルゴリズムは収束しない可能性があります。

両側の対数を取ることから始め、線形モデルに当てはめると、と推定値を傾きと切片として取得し 9.947および-2.011)(編集:自然対数)blog(a)b

これらを使用してと開始値をガイドと、すべてが問題なく動作するように見えます。bab

 newMod <- nls(rev ~ a*weeks^b, data=mydf, start = list(a=exp(9.947),b=-2.011))
 predict(newMod, newdata = data.frame(weeks=c(1,2,3,4,5,6,7,8,9,10)))
 [1] 17919.2138  5280.7001  2584.0109  1556.1951  1050.1230   761.4947   580.3091   458.6027
 [9]   372.6231   309.4658

とても助かります、本当にありがとう!ここで「a」の値をどのように取得したかについて質問があります。lm(log10(rev)〜log10(weeks))を実行してから「summary」関数を使用してみましたが、同じ「b」値を取得していますが、「a」値が4.3201になっています。a = 9.947に到達するために、あなたは何を違った方法で行いましたか?
NeonBlueHair 2015年

以前expはそれをログに記録されていない値に戻すことに注意してください。これは、単純なlog関数を使用したことを示す手掛かりです。使用するログとアンチログに一貫している限り、開始値に対して同じ答えが得られます。だからあなたはベース10を行うことができ、私はベースを行うことができ、すべてが同じです。e
Glen_b-2015

ああ、あなたは完全に正しいです。私のアマチュアミス。"log"が10を底とする対数を意味し、 "ln"が自然対数を意味することを期待する数学的表記について考え続けました。説明をありがとう。
NeonBlueHair 2015年

1
多くの数学者(および多くの統計学者)にとって、無秩序な「対数」は自然対数です。これは、sin関数に対する無飾の引数がラジアン単位であるのと同じです。[残念なことに、規則の衝突は混乱を招く可能性がありますが、たとえばRを使い始めたとき、Rと同じ規則を共有しているため、log関数の使用については2度考えませんでした。]
Glen_b -Reinstate Monica

4

やってみる

 newMod <- nls(rev ~ a*weeks^b, data=mydf, startlist(a=17919.2127344,b=-1.76270557120))

この答えを少し広げるように言われました。この問題は非常に単純なので、nlsが失敗するのはちょっと驚きです。ただし、実際の問題は、Rアプローチ全体と非線形モデルフィッティングの哲学にあります。現実の世界では、xを-1と1の間にあるようにスケーリングし、yとyを0と1の間にあるようにスケーリングします(y = ax ^ b)。それはおそらくnlsを収束させるのに十分でしょう。もちろん、Glenが指摘するように、対応する対数線形モデルを当てはめることができます。これは、モデルを線形化する単純な変換が存在するという事実に依存しています。それはしばしばそうではありません。nlsのようなRルーチンの問題は、モデルを再パラメーター化するためのサポートを提供しないことです。この場合、再パラメーター化は単純で、xとyを再スケール/再中心化するだけです。ただし、モデルを適合させると、ユーザーは元のパラメーターとは異なるパラメーターaおよびbを持ちます。これらから元の値を計算することは簡単ですが、他の難点は、これらのパラメーター推定値の推定標準偏差を取得することは、一般にそれほど単純ではないことです。これは、対数尤度のヘッセ行列といくつかの導関数を含むデルタ法によって行われます。非線形パラメーター推定ソフトウェアはこれらの計算を自動的に提供するため、モデルの再パラメーター化が容易にサポートされます。ソフトウェアがサポートすべきもう1つのことは、フェーズの概念です。最初にモデルをグレンのバージョンにフィッティングするフェーズ1と考えることができます。「実際の」モデルはステージ2にフィッティングします。他の難点は、これらのパラメーター推定値の推定標準偏差を取得することは、一般にそれほど簡単ではないことです。これは、対数尤度のヘッセ行列といくつかの導関数を含むデルタ法によって行われます。非線形パラメーター推定ソフトウェアはこれらの計算を自動的に提供するため、モデルの再パラメーター化が容易にサポートされます。ソフトウェアがサポートすべきもう1つのことは、フェーズの概念です。最初にモデルをグレンのバージョンにフィッティングするフェーズ1と考えることができます。「実際の」モデルはステージ2にフィッティングします。他の難点は、これらのパラメーター推定値の推定標準偏差を取得することは、一般にそれほど簡単ではないことです。これは、対数尤度のヘッセ行列といくつかの導関数を含むデルタ法によって行われます。非線形パラメーター推定ソフトウェアはこれらの計算を自動的に提供するため、モデルの再パラメーター化が容易にサポートされます。ソフトウェアがサポートすべきもう1つのことは、フェーズの概念です。最初にモデルをグレンのバージョンにフィッティングするフェーズ1と考えることができます。「実際の」モデルはステージ2にフィッティングします。非線形パラメーター推定ソフトウェアはこれらの計算を自動的に提供するため、モデルの再パラメーター化が容易にサポートされます。ソフトウェアがサポートすべきもう1つのことは、フェーズの概念です。最初にモデルをグレンのバージョンにフィッティングするフェーズ1と考えることができます。「実際の」モデルはステージ2にフィッティングします。非線形パラメーター推定ソフトウェアはこれらの計算を自動的に提供するため、モデルの再パラメーター化が容易にサポートされます。ソフトウェアがサポートすべきもう1つのことは、フェーズの概念です。最初にモデルをグレンのバージョンにフィッティングするフェーズ1と考えることができます。「実際の」モデルはステージ2にフィッティングします。

自然にフェーズをサポートするADモデルビルダーを使用してモデルを適合させます。最初のフェーズでは、aのみが推定されました。これにより、モデルが球場に入ります。2番目のフェーズでは、ソリューションを取得するためにaとbが推定されます。ADモデルビルダーは、デルタメソッドを介してモデルパラメーターの関数の標準偏差を自動的に計算し、モデルの安定した再パラメーター化を促進します。


2

Levenberg-Marquardtアルゴリズムは、次のことに役立ちます。

modeldf <- data.frame(rev=c(17906.4, 5303.72, 2700.58 ,1696.77 ,947.53 ,362.03), weeks=c(1,2,3,4,5,6))

require(minpack.lm)
fit <- nlsLM(rev ~ a*weeks^b, data=modeldf, start = list(a=1,b=1))

require(broom)
fit_data <- augment(fit)

plot(.fitted~rev, data=fit_data)

1

私の経験では、NLRモデルのパラメーターの開始値を見つける良い方法は、進化的アルゴリズムを使用することです。サーチスペース内のランダムな推定(親)の初期母集団(100)から、最高の20(子孫)を選択し、これらを使用して後続の母集団の検索を定義します。収束するまで繰り返します。勾配やヘッセ行列は必要ありません。SSE評価のみです。欲張りすぎない場合、これは非常によく機能します。人々がしばしば抱える問題は、ローカル検索(Newton-Raphson)を使用してグローバル検索の作業を実行していることです。いつものように、それは目の前の仕事のための正しいツールを使用することの問題です。EAグローバル検索を使用してニュートンローカル検索の開始値を見つけ、これを最小限に抑える方が理にかなっています。しかし、すべてのものと同様に、悪魔は詳細にあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.