• R语言
  • 非线性拟合模型的初始参数

问一个问题啊,非线性拟合模型需要给定初始参数,我想用循环来找出合理的初始参数,怎么弄啊?

我的数据:

[data]

> mean.w

day mean

337 0 0.169650

339 4 0.306950

341 8 0.482350

343 12 0.743450

345 16 1.286895

347 20 2.473700

349 24 2.982200

351 28 5.423950

353 35 9.739550

355 42 15.723950

357 49 22.787900

359 56 39.161211

361 63 48.866000

363 70 52.302700

[/data]

我的循环体如下:

<br />
i <- 100<br />
while (TRUE) {<br />
  i <- i + 10<br />
  nls.sol <- nls(mean ~ A/(1 + B*exp(-k*day)),<br />
                 start = list(A = i, B = 0.5, k = 0.6),<br />
                 data = mean.w)<br />
  if (exists("nls.sol")) break<br />
}<br />


程序中,如果参数A不正确,那么nls.sol就计算不出来,即nls.sol不存在。现在关键是如果A不正确,那么程序会跳出错误警告,并且终止运行。怎么可以让程序忽略这种错误而继续运行?
</p>

貌似统计之都的人气大不如前啊,好多帖子都没有回音。[s:12]

一个门外汉,也想搭车问一下,我有一堆数据,我猜应该是非线性关系的,但我不知道是什么样子的非线性关系,不知道应该用什么模型,我该怎么办呢?线性拟合出来的效果极差。

回复 第3楼 的 tjt2008:你这个问题得首先画散点图看是什么形状的,然后根据已知函数图形选择一些模型。我的是生物体生长曲线,S型的,基本上就是Gompertz、Logistic、Bertalanffy这几种。

循环的问题已经解决,非常开心,将代码提供:

<br />
i <- 1<br />
repeat {<br />
  x.inv <- try(nls(mean ~ A*(1 - B*exp(-k*day))^3,<br />
                   start = list(A = i, B = 0.5, k = 0.6), data = mean.w),<br />
               silent = TRUE) #用try()函数,并且设定silent = TRUE,也即追踪但忽略可能的错误。<br />
  if ("try-error" %in% class(x.inv)) { #如果出现错误,那么就将初始参数加1,并进入下一循环,直到得到正确的初始参数<br />
    i <- i + 1<br />
    next<br />
  } else {<br />
    break #得到正确初始参数,也即程序没有检查到错误,那么就结束循环。<br />
  }<br />
}<br />


这样得到的 i 值为58。将58带入初始参数,OK,程序运行成功。感谢循环的“暴力破解”,我刚验证过,57、59都不行,人工试谁会想到58?
<br />
nls.sol <- nls(mean ~ A*(1 - B*exp(-k*day))^3,<br />
               start = list(A = 58, B = 0.5, k = 0.6),<br />
               data = mean.w)<br />
nls.sum <- summary(nls.sol)<br />
nls.sum$parameters<br />


结果:

[data]

Estimate Std. Error t value Pr(>|t|)

A 175.03042385 73.386532191 2.385048 3.617679e-02

B 1.16480280 0.130064900 8.955551 2.200144e-06

k 0.01852205 0.005563022 3.329494 6.717270e-03

[/data][s:11]
</p>

回复 第2楼 的 dugucan:因为忙,很久没上论坛,自我检讨一下。

回复 第3楼 的 tjt2008:个人建议是从专业知识出发寻找突破口。

回复 第5楼 的 dugucan:try() 正适用你所需要的“忽略错误”,但这种尝试方法是不是有点太暴力了?

回复 第4楼 的 dugucan:关键问题是,我想用好几个自变量来拟合一个因变量。。。。

4 个月 后
[未知用户]
这个不妨碍啊。有几个自变量,那就在公式中加入几个自变量,就看你的公式是怎么样的了。我想应该是这样。
1 个月 后
[未知用户]
想请问一下,我现在是在做非线性二元回归。
如果说我想用循环求两个参数的合理值呢,那该怎么编?比如 如果在你的例子里面,想求A和B的合理初始值?
[未知用户]
另外还有个小问题,怎么获取到拟合的决定系数和最小残差平方和之类的检验值? 我用summary没有 用anova,显示:anova is only defined for sequences of "nls" objects 求大神指教~
[未知用户]
第一个问题:模型拟合中合理的参数值并不是唯一的。而是有很多,即便如此,若想一下子找到或猜到还是很困难,所以需要我上面那样的暴力验证。参数值只要是合理的,即只要能够得到结果,那么得到的结果都是一样的。你就按照我上面的方法暴力得到合理的参数值。
第二个问题,你说的那些检验值,我也没有具体试过。我想应该会有一些结果的吧,你可以用str()的命令来看看结果中究竟还有哪些没有显示出来的内容。如果实在没有的话,可以找一本统计书过来编一个计算公式就行,这个应该也不难。
非线性估计需要使用初值的算法,一般是利用迭代,使参数状态从初值向最佳目标状态移动,核心是移动方法(最速下降,牛顿迭代)。
若是如你说的这般复杂(存在多个极值),初值无法确定,需要大量初值实验,并且需求精度不高的初值。建议使用启发式算法,将回归问题效果会好很多,推荐粒子群算法(全局最优无法保证)。该方法可以直接获得结果,或者将结果作为初值,使用传统算法提高精度。