r - 使用 nls 和 nlr 嵌套用户定义函数的非线性回归
问题描述
我一直在尝试使用函数nls
和 软件包执行非线性回归nlr
,gnlm
但我的目标函数有许多可调整的参数,并且通过首先定义一堆不同的方程来更容易定义它。所以,我在链接(https://github.com/Shend92/Nonlinear-regression)和以下方程中得到了数据:
#Import data to data.frame called 'DATA'
#Equations:
ws = function (ap,bp,cp,dp,vel) {
ap*vel+cp*vel^2+dp
}
Fins = function(bs) {
(X1+X5+bs)/(522.64+bs)
}
alp = function(ap,bp,cp,dp,vel,bs) {
Fins(bs)*(ws(ap,bp,cp,dp,vel)-Fins(bs))/ws(ap,bp,cp,dp,vel)^2
}
vel.max = function(ep,fp,bs) {
ep-fp*Fins(bs)
}
del = function(vel,ep,fp,gp,bs) {
vel*(1-(1-vel.max(ep,fp,bs))*exp(-gp*(vel.max(ep,fp,bs)-vel)))
}
Le = function(hp,L,Ld,bs) {
L*(1+hp*Fins(bs)*(1-Fins(bs))*Ld/L)
}
E.s = function(ae,be,ce) {
ae*X1*X2/(100*X1)+be*X1*X3/(100*X1)+ce*(X1*X4)/(100*X1)
}
dens.0 = function(ad,bd,cd){
ad*X1*X2/(100*X1)+bd*X1*X3/(100*X1)+cd*(X1*X4)/(100*X1)
}
Fb = function(lp,Dmill,L) {
lp/(pi*Dmill^2*L)
}
dens.b = 8.05
dens.c = function(bs,ad,bd,cd,ae,be,ce,lp,Dmill,L) {
(Fins(bs)*dens.0(ad,bd,cd)*(1-E.s(ae,be,ce))+Fb(lp,Dmill,L)*
(dens.b-dens.0(ad,bd,cd))*(1-E.s(ae,be,ce)))/Fins(bs)
}
Pmo.s = function(Dmill,vel,Ld,L,ip,jp,kp) {
Dmill^ip*(vel*(jp*Ld+L))^kp
}
##Objective function
Y.s = function(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,ap,bp,
cp,dp,ep,fp,gp,hp) {
Pmo.s(Dmill,vel,Ld,L,ip,jp,kp)+K*Dmill^2.5*Le(hp,L,Ld,bs)*
dens.c(bs,ad,bd,cd,ae,be,ce,lp,Dmill,L)*alp(ap,bp,cp,dp,vel,bs)*
del(vel,ep,fp,gp,bs)
}
一旦定义了我的所有方程(请注意,目标函数Y.s
包含所有其他函数,并且我检查了这个最终方程是否使用一些测试参数正确运行)我尝试运行以下代码以适应所有可调整参数(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,ap,bp,cp,dp,ep,fp,gp,hp)
nlr.test1 <- nls(Y ~ Y.s(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,
ap,bp,cp,dp,ep,fp,gp,hp),
start=list(Dmill = 3.526,ap = 2.000,bp = 2.900,cp = -2.200,
dp = -0.500,ep = 0.900,fp = -0.135,gp = -19.420,
hp = 12.280,ip = 2.500,jp = 0.600,kp = 0.8,K = 2.000,
vel = 0.700,bs = 0.187,L = 15.000,Ld = 3.000,ae = 0.307,
be = 0.174,ce = 0.279,ad = 3.200,bd = 2.700,
cd = 2.749,lp=430),
algorithm = "port", ,lower=list(ap = 0,bp = 0,cp = -5,dp = -2,ep = 0,
fp = -5,gp = -100,hp = 0,ip = 0,jp = 0,kp = 0,K = 0,
Dmill = 1,vel = 0,bs = 0,L = 8,Ld = 0,ae = 0,be = 0,
ce = 0,ad = 0,bd = 0,cd = 0,lp=0), upper=list(ap = 5,
bp = 5,cp = -1,dp = 0,ep = 2,fp = 0,gp = 0,hp = 20,ip = 5,
jp = 1,kp = 2,K = 5,Dmill = 5,vel = 2,bs = 5,L = 20,
Ld = 8,ae = 1,be = 1,ce = 1,ad = 5,bd = 4,cd = 4,lp=1000),
data=DATA)
运行此代码会给出以下错误消息
Error in nlsModel(formula, mf, start, wts, upper) : singular gradient matrix at initial parameter estimates
据我了解,这个错误是说初始值不好,但我认为不是真的,因为初始值似乎给出了接近 Y 实际值的 Ys 值。所以我尝试了一个不同的功能:
nlr(Y,mu=Y.s(K,Dmill,vel,Ld,L,ip,jp,kp,bs,ad,bd,cd,ae,be,ce,lp,
ap,bp,cp,dp,ep,fp,gp,hp),
pmu=list(Dmill = 3.526,ap = 2.000,bp = 2.900,cp = -2.200,
dp = -0.500,ep = 0.900,fp = -0.135,gp = -19.420,
hp = 12.280,ip = 2.500,jp = 0.600,kp = 0.8,K = 2.000,
vel = 0.700,bs = 0.187,L = 15.000,Ld = 3.000,ae = 0.307,
be = 0.174,ce = 0.279,ad = 3.200,bd = 2.700,
cd = 2.749,lp=430))
运行此代码会给出以下错误消息:
Error in Pmo.s(Dmill, vel, Ld, L, ip, jp, kp) : object 'Dmill' not found
现在在这里我不确定发生了什么,因为正如我之前所说,我通过为所有参数提供测试值来检查函数是否正确定义。
我知道这个问题有点难以理解,因为它有很多参数和方程,但如果有人至少可以帮助我解释为什么nlr
给我在主目录中找不到定义的对象的错误,我将不胜感激功能。或者,如果有更好的函数来解决非线性回归问题。
非常感谢您!
苏菲亚
解决方案
推荐阅读
- terraform - 具有嵌套列表的 Terraform 动态块
- javascript - 反向位 JavaScript
- c# - 如何在每个数据集之后使用换行符将多个 CSV 文件合并为一个
- python - 立即收取订阅升级费用,但不收取降级费用或退款
- python - 数组在 PyYAML 中没有缩进或空格
- ios - 在 Xcode 中将构建系统更改为“新构建系统”后出现 ITMS-90035 错误
- ios - 如何根据另一个pickervew更改pickerview中的选择?
- python - 如何使用python将文件夹中的所有文件复制到一个文件到另一个文件夹?
- pointers - 访问函数类型 void 中的结构
- java - 空指针异常宁静行为根包