2017-02-28 78 views
1

我需要幫助擬合nls並找到不會導致奇異矩陣的初始估計。我將不勝感激任何幫助。NLS曲線擬合奇異矩陣錯誤

via_data$Concentration <- c(0.197, 0.398, 0.792, 1.575, 
          3.154, 6.270, 12.625, 25.277, 
          25.110, 49.945, 74.680) 
via_data$Viability <- c(100, 94.62, 96.21, 87.53, 
         80, 62.22, 39.11, 
         30.80, 30, 22, 2.56) 
x <- via_data$Concentration 
y <- via_data$Viability 
fit <- nls(y ~((1/(1+Epsup/x)^Bup)*(1/(1+Epsdn/x)^Bdn)), start=list(Epsup=0, Bup=1, Epsdn=10, Bdn=-5), trace=T) 

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

感謝, Krina

+0

您的公式與'y〜1 /(1 + Epsup/x)^(Bup + Bdn)相同'因此,您只能估計'Bup + Bdn'。也相同:'y〜(1 + Epsup/x)^( - Bup-Bdn)' – jogo

+0

這不是問題,因爲http://stackoverflow.com/questions/34201377/r-and-nls-singular-gradient - 矩陣 - 在-初始參數。在這個問題上,問題是過度參與。一般來說,這個問題並沒有被過度參數化,但是隻有當'Epsup = Epsdn'或者任何參數接近於零時,以及存在的問題是我們必須確定'1 + Epsup/x'和'1 + Epsdn/x'仍然是積極的。因此,如果我們可以找到足夠好的起始值,遠離這些不好的地方,它可以解決.. –

回答

2

下面st是你的初始值,除了我們已經使用Epsup=1避免退化爲0 fo是公式。爲了防止將負數提升爲功率,我們用sqrt(Epsup^2)代替Epsup,並且類似地代替Epsdn - 這增加了假設EpsupEspdn不能爲負。 (這與使用abs(Epsup)相同;但是,nlxb在其派生表中沒有abs)。接下來使用nls2在邊界st/1010*st之間的網格上生成值。 nls2將生成這些並返回一個"nls"對象找到最好的一個。現在用它作爲nlmrt軟件包的nlxb的起始值。它處理難以比nls更難的問題。 nlxb不會返回"nls"對象(雖然包確實有wrapnls它運行之後nlsnlxb但當時我們沒有得到來自nlxb直接輸出),因此飼料通過nls2再創建一個"nls"對象,允許我們使用fitted方法。我們繪製出適合的結果。

library(nlmrt) 
library(nls2) 

st <- c(Epsup=1, Bup=1, Epsdn=10, Bdn=-5) 
fo <- y ~ (1/(1+sqrt(Epsup^2)/x)^Bup)*(1/(1+sqrt(Epsdn^2)/x)^Bdn) 

fit.nls2 <- nls2(fo, start = data.frame(rbind(st/10, 10*st)), alg = "brute") 
fit.nlxb <- nlxb(fo, data = data.frame(x, y), start = coef(fit.nls2)) 

給予以下:

> fit.nlxb 
nlmrt class object: x 
residual sumsquares = 171.2 on 11 observations 
    after 19 Jacobian and 25 function evaluations 
    name   coeff   SE  tstat  pval  gradient JSingval 
Epsup   10.7464   10.95  0.9814  0.3591 6.855e-05  1584 
Bup    1.15049  0.5928  1.941 0.09345 0.001839  120.2 
Epsdn   642.754   908.5  0.7075  0.5021 -1.298e-06  1.406 
Bdn    -1.13885  0.6315  -1.804  0.1143 0.004964 0.005443 

,並密謀直觀地評估擬合:

fit.nlxb.nls <- nls2(fo, start = coef(fit.nlxb)) 
plot(y ~ x) 
lines(fitted(fit.nlxb.nls) ~ x) 

screenshot

注:我們用這個輸入:

via_data <- data.frame(Concentration = c(0.197, 0.398, 0.792, 1.575, 
    3.154, 6.270, 12.625, 25.277, 25.110, 49.945, 74.680), 
Viability = c(100, 94.62, 96.21, 87.53, 80, 62.22, 39.11, 
         30.80, 30, 22, 2.56)) 
x <- via_data$Concentration 
y <- via_data$Viability 
+0

非常有幫助。謝謝 –