R中非线性Langmuir等温线的拟合
我想为R中的以下数据拟合等温线模型。最简单的等温线模型是这里给出的Langmuir模型。下面给出了我的MWE,它抛出了错误。我想知道是否有等温线模型的R包R中非线性Langmuir等温线的拟合,r,nonlinear-functions,nls,non-linear-regression,R,Nonlinear Functions,Nls,Non Linear Regression,我想为R中的以下数据拟合等温线模型。最简单的等温线模型是这里给出的Langmuir模型。下面给出了我的MWE,它抛出了错误。我想知道是否有等温线模型的R包 X <- c(10, 30, 50, 70, 100, 125) Y <- c(155, 250, 270, 330, 320, 323) Data <- data.frame(X, Y) LangIMfm2 <- nls(formula = Y ~ Q*b*X/(1+b*X), data = Data, start
X <- c(10, 30, 50, 70, 100, 125)
Y <- c(155, 250, 270, 330, 320, 323)
Data <- data.frame(X, Y)
LangIMfm2 <- nls(formula = Y ~ Q*b*X/(1+b*X), data = Data, start = list(Q = 1, b = 0.5), algorith = "port")
Error in nls(formula = Y ~ Q * b * X/(1 + b * X), data = Data, start = list(Q = 1, :
Convergence failure: singular convergence (7)
X我不知道有这样的软件包,我个人认为你不需要,因为这个问题可以用基本的R解决
nls
对起始参数很敏感,因此您应该从一个好的起始猜测开始。您可以很容易地计算Q
,因为它对应于x-->Inf处等温线的渐近极限,因此从Q=323
开始是合理的(这是样本数据集中Y
的最后一个值)
接下来,您可以进行绘图(数据)
并添加一条等温线,该等温线对应于您的起始参数Q
和b
,并调整b
,以得出合理的猜测
下图显示了数据集(点)和由生成的Q=323和b=0.5的探针等温线(数据,行(X,323*0.5*X/(1+0.5*X),列为红色)
(红线)。对我来说,这似乎是一个合理的开始猜测,我用nls
尝试了一下:
LangIMfm2 <- nls(formula = Y ~ Q*b*X/(1+b*X), data = Data, start = list(Q = 300, b = 1), algorith = "port")
# Nonlinear regression model
# model: Y ~ Q * b * X/(1 + b * X)
# data: Data
# Q b
# 366.2778 0.0721
# residual sum-of-squares: 920.6
#
# Algorithm "port", convergence message: relative convergence (4)
话虽如此,我建议使用更有效的策略,通过在倒数坐标中重写等温线方程,基于模型的线性化:
z <- 1/Data
plot(Y~X,z)
abline(lm(Y~X,z))
M <- lm(Y~X,z)
Q <- 1/coef(M)[1]
# 363.2488
b <- coef(M)[1]/coef(M)[2]
# 0.0741759
z您可以在nlme软件包中使用R的SSmicmen自启动函数(见Ritz and Streibig,2008,R非线性回归),该函数通过拟合Michaelis-Menten(MM)方程的线性化形式计算初始参数。幸运的是,MM方程具有一种可适用于朗缪尔方程的形式,S=Smax*x/(KL+x)。我发现nlshelper和tidyverse软件包对于建模和将nls命令的结果导出到表格和绘图中非常有用,尤其是在建模样本组时。以下是我为一组吸附数据建模的代码:
library(tidyverse)
library(nlme)
library(nlshelper)
lang.fit问题在于起始值。我们展示了两种方法,以及一种即使使用问题中的起始值也会收敛的替代方法
1)plinear右侧在Q*b中是线性的,因此最好将b吸收到Q中,然后我们有一个参数,该参数以线性形式输入,因此更容易求解。同样,对于plinear算法,线性参数不需要起始值,因此只需指定b的起始值。对于plinear,nls公式的右侧应指定为乘以线性参数的向量。运行nls的结果,给出下面的fm0
将是名为b
和.lin
的系数,其中Q=.lin/b
我们已经从fm0
中得到了答案,但是如果我们想要以b
和Q
而不是b
和的形式进行干净的运行,我们可以使用fm0
返回的系数所隐含的起始值运行问题中的原始公式,如图所示
fm0 <- nls(Y ~ X/(1+b*X), Data, start = list(b = 0.5), alg = "plinear")
st <- with(as.list(coef(fm0)), list(b = b, Q = .lin/b))
fm <- nls(Y ~ Q*b*X/(1+b*X), Data, start = st)
fm
我们可以显示结果。这些点是数据,红线是拟合曲线
plot(Data)
lines(fitted(fm) ~ X, Data, col = "red")
(地块后续)
2)平均值或者,对Q使用平均值的起始值(数据$Y)似乎效果良好
nls(Y ~ Q*b*X/(1+b*X), Data, start = list(b = 0.5, Q = mean(Data$Y)))
给予:
Nonlinear regression model
model: Y ~ Q * b * X/(1 + b * X)
data: Data
b Q
0.0721 366.2779
residual sum-of-squares: 920.6
Number of iterations to convergence: 6
Achieved convergence tolerance: 5.818e-06
$par
[1] 366.27028219 0.07213613
$value
[1] 920.62
$counts
function gradient
249 NA
$convergence
[1] 0
$message
NULL
这个问题已经有了我们使用的合理的b
起始值,但是如果需要的话,可以将Y
设置为Q*b
,这样它们就可以取消,并X
取平均值(数据$X),然后求解b
得到b=1-1/平均值(数据$X)
。虽然未显示使用b
的该起始值和平均值(数据$Y)
作为Q
的起始值也会导致收敛
3)optim如果我们使用optim
算法收敛,甚至与问题中使用的初始值一致。我们形成残差平方和,并最小化:
rss <- function(p) {
Q <- p[1]
b <- p[2]
with(Data, sum((Y - b*Q*X/(1+b*X))^2))
}
optim(c(1, 0.5), rss)
只需尝试不同的启动参数,例如start=list(Q=300,b=1)
谢谢@MaratTalipov提供的有用意见。你知道有没有适合等温线模型的R软件包吗?谢谢@Marat的回答。我认为Lanmuir等温线模型的线性版本和非线性版本有很大的不同,特别是在估计的标准误差方面。一些非线性模型可以转换为线性模型。我的理解是,非线性模型的估计与其线性模型形式之间可能存在一对一的关系,但它们相应的标准误差彼此不相关。这个断言是真的吗?通过转换为线性来拟合非线性模型是否存在缺陷?提前感谢你的帮助。
plot(Data)
lines(fitted(fm) ~ X, Data, col = "red")
nls(Y ~ Q*b*X/(1+b*X), Data, start = list(b = 0.5, Q = mean(Data$Y)))
Nonlinear regression model
model: Y ~ Q * b * X/(1 + b * X)
data: Data
b Q
0.0721 366.2779
residual sum-of-squares: 920.6
Number of iterations to convergence: 6
Achieved convergence tolerance: 5.818e-06
rss <- function(p) {
Q <- p[1]
b <- p[2]
with(Data, sum((Y - b*Q*X/(1+b*X))^2))
}
optim(c(1, 0.5), rss)
$par
[1] 366.27028219 0.07213613
$value
[1] 920.62
$counts
function gradient
249 NA
$convergence
[1] 0
$message
NULL