web-dev-qa-db-ja.com

Rを使用したシグモイド曲線のあてはめ

私は投稿を読みました(Rのシグモイド曲線フィット)。重複のラベルが付けられましたが、投稿に関連するものは何も表示されません。そして、投稿に対して与えられた答えは十分ではありませんでした。

私は webpage を読みました

他の人と同様に、彼はこのフォーマットを使用して行を合わせています。

fitmodel <- nls(y~a/(1 + exp(-b * (x-c))), start=list(a=1,b=.5,c=25))

問題は、ほとんどの場合、a、b、cが指定されていて、データのセットにどのa、b、cのセットを使用するべきかについての手掛かりがないことです。パラメータを取得する方法について誰かがアドバイスをくれませんか?

これが私の番号のセットです:

x <- c(3.9637878,3.486667,3.0095444,2.5324231,2.0553019,1.5781806,1.1010594,0.6242821)
y <- c(6491.314,6190.092,2664.021,2686.414,724.707,791.243,1809.586,541.243)
9
FunnyFunkyBuggy

幸運なことに、Rはロジスティックモデルの自動開始モデルを提供します。わずかな再パラメータ化を使用しますが、実際には同じモデルです:Asym/(1+exp((xmid-input)/scal))

自動開始モデルは適切な開始値を推定できるため、それらを指定する必要はありません。

plot(y ~ x)
fit <- nls(y ~ SSlogis(x, Asym, xmid, scal), data = data.frame(x, y))

summary(fit)
#Formula: y ~ SSlogis(x, Asym, xmid, scal)
#
#Parameters:
#      Estimate Std. Error t value Pr(>|t|)
#Asym 1.473e+04  2.309e+04   0.638    0.551
#xmid 4.094e+00  2.739e+00   1.495    0.195
#scal 9.487e-01  5.851e-01   1.622    0.166
#
#Residual standard error: 941.9 on 5 degrees of freedom
#
#Number of iterations to convergence: 0 
#Achieved convergence tolerance: 4.928e-06

lines(seq(0.5, 4, length.out = 100), 
      predict(fit, newdata = data.frame(x = seq(0.5, 4, length.out = 100))))

resulting plot

もちろん、データは実際にはモデルをサポートしていません。推定された中点はデータ範囲の適切な限界にあるため、パラメーターの推定値(特に漸近線)は非常に不確かです。

5
Roland

私があなたのデータを適合させるために使用したコード:

 df <- data.frame(x=c(3.9637878,3.486667,3.0095444,2.5324231,2.0553019,1.5781806,1.1010594,0.6242821),                     
                  y=c(6491.314,6190.092,2664.021,2686.414,724.707,791.243,1809.586,541.243))

library(drc)
fm <- drm(y ~ x, data = df, fct = G.3())

plot(fm)
summary(fm)

フィッティング後の様子: enter image description here

2
numb

2つの問題が表示されます。

  1. nlsのデフォルトのアルゴリズムは、開始パラメーターに非常に敏感です。あなたの例のデータでは、algorithm='port'。あるいは、「堅牢な」実装に切り替えることも役立つ場合があります。

  2. これは、モデル内のパラメーターの役割を理解するのに役立ちます。

モデルの単純な解釈は、次のとおりです。シグモイドは0からaまでyに入ります。これは、x = cで「中間点」に到達します。 bには勾配の役割があり、負の場合、モデルはaから0に変わります。

具体的には、あなたが投稿したテストデータに対して、次のように開始値を見積もります。

  • 最初に気付くのは、データが正確にゼロに近いわけではないため、約1000のオフセットdを追加すると便利かもしれません。
  • aは5000以上
  • cはどこか大きい2-多分3
  • b推測する必要があります-x 2から3.5への信号の1000から6000へのジャンプは5000の差を与えます-aで除算-1/1.5 = 0.66以上の傾き... 1に丸めます。

だから最終的に式を使用して

fitmodel <- nls(y ~a/(1 + exp(-b * (x-c)) ) + d, start=list(a=5000,b=1,c=3, d=1000))

フィットを与えます(dなしでも機能します)。試してみたところ、設定が見つかりましたalgorithm='port'により、コマンドは開始値に対する感度がさらに低くなりました。

1
bdecaf