nls()で「初期パラメーター推定での特異勾配行列」エラーが発生するのはなぜですか?


21

排出削減と車あたりのコストに関するいくつかの基本的なデータがあります。

q24 <- read.table(text = "reductions  cost.per.car
    50  45
    55  55
    60  62
    65  70
    70  80
    75  90
    80  100
    85  200
    90  375
    95  600
    ",header = TRUE, sep = "")

これは指数関数であることを知っているので、以下に適合するモデルを見つけることができると期待しています。

    model <- nls(cost.per.car ~ a * exp(b * reductions) + c, 
         data = q24, 
         start = list(a=1, b=1, c=0))

しかし、私はエラーが発生しています:

Error in nlsModel(formula, mf, start, wts) : 
  singular gradient matrix at initial parameter estimates

私は私が見ているエラーに関するたくさんの質問を読んでおり、問題はおそらくより良い/異なるstart値が必要であることを収集しています(initial parameter estimatesもう少し理にかなっています)が、私が持っているデータ、より良いパラメータを推定する方法。


たちのサイトでエラーメッセージを検索することであなたの解読を始めることをお勧めします
whuber

3
実際、私はそれをしました、そして、完全なエラーの私の検索は、3つのデータポイントと答えのない中途半端な質問になりました。しかし、より具体的な検索では結果が得られます。おそらく、ここでより多くの経験を持ち、どの用語が関連するものとして際立っているかを知っているからでしょう。
アマンダ

ソフトウェアエラーについて私が発見したことの1つは、特定のエラーメッセージ(通常は引用符で囲む)の検索が、それが以前に議論されたかどうかを確認する最も確実な方法であるということです。(これは、SEサイトだけでなく、インターネット全体に適用されます。)「保留」メッセージが示すように、追加の調査で問題が解決しない場合は、戻って少し押し戻してください。この質問は統計とコンピューティングの共通部分であり、ここで大きな関心のあるいくつかの問題を明らかにするかもしれません。
whuber

1
開始値への適合は、データからはほど遠いです。x = 50およびx = 95でのy値exp(50)と比較しexp(95)ます。c=0yの対数を設定して取得する場合(線形関係を作成する場合)、回帰を使用して、データに十分なlog()および初期推定値を取得できます(または、原点を通る直線を当てはめる場合は、そのままにしておくことができます)を1に設定し、の推定値を使用するだけで、データにも十分です)。場合、これら二つの値の周りのかなり狭い間隔ずっと外で、あなたはいくつかの問題に実行されます。[別のアルゴリズムを試す]b a b bababb
Glen_b -Reinstate Monica

1
@Glen_bに感謝します。グラフ計算機の代わりにRを使用して統計イントロの教科書を操作できることを期待していました(そして、コース自体を飛ばします)。 。
アマンダ

回答:


38

非線形モデルの適切な開始値を自動的に見つけることは芸術です。(1回限りのデータセットでは、データをプロットして視覚的に適切に推測できる場合、比較的簡単です。)1つのアプローチは、モデル線形化し、最小二乗推定を使用することです。

この場合、モデルの形式は

EY=aexpbバツ+c

不明なパラメータ。指数の存在は、対数を使用することを奨励しますが、を追加すると、それを行うことが難しくなります。通知は、しかし、場合に正次いで以下の最小期待値よりなり従って--and最小弱かもしれない観測値。(が負になる可能性がある場合、値は最大観測値よりも少し大きいことも考慮する必要があります。)c a c Y Y a c YabccacYYacY

それでは、観測値最小値の半分のような初期推定値を使用してを処理します。モデルは、その厄介な加法的用語なしで次のように書き換えられるようになりました。c 0 y icc0y

EYc0aexpbバツ

のログを取得できること:

ログEYc0ログa+bバツ

これはモデルの線形近似です。とは両方とも最小二乗で推定できます。bログab

修正されたコードは次のとおりです。

c.0 <- min(q24$cost.per.car) * 0.5
model.0 <- lm(log(cost.per.car - c.0) ~ reductions, data=q24)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(cost.per.car ~ a * exp(b * reductions) + c, data = q24, start = start)

その出力(サンプルデータ)は

Nonlinear regression model
  model: cost.per.car ~ a * exp(b * reductions) + c
   data: q24
        a         b         c 
 0.003289  0.126805 48.487386 
 residual sum-of-squares: 2243

Number of iterations to convergence: 38 
Achieved convergence tolerance: 1.374e-06

収束がよさそうです。プロットしましょう:

plot(q24)
p <- coef(model)
curve(p["a"] * exp(p["b"] * x) + p["c"], lwd=2, col="Red", add=TRUE)

図

うまくいきました!

これを自動化する場合、極値と()データの広がりを比較するなど、残差の簡単な分析を実行できます。また、可能性を処理するために類似のコードが必要になる場合があります。演習として残しておきます。a < 0ya<0


初期値を推定する別の方法は、経験、物理理論などに基づいた、意味の理解に依存します この方法で初期値を決定できる(適度に難しい)非線形近似の拡張例は、私の回答で説明されていますで/stats//a/15769

散布図の視覚的分析(初期パラメーター推定値を決定するため)は、/stats//a/32832で説明および図解されています

状況によっては、解がゆっくりと変化することが予想される場合に、非線形近似のシーケンスが作成されます。その場合、次のソリューションの初期推定値として以前のソリューション使用すると便利です(そして高速です)。/stats//a/63169で(コメントなしで)この手法を使用したことを思い出します


2

このライブラリは、nlsの問題を解決できましたsingular gradienthttp : //www.r-bloggers.com/a-better-nls/ 例:

library(minpack.lm)
nlsLM(function, start=list(variable=2,variable2=12))

その関数はnls.lm今呼び出されているようです。
マット

-1

だから...私はこれを指数関数と誤解していると思う。必要なのはpoly()

model <- lm(cost.per.car ~ poly(reductions, 3), data=q24)
new.data <- data.frame(reductions = c(91,92,93,94))
predict(model, new.data)

plot(q24)
lines(q24$reductions, predict(model, list(reductions = q24$reductions)))

または、次を使用lattice

xyplot(cost.per.car ~ reductions, data = q24,
       panel = function(x, y) {
         panel.xyplot(x, y)
         panel.lines(x, predict(model,list(reductions = x) ))
       }, 
       xlab = "Reductions", 
       ylab = "Cost per car")

2
これは、あなたが尋ねた質問には答えません。それを異なるものに変更します(そして、面白くない、私見)。
whuber

6
データを表すために関数を適合させる問題を解決するかもしれませんが、受け入れられた答えはあなたの質問に対する期待ではありません。@whuber氏は優れた説明を提供し、受け入れられた答えに値します。
ロウレンソ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.