R 用lm()、nls()和glm()估计马尔萨斯增长模型中的人口增长率
我的问题是关于估计中国的人口增长率。作为一个玩具例子,考虑玩具数据集<代码> df>代码>:R 用lm()、nls()和glm()估计马尔萨斯增长模型中的人口增长率,r,regression,glm,lm,nls,R,Regression,Glm,Lm,Nls,我的问题是关于估计中国的人口增长率。作为一个玩具例子,考虑玩具数据集 df>代码>: structure(list(x= c(0L, 24L, 48L, 72L, 96L, 120L, 144L, 168L ), y = c(10000, 18744.0760659189, 35134.0387564953, 65855.509495469, 123440.067934292, 231377.002294256, 433694.813090781, 812920.856596808 )), .
structure(list(x= c(0L, 24L, 48L, 72L, 96L, 120L, 144L, 168L
), y = c(10000, 18744.0760659189, 35134.0387564953, 65855.509495469,
123440.067934292, 231377.002294256, 433694.813090781, 812920.856596808
)), .Names = c("x", "y"), row.names = c(NA, -8L), class = "data.frame")
我试图通过指数模型来拟合此数据集:
y = 10000 * (e^(r * x))
并估算r
。使用非线性回归时nls()
:
我还尝试了lm()
我怎样才能解决这个问题?如何将数据拟合到我拥有的指数模型
还可以考虑其他的方法来拟合人口增长模型吗?glm()
合理吗?使用lm()
请阅读?公式
,了解公式的正确规格。现在,假设你已经读过了,我将继续
首先,在LHS和RHS上进行log
变换后,您的模型将变为:
log(y) = log(10000) + r * x
该常数是一个已知值,不可估计。这种常数在lm
中称为offset
您应该使用lm
,如下所示:
# "-1" in the formula will drop intercept
fit <- lm(log(y) ~ x - 1, data = df, offset = rep(log(10000), nrow(df)))
# Call:
# lm(formula = log(y) ~ x - 1, data = df, offset = rep(log(10000), nrow(df)))
# Coefficients:
# x
# 0.02618
请注意我使用的exp(fit$fitted)
,因为我们为log(y)
安装了一个模型,现在我们要回到原始比例
备注
正如@BenBolker所说,更简单的规范是:
fit <- lm(log(y/10000) ~ x - 1, data = df)
使用
nls()
使用nls()
的正确方法如下:
nls(y ~ 10000 * exp(r * x), data = df, start = list(r = 0.1))
因为非线性曲线拟合需要迭代,所以需要一个起始值,必须通过参数start
提供
现在,如果您尝试此代码,您将获得:
Error in nls(y ~ 10000 * exp(r * x), data = df, start = list(r = 0.1)) :
number of iterations exceeded maximum of 50
问题在于你的数据是准确的,没有噪音。阅读?nls
:
fit <- nls(y ~ (10000 * exp(r*x)), data=df)
Warning:
*Do not use ‘nls’ on artificial "zero-residual" data.*
因此,对玩具数据集df
使用nls()
让我们从lm()
返回检查已安装的型号:
残差基本上到处都是0,在这种情况下,lm()
非常适合
跟进
最后一件我还没有弄清楚的事情是为什么参数r
没有在lm
的公式规范中使用
实际上,lm
和nls
之间的公式有些不同。也许你可以这样认为:
lm()
的公式称为模型公式,您可以从公式
中读取该公式。它在R中非常重要。模型拟合例程使用它,如lm
,glm
,而许多函数都有公式方法,如Model.matrix
,aggregate
,boxplot
,等等
nls()
的公式更像是一个函数规范,实际上并没有广泛使用。许多其他执行非线性迭代的函数,如optim
将不接受公式,而是直接接受函数。因此,只需将nls()
视为一个特例即可
那么,使用线性模型做这件事有意义吗?简单地说,我在这里试图建模的是马尔萨斯增长模型
严格地说,给出真实人口数据(当然有噪声),使用nls()
进行曲线拟合,或使用glm(,family=poisson)
进行泊松响应glm比拟合线性模型有更好的基础。对数据的glm()
调用将是:
glm(y ~ x - 1, family = poisson(), data = df, offset = rep(log(10000), nrow(df)))
(您可能需要先了解GLM是什么。)但由于您的数据没有噪声,因此在使用它时会收到警告消息
然而,就计算复杂度而言,通过首先进行log
变换来使用线性模型显然是一种成功。在统计建模中,变量转换非常常见,因此没有令人信服的理由拒绝使用线性模型估计人口增长率
作为一个完整的图片,我建议您尝试这三种方法来获取真实数据(或嘈杂的玩具数据)。估计和预测会有一些差异,但不太可能很大
“后续跟进”
哈哈,再次感谢@Ben。对于glm()
,我们还可以尝试:
glm(y ~ x - 1 + offset(log(10000)), family = gaussian(link="log"))
对于offset
规范,我们可以在lm
/glm
中使用offset
参数,或者像Ben一样使用offset()
函数。对于线性模型,您甚至不需要偏移:log(y)-log(10000)~x-1
应该可以工作(尽管偏移可能更清晰)谢谢你的帮助!但是,我无法输入log(y)=log(10000)+r*x,因为它显示找不到函数“logI实际上有点困惑,但现在读到关于截取的内容,我理解得更清楚了,有一点仍然存在问题,那就是为什么lm会得到13个。但是在这种情况下,我不能使用lm的拟合来绘制图!我正在使用plot(df)
然后使用行(x,fit)
fit
基本上是lm(log(y)~x-1,data=df,offset=rep(log(10000),nrow(df))
。非常感谢。它现在为我清理了一切。最后一件我还没有弄清楚的事情是为什么参数r
没有在lm
中使用,我特别质疑这一点,因为在我所做的r
是我的模型在生物信息学任务中的增长率,所以它非常重要。glm(y~x-1+偏移量(log(10000)),family=gaussian(link=“log”))
是另一种可能性
lines(df$x, 10000 * exp(fit$fitted), col = 2, lwd = 2)
nls(y ~ 10000 * exp(r * x), data = df, start = list(r = 0.1))
Error in nls(y ~ 10000 * exp(r * x), data = df, start = list(r = 0.1)) :
number of iterations exceeded maximum of 50
Warning:
*Do not use ‘nls’ on artificial "zero-residual" data.*
fit$residuals
# 1 2 3 4 5
#-2.793991e-16 -1.145239e-16 -2.005405e-15 -5.498411e-16 3.094618e-15
# 6 7 8
# 1.410007e-15 -1.099682e-15 -1.007937e-15
glm(y ~ x - 1, family = poisson(), data = df, offset = rep(log(10000), nrow(df)))
glm(y ~ x - 1 + offset(log(10000)), family = gaussian(link="log"))