2012-07-05 77 views
4

是否有任何软件包可以使用许多简单模型自动拟合曲线?
通过简单的模型我的意思是:R中的自动曲线拟合

  • 斧+ B
  • 斧^ 2 + BX + C
  • 一个*日志(X)+ B
  • 一个* X^N + B
  • AX /(1 + BX)
  • 斧^ N /(1 + BX^N)
  • ...

最好的方法是创建一个带有两个向量参数X和Y的函数,并返回一个适合他们的SSE的简单模型列表。

+0

目的是什么? – Roland 2012-07-05 19:05:08

+0

@Roland:在线性回归中寻找最佳非线性变换。我喜欢从连续变量中创建一个分类变量(例如十进制),然后查看每个decil中每个decil Vs平均值的参数图。这有助于找到变量的非线性变换。我想加快这一过程。 – 2012-07-05 19:08:02

回答

10

试试这个。 rhs是右侧的字符向量,xy是数据。它为每一个构建公式fo,然后提取参数并将每个参数设置为1作为起始值。最后,它运行nls并返回已排序的SSE,以便结果是通过右侧命名的SSE的向量。如果verbose=TRUE(它是默认值),那么它也会显示每个拟合的输出。

sse <- function(rhs, x, y) sort(sapply(rhs, function(rhs, x, y, verbose = TRUE) { 
    fo <- as.formula(paste("y", rhs, sep = "~")) 
    nms <- setdiff(all.vars(fo), c("x", "y")) 
    start <- as.list(setNames(rep(1, length(nms)), nms)) 
    fm <- nls(fo, data.frame(x, y), start = start) 
    if (verbose) { print(fm); cat("---\n") } 
    deviance(fm) 
}, x = x, y = y)) 

## test 

set.seed(123) 
x <- 1:10 
y <- rnorm(10, x) 

# modify to suit 
rhs <- c("a*x+b", "a*x*x+b*x+c") 

sse(rhs, x, y) 
+0

有趣的结果是,二阶多项式总是适合使用多个常量数据集的前四个模型中的最好的。我认为这是因为rnorm只是伪随机。但是,为什么最好用二次多项式近似,每次都是奇数...... – DWAHL 2012-07-06 00:17:40

+0

三个参数比两个更合适。如果您想惩罚更多参数或使用SSE,但只是比较具有相同参数数量的模型,则可以使用AIC。 – 2012-07-06 00:59:54

+0

感谢您展示如何创建这些功能。我希望它已经存在,因为我可以从头顶考虑30个简单模型,这意味着可能有超过100个这样的模型。 @ G.格洛腾迪克:你认为这样会有更好的结果吗? – 2012-07-06 12:22:19

3

你也可以看看提供函数来评估分数多项式的包。到目前为止,这些似乎是mboost(功能FP)和mfp(功能mfp)。虽然我还没有尝试过这些软件包,但它们背后的理论与你所追求的一致。

mfp包在R-News于2005年

两个引用这可能是感兴趣的是

罗伊斯顿P,奥特曼d(1994)回归使用连续协变量的分数多项式描述。 Appl Stat。 3:429-467。

Sauerbrei W,Royston P(1999)构建多变量预测和诊断模型:使用分数多项式对预测变量进行变换。皇家统计学会杂志(系列A)162:71-94。

+0

谢谢,我从来没有听说过分数多项式。我会定义它的阅读! – 2012-07-06 12:23:19

1

您可以拟合回归样条曲线,并通过几次手动调整自由度来找到合适的曲线。尝试以下功能:

spline.fit <- function(x, y, df=5) { 
    ## INPUT: x, y are two vectors (predictor and response); 
    ##  df is the number of spline basis. Increase "df" to fit more adaptively to the data. 
    require(splines) # available as default R Package. 
    bx <- bs(x, df) # B-spline basis matrix as New Predictors (dimension is "length(x)" by "df") 
    f <- lm(y ~ bx) # Linear Regression on Spline Basis (that is, "df" number of new predictors) 
    fy <- fitted(f) # Fitted Response 
    plot(x, y); lines(x, fy, col="blue", lwd=2) # Make a plot to show the fit. 
    invisible(list(x=bx, y=fy, f=f)) # Return the Basis (new predictors), Fitted Y, Regression 
} 

if (F) {        # Unit Test 
    spline.fit(1:100, rnorm(100)) 
    spline.fit(1:100, rnorm(100), df=20) 
}