2012-12-19 106 views
1

我正在嘗試編寫一個基本函數,使用nls來添加一些最適合繪圖的線條。 這工作正常,除非數據恰好由傳遞給nls的公式定義。我意識到這些問題,並且這是有記錄的行爲as reported herenls最適合的線條 - 如何強制繪製線條?

雖然我的問題是如何解決這個問題,並強制繪製最適合的線條,而不管模型中的數據是完全描述的?有沒有辦法準確檢測數據匹配並繪製完美擬合的曲線?我現在的狡猾的解決方案是:

#test data 
x <- 1:10 
y <- x^2 
plot(x, y, pch=20) 

# polynomial line of best fit 
f <- function(x,a,b,d) {(a*x^2) + (b*x) + d} 
fit <- nls(y ~ f(x,a,b,d), start = c(a=1, b=1, d=1)) 
co <- coef(fit) 
curve(f(x, a=co[1], b=co[2], d=co[3]), add = TRUE, col="red", lwd=2) 

哪個失敗,出現錯誤:

Error in nls(y ~ f(x, a, b, d), start = c(a = 1, b = 1, d = 1)) : 
    singular gradient 

的簡單的解決方法我申請是jitter稍微數據,但是這似乎有點破壞性和hackish的。

# the above code works after doing... 
y <- jitter(x^2) 

有沒有更好的方法?

+0

都一樣,在現實世界中,這種情況永遠不會發生。總是有測量誤差。除非你是一位正在參加R考試並且爲你的學生提供完美數據集的老師,那就是:-)。 –

+0

@CarlWitthoft如果n很小,我就會遇到這樣的問題,即將數據從Excel導出爲CSV(並舍入爲可見數字)。 – Roland

+0

@Roland,我想如果你不適當地測試你的測試數據(即丟失有效的sig figs),你會得到你應得的:-) –

回答

6

Use Levenberg-Marquardt

x <- 1:10 
y <- x^2 

f <- function(x,a,b,d) {(a*x^2) + (b*x) + d} 
fit <- nls(y ~ f(x,a,b,d), start = c(a=1, b=0, d=0)) 

Error in nls(y ~ f(x, a, b, d), start = c(a = 1, b = 0, d = 0)) : 
    number of iterations exceeded maximum of 50 

library(minpack.lm) 
fit <- nlsLM(y ~ f(x,a,b,d), start = c(a=1, b=0, d=0)) 
summary(fit) 

Formula: y ~ f(x, a, b, d) 

Parameters: 
    Estimate Std. Error t value Pr(>|t|)  
a  1   0  Inf <2e-16 *** 
b  0   0  NA  NA  
d  0   0  NA  NA  
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 0 on 7 degrees of freedom 

Number of iterations to convergence: 1 
Achieved convergence tolerance: 1.49e-08 

請注意,我必須調整起始值,結果對起始值很敏感。

fit <- nlsLM(y ~ f(x,a,b,d), start = c(a=1, b=0.1, d=0.1)) 

Parameters: 
    Estimate Std. Error t value Pr(>|t|)  
a 1.000e+00 2.083e-09 4.800e+08 < 2e-16 *** 
b -7.693e-08 1.491e-08 -5.160e+00 0.00131 ** 
d 1.450e-07 1.412e-08 1.027e+01 1.8e-05 *** 
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 6.191e-08 on 7 degrees of freedom 

Number of iterations to convergence: 3 
Achieved convergence tolerance: 1.49e-08