简体   繁体   English

评估(即预测)R 外的平滑样条

[英]evaluate (i.e., predict) a smoothing spline outside R

I fitted a smoothing spline to data in R with我为 R 中的数据拟合了一个平滑样条

library(splines)
Model <- smooth.spline(x, y, df =6) 

I would like to take the fitted spline and evaluate it for arbitrary new data in an external code (not in R).我想采用拟合的样条并在外部代码(不是在 R 中)中评估它的任意新数据。 In other words, do what the predict.smooth.spline function does.换句话说,做predict.smooth.spline函数所做的事情。 I had a look at the Model object:我看了一下Model对象:

> str(Total_work_model)
List of 15
 $ x       : num [1:14] 0.0127 0.0186 0.0275 0.0343 0.0455 ...
 $ y       : num [1:14] 3174 3049 2887 2862 2975 ...
 $ w       : num [1:14] 1 1 1 1 1 1 1 1 1 1 ...
 $ yin     : num [1:14] 3173 3075 2857 2844 2984 ...
 $ data    :List of 3
  ..$ x: num [1:14] 0.0343 0.0455 0.0576 0.0697 0.0798 ...
  ..$ y: num [1:14] 2844 2984 3048 2805 2490 ...
  ..$ w: num [1:14] 1 1 1 1 1 1 1 1 1 1 ...
 $ lev     : num [1:14] 0.819 0.515 0.542 0.568 0.683 ...
 $ cv.crit : num 6494075
 $ pen.crit: num 3260
 $ crit    : num 3
 $ df      : num 8
 $ spar    : num 0.353
 $ lambda  : num 8.26e-05
 $ iparms  : Named int [1:3] 3 0 10
  ..- attr(*, "names")= chr [1:3] "icrit" "ispar" "iter"
 $ fit     :List of 5
  ..$ knot : num [1:20] 0 0 0 0 0.056 ...
  ..$ nk   : int 16
  ..$ min  : num 0.0127
  ..$ range: num 0.104
  ..$ coef : num [1:16] 3174 3132 3027 2871 2842 ...
  ..- attr(*, "class")= chr "smooth.spline.fit"
 $ call    : language smooth.spline(x = Phi00, y = Total, df = 8)
 - attr(*, "class")= chr "smooth.spline"

I think the Model$fit$knot and Model$fit$coef vectors contain the full description of the fit.我认为Model$fit$knotModel$fit$coef向量包含Model$fit$coef的完整描述。 Note that the knots are 20, while x and y have 14 elements each: I always thought a smoothing spline would have as many knots as fitting points.请注意,节点数为 20,而xy各有 14 个元素:我一直认为平滑样条曲线的节点数与拟合点数一样多。 However, since the first three and the last three knots are identical, 20-6 = 14 which makes sense.然而,由于前三个和最后三个结是相同的,20-6 = 14 这是有道理的。 The problem is that I don't know how to use Model$fit$knot and Model$fit$coef to make predictions outside R. I tried to have a look at predict.smooth.spline , but surprisingly that's what I get问题是我不知道如何使用Model$fit$knotModel$fit$coef在 R 之外进行预测。我试图看看predict.smooth.spline ,但令人惊讶的是我得到的

> library(splines)
> predict.smooth.spline
Error: object 'predict.smooth.spline' not found

EDIT: since apparently some users misunderstood the question, I know how to use predict in R, to get new values of my smoothing spline.编辑:由于显然有些用户误解了这个问题,我知道如何在 R 中使用predict来获得我的平滑样条的新值。 The problem is that I want to make those predictions in an external code.问题是我想在外部代码中做出这些预测。 Thus I wanted to have a look at the code for the function predict.smooth.spline , so that I could try to reproduce the algorithm outside R. Usually in R you can read the code of a function just by entering its name (without arguments and without parentheses) at the R prompt.因此,我想查看函数predict.smooth.spline的代码,以便我可以尝试在 R 之外重现该算法。通常在 R 中,您只需输入函数名称(不带参数)即可读取函数的代码并且没有括号)在 R 提示符下。 But when I try to do that with predict.smooth.spline , I get the above error.但是,当我尝试使用predict.smooth.spline执行此操作时,出现上述错误。

EDIT2: thanks to the great help from @r2evans, I found the source for the predict method of smooth.spline . EDIT2:感谢@r2evans 的大力帮助,我找到了smooth.splinepredict方法的smooth.spline I (think I) understand most of it:我(认为我)理解其中的大部分内容:

> stats:::predict.smooth.spline.fit
function (object, x, deriv = 0, ...) 
{
    if (missing(x)) 
        x <- seq.int(from = object$min, to = object$min + object$range, 
            length.out = length(object$coef) - 4L)
    xs <- (x - object$min)/object$range
    extrap.left <- xs < 0
    extrap.right <- xs > 1
    interp <- !(extrap <- extrap.left | extrap.right)
    n <- sum(interp)
    y <- xs
    if (any(interp)) 
        y[interp] <- .Fortran(C_bvalus, n = as.integer(n), knot = as.double(object$knot), 
            coef = as.double(object$coef), nk = as.integer(object$nk), 
            x = as.double(xs[interp]), s = double(n), order = as.integer(deriv))$s
    if (any(extrap)) {
        xrange <- c(object$min, object$min + object$range)
        if (deriv == 0) {
            end.object <- Recall(object, xrange)$y
            end.slopes <- Recall(object, xrange, 1)$y * object$range
            if (any(extrap.left)) 
                y[extrap.left] <- end.object[1L] + end.slopes[1L] * 
                  (xs[extrap.left] - 0)
            if (any(extrap.right)) 
                y[extrap.right] <- end.object[2L] + end.slopes[2L] * 
                  (xs[extrap.right] - 1)
        }
        else if (deriv == 1) {
            end.slopes <- Recall(object, xrange, 1)$y * object$range
            y[extrap.left] <- end.slopes[1L]
            y[extrap.right] <- end.slopes[2L]
        }
        else y[extrap] <- 0
    }
    if (deriv > 0) 
        y <- y/(object$range^deriv)
    list(x = x, y = y)
}

However, I have two difficulties:但是,我有两个困难:

  1. the .Fortran() function calls a Fortran subroutine bvalus whose source is quite simple. .Fortran()函数调用非常简单的 Fortran 子程序bvalus However, bvalus in turn calls bvalue which is much more complicated , and calls interv whose source I cannot find.然而, bvalus依次调用bvalue这是更为复杂,并要求interv其源我找不到。 Bad news: bvalue is way too complicated for me to understand (I'm definitely not a Fortran expert).坏消息: bvalue太复杂了,我无法理解(我绝对不是 Fortran 专家)。 Good news: the external code which must reproduce predict.smooth.spline.fit is also a Fortran code.好消息:必须重现predict.smooth.spline.fit的外部代码也是 Fortran 代码。 If worse comes to worst, I could just ask my coworker to include the source from bvalus and bvalue in his code.如果更糟,我可以让我的同事在他的代码中包含bvalusbvalue的源代码。 However, even in this admittedly not so nice scenario, I would still miss the source code for interv (I hope it doesn't call something else!!!).然而,即使在这个公认的不太好的场景中,我仍然会错过interv的源代码(我希望它不会调用其他东西!!!)。

  2. I don't understand what it's being done here (note I'm only interested in the deriv == 0 case):我不明白这里做了什么(注意我只对deriv == 0情况感兴趣):

k

  if (any(extrap)) {
        xrange <- c(object$min, object$min + object$range)
        if (deriv == 0) {
            end.object <- Recall(object, xrange)$y
            end.slopes <- Recall(object, xrange, 1)$y * object$range
            if (any(extrap.left)) 
                y[extrap.left] <- end.object[1L] + end.slopes[1L] * 
                  (xs[extrap.left] - 0)
            if (any(extrap.right)) 
                y[extrap.right] <- end.object[2L] + end.slopes[2L] * 
                  (xs[extrap.right] - 1)
        }

Some sort of recursive code?某种递归代码? Any help here?这里有什么帮助吗?

smooth.spline is not in the splines package, it's in stats . smooth.spline不在splines包中,它在stats Additionally, it's not exported, so you have to use the triple-colon method to see it: stats:::predict.smooth.spline .此外,它不会被导出,因此您必须使用三冒号方法来查看它: stats:::predict.smooth.spline It then points you to predict.smooth.spline.fit , which can be found in a similar manner.然后它会指向predict.smooth.spline.fit ,它可以以类似的方式找到。 (Since it optionally uses .Fortran() , you may have to infer what is going on ... unless you dive into the source .) (因为它可选地使用.Fortran() ,你可能必须推断发生了什么......除非你深入研究源代码。)

Exporting a smoothing spline as piecewise polynomials is one way to reconstruct the spline outside R. My package SplinesUtils : https://github.com/ZheyuanLi/SplinesUtils can do this.将平滑样条导出为分段多项式是在 R 之外重建样条的一种方法。我的包SplinesUtilshttps : //github.com/ZheyuanLi/SplinesUtils可以做到这一点。 You can get it by你可以通过

devtools::install_github("ZheyuanLi/SplinesUtils")

The function to be used here is SmoothSplinesAsPiecePoly .此处使用的函数是SmoothSplinesAsPiecePoly I am just copying in examples for this function in its documentation.我只是在其文档中复制此函数的示例。

library(SplinesUtils)

## a toy dataset
set.seed(0)
x <- 1:100 + runif(100, -0.1, 0.1)
y <- poly(x, 9) %*% rnorm(9)
y <- y + rnorm(length(y), 0, 0.2 * sd(y))

## fit a smoothing spline
sm <- smooth.spline(x, y)

## coerce "smooth.spline" object to "PiecePoly" object
oo <- SmoothSplineAsPiecePoly(sm)

## print the "PiecePoly"
oo
#61 piecewise polynomials of degree 3 are constructed!
#Use 'summary' to export all of them.
#The first 6 are printed below.
#-0.626 - 0.17 * (x - 1.08) - 0 * (x - 1.08) ^ 2 - 0.0094 * (x - 1.08) ^ 3
#-0.768 - 0.148 * (x - 1.95) - 0.0246 * (x - 1.95) ^ 2 - 0.00569 * (x - 1.95) ^ 3
#-0.919 + 0.0259 * (x - 4.01) + 0.0598 * (x - 4.01) ^ 2 + 0.0086 * (x - 4.01) ^ 3
#-0.834 + 0.124 * (x - 5.08) + 0.0323 * (x - 5.08) ^ 2 + 0.00466 * (x - 5.08) ^ 3
#-0.494 + 0.197 * (x - 7.08) + 0.00433 * (x - 7.08) ^ 2 + 0.0027 * (x - 7.08) ^ 3
#-0.113 + 0.183 * (x - 9.03) + 0.0115 * (x - 9.03) ^ 2 + 0.00377 * (x - 9.03) ^ 3

The knots of the spline are样条的节点是

oo$knots
# [1]   1.079339   1.953102   4.014571   5.081642   7.079678   9.032160
# [7]  10.025823  11.941195  12.935311  14.976821  16.999540  18.043524
#[13]  19.976007  22.086941  22.942429  24.925111  25.953444  27.902678
#[19]  30.073938  30.968070  33.019913  34.937244  36.065475  38.058848
#[25]  38.921589  40.982255  43.029412  44.056587  46.005944  47.904666
#[31]  48.995446  51.038546  51.995524  53.987619  55.914136  56.919893
#[37]  59.003727  60.981366  62.082575  63.991813  64.966479  66.951603
#[43]  69.053262  69.916849  71.967815  73.969337  74.966755  77.078440
#[49]  78.072868  80.055464  81.986932  83.042503  84.965070  86.940538
#[55]  88.042224  89.949098  90.928661  92.911787  95.075254  96.055783
#[61]  97.991055 100.062174

The piecewise polynomial coefficients are分段多项式系数为

CoefMat <- oo$PiecePoly$coef
## for the first 5 pieces
CoefMat[, 1:5]
#             [,1]         [,2]         [,3]        [,4]         [,5]
#[1,] -0.626225456 -0.768321912 -0.919380838 -0.83408278 -0.494257767
#[2,] -0.169805245 -0.148267472  0.025888868  0.12418698  0.197353171
#[3,]  0.000000000  0.024649465  0.059832206  0.03228737  0.004331680
#[4,]  0.009403574  0.005688943 -0.008604501 -0.00466386 -0.002702257

The package also has other functionality.该软件包还具有其他功能。 See Identify all local extrema of a fitted smoothing spline via R function 'smooth.spline' for an example.有关示例,请参阅通过 R 函数“smooth.spline”识别拟合平滑样条的所有局部极值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 R 中的一次语句,即仅对 if 语句求值一次 - Once statement in R i.e. evaluate if statement only once R,predict()函数,为什么计算的间隔为0? (即fit = upper = lower) - R, predict() function, why are the calulcated intervals 0? (i.e. fit=upper=lower) R工作区即.R文件 - R workspaces i.e. .R files 如何评估R中样条函数的导数? - how can I evaluate the derivative of a spline function in R? R smooth.spline():平滑样条曲线不平滑但过度拟合我的数据 - R smooth.spline(): smoothing spline is not smooth but overfitting my data R:如何将用户定义的函数应用于数据表的多列并在滑动窗口中进行评估,即移动平均 - R: How to apply user defined functions to multiple columns of data table and evaluate in a sliding window, i.e. moving average 在R中的两个数之间,即5 &lt;= R&gt; 7 - Between two numbers in R i.e. 5<=R>7 通过R函数&#39;smooth.spline&#39;确定拟合的平滑样条曲线的所有局部极值 - Identify all local extrema of a fitted smoothing spline via R function 'smooth.spline' 如何为smooth.spline()选择平滑参数? - how do I select the smoothing parameter for smooth.spline()? 如何检查numpy / pandas对象,即R中的str() - How to inspect a numpy/pandas object, i.e. str() in R
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM