Nls () neden bana “ilk parametre tahminlerinde tekil gradyan matrisi” hatası veriyor?


21

Emisyon azaltımı ve araç başına maliyet hakkında bazı temel verilerim var:

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 = "")

Bu üstel bir işlev olduğunu biliyorum, bu yüzden uygun bir model bulmak için bekliyoruz:

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

ama bir hata alıyorum:

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

Gördüğüm hata hakkında bir ton soru okudum ve sorunun muhtemelen daha iyi / farklı startdeğerlere ihtiyacım olduğu ( initial parameter estimatesbiraz daha mantıklı) olduğunu düşünüyorum ama emin değilim, verilen sahip olduğum veriler, daha iyi parametreler tahmin etmeye nasıl devam edeceğim.


Hata mesajını sitemizde arayarak deşifre işleminize başlamanızı öneririm .
whuber

3
Aslında bunu yaptım ve tam hatayı araştırmam, üç veri noktası olan ve cevapsız yarı pişmiş bir soruya dönüştü. Ancak daha spesifik aramanız bazı sonuçlar verir. Muhtemelen burada daha fazla deneyime sahip olduğunuz ve hangi terimlerin alakalı olduğunu öne sürdüğünüz için.
Amanda

Yazılım hataları hakkında bulduğum bir şey, belirli bir hata mesajı (genellikle tırnak işaretleri içinde) aramasının, daha önce tartışılıp tartışılmadığını bulmanın en kesin yolu olmasıdır. (Bu, yalnızca SE sitelerinde değil, İnternet genelinde de geçerlidir.) "Beklemede" mesajımızın söylediği gibi, ek araştırmanız sorununuzu çözmezse, lütfen geri dönün ve bizi biraz itin: bu soru istatistik ve bilgi işlemin kesişim noktasıdır ve burada büyük ilgi gören bazı konuları ortaya çıkarabilir.
whuber

1
Başlangıç ​​değerleriniz için uygunluk verilerden çok uzaktır; exp(50)ve exp(95)x = 50 ve x = 95'teki y değerlerini karşılaştırın . Eğer ayarlarsanız c=0ve y günlüğünü (doğrusal ilişki yapma) almak, günlüğün (başlangıç tahminler almak için regresyon kullanabilirsiniz ) ve b Eğer kökenli bir çizgi uyarlarsa verileriniz için yeterli olacaktır (veya, gidebilirsin a 1 olarak ayarlayın ve b için tahmini kullanın ; bu da verileriniz için yeterlidir). Eğer b çok dışında bu iki değerler etrafında oldukça dar aralık ise, bazı sorunlarla edeceğiz. [Alternatif olarak farklı bir algoritma deneyin]birbbirbb
Glen_b

1
Teşekkürler @Glen_b. Ben bir istatistik intro ders kitabı (ve kursun kendisi sıçrama) çalışmak için bir grafik hesap makinesi yerine R kullanabilirsiniz umuyordum, bu yüzden sadece en bariz istatistiksel içgörü ile başlıyorum, ama R diğer dilimleme ve küp şeklinde yapma deneyimi çok .
Amanda

Yanıtlar:


38

Doğrusal olmayan bir model için otomatik olarak iyi başlangıç ​​değerleri bulmak bir sanattır. (Sadece verileri çizip görsel olarak iyi tahminler yapabileceğiniz tek seferlik veri kümeleri için nispeten kolaydır.) Bir yaklaşım, modeli doğrusallaştırmak ve en küçük kareler tahminlerini kullanmaktır.

Bu durumda, model şu şekildedir:

E(Y)=birtecrübe(bx)+c

bilinmeyen parametreler için . Üstel varlığı bizi logaritmaları kullanmaya teşvik eder - ancak c'nin eklenmesi bunu yapmayı zorlaştırır. Bildirim olsa da, eğer bir pozitif sonra c az en küçük beklenen değerden olacak Y nedenle --ve en küçük biraz daha az olabilir gözlenen değeri Y . (Eğer bir negatif olabilir ayrıca bir değerini düşünmek zorunda kalacak c en büyük gözlenen değerden daha küçük büyüktür Y .)bir,b,ccbircYYbircY

Bize, o zaman, yapsın başlangıç tahmini olarak kullanarak c 0 gözlemlerin yarısı asgari gibi bir şey y ı . Model şimdi bu dikenli ek terim olmadan yeniden yazılabilircc0yben

E(Y)-c0birtecrübe(bx).

Şu günlüğü alabiliriz:

günlük(E(Y)-c0)günlük(bir)+bx.

Bu, modele doğrusal bir yaklaşımdır. Hem hem de b , en küçük karelerle tahmin edilebilir.günlük(bir)b

Düzeltilmiş kod:

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)

Çıkışı (örnek veriler için)

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

Yakınsama iyi görünüyor. Hadi çizelim:

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

şekil

İyi çalıştı!

Bunu otomatikleştirirken, artıkların aşırı uçlarını ( ) verilerindeki yayılımla karşılaştırması gibi bazı hızlı analizler yapabilirsiniz . Ayrıca olasılık başa benzer bir kod gerekebilir a < 0 ; Bunu bir egzersiz olarak bırakıyorum.ybir<0


Başlangıç değerlerini tahmin etmek için başka bir yöntem de, ne anlama geldiğini anlamak dayanır tecrübe, fiziksel teorisine dayandığı edilebileceği vb bir başlangıç değerleri bu yolla tespit edilebilir cevabım açıklanan bir (orta derecede zor) doğrusal olmayan uyum örneği genişletilmiş en /stats//a/15769 .

Dağılım grafiğinin görsel analizi (başlangıç ​​parametre tahminlerini belirlemek için) /stats//a/32832 adresinde açıklanmıştır .

Bazı durumlarda, çözeltilerin yavaşça değişmesini bekleyebileceğiniz bir dizi doğrusal olmayan uyum yapılır. Bu durumda , önceki çözümleri bir sonraki çözümler için başlangıç ​​tahminleri olarak kullanmak genellikle uygun (ve hızlı) olur . Https://stats.stackexchange.com/a/63169 adresinde bu tekniği kullanarak (yorum yapmadan) hatırlıyorum .



-1

Yani ... sanırım bunu üstel bir işlev olarak yanlış okudum. Tek ihtiyacım olanpoly()

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)))

Veya 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
Bu, sorduğunuz soruya cevap vermiyor - farklı bir şeye (ve daha az ilginç olan IMHO) dönüştürüyor.
whuber

6
Verileri temsil etmek için bir işleve uyma sorununu çözse de, kabul edilen yanıtlarınız sorunuzun beklentisi değildir. Bay @whuber size mükemmel bir açıklama yaptı ve kabul edilen cevabı hak etti.
Lourenco
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.