2015-12-09 57 views
1

我试图拟合以下函数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) 
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 

有人可以帮我这个函数来设置这些点,即使安装变得坏了,重要的是获得适合这个功能,即她跑在数据

感谢大家

+1

更改'start'值。 –

+0

这有助于解决问题但并不能解决问题:m <-nls(y_exp(loga)*(1 +(x^2)/(b^2))^ t,data = df,start = list loga = 0,b = 0.5,t = 2),trace = TRUE,control = nls.control(maxiter = 10000,minFactor = 1e-8))。 –

+0

尝试将您的函数更改为y =(a + b x^2)^ t。 –

回答

0

因为你的数据是随机变化的,对于某些情况下一个的值接近于零,你的函数变为零。曲线拟合程序在此时失败。随机化启动参数可能适用于某些情况。

稍微更稳定的输出可以使用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)