如何使用nls()拟合指数衰减模型中的多个常数? [英] How to use nls() to fit multiple constants in exponential decay model?

查看:203
本文介绍了如何使用nls()拟合指数衰减模型中的多个常数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理这种关系:

y = h * R + x * v * h

y = h * R + x * v * h

其中:

x =(N-M)* exp(-Q * u)+ M

x = (N - M) * exp(-Q * u) + M

给出主方程:

y = h * R + v * h *(N-M)* exp(-Q * u)+ v * h * M

y = h * R + v * h * (N - M) * exp(-Q * u) + v * h * M

所有大写字母都是常量,所有小写字母都是变量.

All uppercase letters are constants, and all lowercase letters are variables.

我拥有所有变量的真实数据,但是我要么不知道常数(R和Q)的值,要么想检查数据适合常数(N和M)值的能力.我想使用nls()来使用变量数据拟合方程,以估计这些常数参数.

I have real data for all the variables, but I either do not know the values of the constants (R and Q), or want to check the ability of the data to fit the values of the constants (N and M). I want to use nls() to fit the equation using the data for the variables, to estimate these constant parameters.

我该如何使用nls()函数编写代码来描述主方程式,以允许从模拟测量数据中估计参数R,N,Q和M? (模拟测量数据=带_j后缀的小写字母,请参见下文.)

How do I write code using the nls() function to depict the principal equation, to allow estimation of the parameters R, N, Q, and M from the mock measurement data? (Mock measurement data = lower cases letters with _j suffix, see below.)

要创建模拟数据:

library(dplyr)
library(ggplot2)

### Generate mock data

# Equations:
# y = h*R + x*v*h
# x = (N-M)*exp(-Q*u) + M
# y = h*R + ((N-M)*exp(-Q*u) + M)*v*h
# y = h*R + v*h*(N-M)*exp(-Q*u) + v*h*M

### Variables have varying periodicity,
# and so can be approximated via different functions,
# with unique noise added to each to simulate variability:

# Variability for each variable
n <- 1000 # number of data points
t <- seq(0,4*pi,length.out = 1000)
a <- 3
b <- 2

y.norm <- rnorm(n)
u.norm <- rnorm(n)
u.unif <- runif(n)
v.norm <- rnorm(n)
v.unif <- runif(n)
amp <- 1

# Create reasonable values of mock variable data for all variables except h;
# I will calculate from known fixed values for R, N, Q, and M.

y <- 1.5*a*sin(b*t)+y.norm*amp-10 # Gaussian/normal error
u <- ((1*a*sin(11*b*t)+u.norm*amp)+(0.5*a*sin(13*b*t)+u.unif*amp)+7)/2
v <- 1/((2*a*sin(11*b*t)+v.norm*amp)+(1*a*sin(13*b*t)+v.unif*amp)+20)*800-25

# Put vectors in dataframe
dat <- data.frame("t" = t, "y" = y, "u" = u, "v" = v)

### Create reasonable values for constants:

R=0.5
N=1.12
Q=0.8
M=1

### Define final variable based on these constants and the previous
# mock variable data:

dat$h = y/(R + v*(N-M)*exp(-Q*dat$u))

### Gather data to plot relationships:

dat_gathered <- dat %>%
  gather(-t, value = "value", key = "key")

### Plot data to check all mock variables:

ggplot(dat_gathered, aes(x = t, y = value, color = key)) + geom_line()

# Add small error (to simulate measurement error):

dat <- dat %>%
  mutate(h_j = h + rnorm(h, sd=0.05)/(1/h)) %>%
  mutate(u_j = u + rnorm(u, sd=0.05)/(1/u)) %>%
  mutate(v_j = v + rnorm(v, sd=0.05)/(1/v)) %>%
  mutate(y_j = y + rnorm(y, sd=0.05)/(1/y))

推荐答案

nls似乎可以正常工作,但看起来解决方案(就参数而言)不是唯一的……或者我在某个地方犯了错误

nls appears to work OK, but it looks like the solution (in terms of parameters) is non-unique ... or I made a mistake somewhere.

## parameter values chosen haphazardly
n1 <- nls(y ~ h_j*(R + v_j*((N-M)*exp(-Q*u_j)+M)),
    start=list(R=1,N=2,M=1,Q=1),
    data=dat)

## starting from known true values
true_vals <- c(R=0.5,N=1.12,Q=0.8,M=1)
n2 <- update(n1, start=as.list(true_vals))

round(cbind(coef(n1),coef(n2),true_vals),3)
              true_vals
R 0.495 0.495      0.50
N 0.120 0.120      1.12
M 0.001 0.818      0.80
Q 0.818 0.001      1.00

在两个拟合中使用AIC()表示它们具有基本相同的拟合优度(且预测几乎相同),这表明模型中存在一些对称性,允许MQ互换.我还没有足够认真地考虑/研究方程式,以至于不知道为什么会这样.

Using AIC() on the two fits shows they have essentially equivalent goodness of fits (and the predictions are almost identical), which suggests that there's some symmetry in your model that allows M and Q to be interchanged. I haven't thought about/looked at the equation hard enough to know why this would be the case.

这篇关于如何使用nls()拟合指数衰减模型中的多个常数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆