Tại sao nls () cung cấp cho tôi ma trận độ dốc đơn lẻ tại các tham số ban đầu ước tính lỗi lỗi?


21

Tôi có một số dữ liệu cơ bản về giảm phát thải và chi phí cho mỗi chiếc xe:

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

Tôi biết rằng đây là một hàm số mũ, vì vậy tôi hy vọng có thể tìm thấy một mô hình phù hợp với:

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

nhưng tôi đang gặp lỗi:

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

Tôi đã đọc qua rất nhiều câu hỏi về lỗi tôi gặp và tôi đang thu thập rằng vấn đề có lẽ là tôi cần các startgiá trị tốt hơn / khác nhau ( initial parameter estimatescó ý nghĩa hơn một chút) nhưng tôi không chắc chắn, vì dữ liệu mà tôi có, làm thế nào tôi muốn ước tính các tham số tốt hơn.


Tôi sẽ đề nghị bắt đầu giải mã của bạn bằng cách tìm kiếm trang web của chúng tôi để tìm thông báo lỗi .
whuber

3
Trên thực tế, tôi đã làm điều đó và việc tìm kiếm lỗi đầy đủ của tôi đã đưa ra một câu hỏi nửa vời với ba điểm dữ liệu và không có câu trả lời. Nhưng tìm kiếm cụ thể hơn của bạn sẽ nhận được một số kết quả. Có thể bởi vì bạn có nhiều kinh nghiệm hơn ở đây và biết những thuật ngữ nào nổi bật có liên quan.
Amanda

Một điều tôi đã tìm thấy về lỗi phần mềm là tìm kiếm thông báo lỗi cụ thể (thường là trong dấu ngoặc kép) là cách chắc chắn nhất để tìm hiểu xem nó đã được thảo luận trước đó chưa. (Điều này có trên Internet, không chỉ trên các trang SE.) Như thông báo "tạm dừng" của chúng tôi nói, nếu nghiên cứu bổ sung của bạn không giải quyết được vấn đề của bạn, thì vui lòng quay lại và đẩy lùi chúng tôi một chút: câu hỏi này là tại giao điểm của thống kê và điện toán và có thể phơi bày một số vấn đề rất đáng quan tâm ở đây.
whuber

1
Sự phù hợp cho các giá trị bắt đầu của bạn là rất xa dữ liệu; so sánh exp(50)exp(95)với các giá trị y tại x = 50 và x = 95. Nếu bạn đặt c=0và lấy nhật ký của y (tạo mối quan hệ tuyến tính), bạn có thể sử dụng hồi quy để lấy ước tính ban đầu cho nhật ký ( ) và b sẽ đủ cho dữ liệu của bạn (hoặc nếu bạn khớp một dòng qua gốc, bạn có thể rời khỏi a tại 1 và chỉ sử dụng ước tính cho b ; điều đó cũng đủ cho dữ liệu của bạn). Nếu b nằm ngoài một khoảng khá hẹp xung quanh hai giá trị đó, bạn sẽ gặp phải một số vấn đề. [Hoặc thử một thuật toán khác]ababb
Glen_b -Reinstate Monica

1
Cảm ơn @Glen_b. Tôi đã hy vọng tôi có thể sử dụng R thay cho máy tính vẽ đồ thị để làm việc thông qua sách giáo khoa giới thiệu số liệu thống kê (và bước nhảy vọt của chính khóa học) vì vậy tôi chỉ bắt đầu với cái nhìn sâu sắc thống kê rõ ràng nhất, nhưng có nhiều kinh nghiệm thực hiện việc cắt và cắt nhỏ khác trong R .
Amanda

Câu trả lời:


37

Tự động tìm giá trị khởi đầu tốt cho mô hình phi tuyến là một nghệ thuật. (Nó tương đối dễ dàng cho các bộ dữ liệu một lần khi bạn chỉ có thể vẽ dữ liệu và đưa ra một số dự đoán tốt một cách trực quan.) Một cách tiếp cận là tuyến tính hóa mô hình và sử dụng các ước lượng bình phương tối thiểu.

Trong trường hợp này, mô hình có dạng

E(Y)=aexp(bx)+c

cho các tham số chưa biết . Sự hiện diện của số mũ khuyến khích chúng ta sử dụng logarit - nhưng việc thêm c gây khó khăn cho việc đó. Tuy nhiên, lưu ý rằng nếu a dương thì c sẽ nhỏ hơn giá trị mong đợi nhỏ nhất của Ya,b,ccacY --và do đó có thể là một chút ít so với nhỏ nhất quan sát được giá trị của . (Nếu a có thể âm, bạn cũng sẽ phải xem xét giá trị của c lớn hơn một chút so với giá trị quan sát lớn nhất của Y. )YacY

Sau đó, chúng ta hãy quan tâm đến bằng cách sử dụng như ước tính ban đầu c 0 gì đó giống như một nửa mức tối thiểu của các quan sát y i . Mô hình bây giờ có thể được viết lại mà không có thuật ngữ phụ gia gai góc nhưcc0yi

E(Y)c0aexp(bx).

Rằng chúng ta có thể lấy nhật ký của:

log(E(Y)c0)log(a)+bx.

Đó là một xấp xỉ tuyến tính cho mô hình. Cả b có thể được ước tính với bình phương nhỏ nhất.log(a)b

Đây là mã sửa đổi:

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)

Đầu ra của nó (đối với dữ liệu ví dụ) là

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

Sự hội tụ có vẻ tốt. Hãy vẽ nó:

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

Figure

Nó hoạt động tốt!

Khi tự động hóa việc này, bạn có thể thực hiện một số phân tích nhanh về phần dư, chẳng hạn như so sánh cực trị của chúng với mức chênh lệch trong dữ liệu ( ). Bạn cũng có thể cần mã tương tự để đối phó với khả năng một < 0 ; Tôi để nó như một bài tập.ya<0


Một phương pháp để ước tính giá trị ban đầu dựa trên sự hiểu biết ý nghĩa của chúng, có thể được dựa trên kinh nghiệm, lý thuyết vật lý, vv Một mở rộng ví dụ về một (vừa phải khó khăn) phù hợp phi tuyến có giá trị ban đầu có thể được xác định theo cách này được mô tả trong câu trả lời của tôi tại /stats//a/15769 .

Phân tích trực quan của một biểu đồ phân tán (để xác định ước tính tham số ban đầu) được mô tả và minh họa tại /stats//a/32832 .

Trong một số trường hợp, một chuỗi các sự phù hợp phi tuyến được thực hiện trong đó bạn có thể mong đợi các giải pháp thay đổi từ từ. Trong trường hợp đó, việc sử dụng các giải pháp trước đây như là ước tính ban đầu cho các giải pháp tiếp theo thường thuận tiện (và nhanh chóng) . Tôi nhớ lại bằng cách sử dụng kỹ thuật này (không có nhận xét) tại /stats//a/63169 .


2

Thư viện này đã có thể giải quyết vấn đề của tôi với nls's singular gradient: http://www.r-bloggers.com/a-better-nls/ Một ví dụ:

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

Chức năng đó dường như được gọi nls.lmngay bây giờ.
Matt

-1

Vì vậy, ... tôi nghĩ rằng tôi đã đọc sai đây là một hàm số mũ. Tất cả tôi cần là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)))

Hoặc, sử dụng 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
Điều này không trả lời câu hỏi bạn đã hỏi - nó thay đổi nó thành một cái gì đó khác (và khá ít thú vị hơn, IMHO).
whuber

6
Mặc dù, nó có thể giải quyết vấn đề phù hợp với chức năng để thể hiện dữ liệu, nhưng câu trả lời được chấp nhận của bạn không phải là mong đợi cho câu hỏi của bạn. Ông @whuber cung cấp cho bạn một lời giải thích tuyệt vời và xứng đáng với câu trả lời được chấp nhận.
Lộ Lộ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.