R 用lm()、nls()和glm()估计马尔萨斯增长模型中的人口增长率

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 )), .

我的问题是关于估计中国的人口增长率。作为一个玩具例子,考虑玩具数据集<代码> 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
)), .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"))