R 给定数据集的拟合函数
我试图将下面的函数y(x)=a*(1+(x^2)/(b^2))^t拟合到一组特定的数据,其中,a、b和t是要通过拟合确定的常数 例如,我尝试以下方法R 给定数据集的拟合函数,r,curve-fitting,data-fitting,R,Curve Fitting,Data Fitting,我试图将下面的函数y(x)=a*(1+(x^2)/(b^2))^t拟合到一组特定的数据,其中,a、b和t是要通过拟合确定的常数 例如,我尝试以下方法 len <- 24 x = runif(len) y = x^3 + runif(len, min = -0.1, max = 0.1) plot(x, y) s <- seq(from = 0, to = 1, length = 50) lines(s, s^3, lty = 2) df <- data.frame(x, y)
len <- 24
x = runif(len)
y = x^3 + runif(len, min = -0.1, max = 0.1)
plot(x, y)
s <- seq(from = 0, to = 1, length = 50)
lines(s, s^3, lty = 2)
df <- data.frame(x, y)
m <- nls(y~a*( 1 + (x^2)/(b^2) )^t, data = df, start = list(a=1,t=0, b=1), trace = T)
> Error in nlsModel(formula, mf, start, wts) :
singular gradient matrix at initial parameter estimates
len因为数据是随机变化的,所以在某些情况下,a的值接近于零,函数变为零。曲线拟合过程在该点失败。随机化开始参数可能适用于某些情况
可以使用LM算法计算稍微更稳定的输出:
require("minpack.lm")
LMCurveFit <- function(df) {
# The function to be fit
FitFunction <- function(params, x) {
with (
as.list(params), {
a*(1 + x^2/b^2)^t
}
)
}
# Residual
Residual <- function(params, x, y) {
FitFunction(params, x) - y
}
# Sum of squares of residuals
ssqfun <- function(params, x, y) {
sum(Residual(params, x, y)^2)
}
# Normalize the data
x_max = max(x)
y_max = max(y)
df$x = df$x/x_max
df$y = df$y/y_max
# Define start parameters
a_start = 0.1
b_start = 1.0
t_start = 1.0
param_start = c(a = a_start,
b = b_start,
t = t_start)
# Do LM fit
nls.out <- nls.lm(par = param_start,
fn = Residual,
control = nls.lm.control(nprint=0,
ftol=.Machine$double.eps,
ptol=.Machine$double.eps,
maxfev=10000, maxiter=1024),
x = df$x,
y = df$y)
# Revert scaling
nls.out$par[1] = nls.out$par[1]*y_max
nls.out$par[2] = nls.out$par[2]*x_max
# Get the parameters
params_fit = coef(nls.out)
print(params_fit)
# Compute predicted values
predicted = FitFunction(as.list(params_fit), df$x*x_max)
}
# LM fit
pred_y = LMCurveFit(df)
lines(x, pred_y)
require(“minpack.lm”)
LMCurveFit因为数据是随机变化的,所以在某些情况下,a的值接近于零,函数变为零。曲线拟合过程在该点失败。随机化开始参数可能适用于某些情况
可以使用LM算法计算稍微更稳定的输出:
require("minpack.lm")
LMCurveFit <- function(df) {
# The function to be fit
FitFunction <- function(params, x) {
with (
as.list(params), {
a*(1 + x^2/b^2)^t
}
)
}
# Residual
Residual <- function(params, x, y) {
FitFunction(params, x) - y
}
# Sum of squares of residuals
ssqfun <- function(params, x, y) {
sum(Residual(params, x, y)^2)
}
# Normalize the data
x_max = max(x)
y_max = max(y)
df$x = df$x/x_max
df$y = df$y/y_max
# Define start parameters
a_start = 0.1
b_start = 1.0
t_start = 1.0
param_start = c(a = a_start,
b = b_start,
t = t_start)
# Do LM fit
nls.out <- nls.lm(par = param_start,
fn = Residual,
control = nls.lm.control(nprint=0,
ftol=.Machine$double.eps,
ptol=.Machine$double.eps,
maxfev=10000, maxiter=1024),
x = df$x,
y = df$y)
# Revert scaling
nls.out$par[1] = nls.out$par[1]*y_max
nls.out$par[2] = nls.out$par[2]*x_max
# Get the parameters
params_fit = coef(nls.out)
print(params_fit)
# Compute predicted values
predicted = FitFunction(as.list(params_fit), df$x*x_max)
}
# LM fit
pred_y = LMCurveFit(df)
lines(x, pred_y)
require(“minpack.lm”)
LMCurveFit更改start
值。这有助于解决问题:m尝试将函数更改为y=(a+b x^2)^t。更改start
值。这有助于解决问题:m尝试将函数更改为y=(a+b x^2)^t。