2016-04-21 74 views
5

這裏的用戶指定的程度是我跑smooth.spline():擬合模型不符自由

fun <- function(x) {1 + 3*sin(4*pi*x-pi)} 
set.seed(1) 
num.samples <- 1000 
x <- runif(num.samples) 
y <- fun(x) + rnorm(num.samples) * 1.5 
fit <- smooth.spline(x, y, all.knots=TRUE, df=3) 

儘管df=3的代碼,當我檢查擬合模型,輸出是

Call: 
smooth.spline(x = x, y = y, df = 3, all.knots = TRUE) 
Smoothing Parameter spar= 1.499954 lambda= 0.002508571 (26 iterations) 
Equivalent Degrees of Freedom (Df): 9.86422 

有人可以幫忙嗎?謝謝!

+0

您是否考慮過您提供的自由度是該算法試圖優化的目標(以及其他標準),並且該算法與算法可以達到的距離近似? – joran

回答

4

請注意,從R-3.4.0(2017-04-21),smooth.spline可以通過新增加的參數lambda接受λ的直接規範。但在估算過程中它仍然會被轉換爲內部的spar。所以下面的答案不受影響。


平滑參數λ/spar在於

平滑度是由平滑參數λ控制平整度控制的中心。 smooth.spline()使用內部平滑參數spar而非λ

spar = s0 + 0.0601 * log(λ) 

這種對數變換是必要的,以便做無約束極小化,像GCV/CV。用戶可以指定spar來間接指定λ。當spar線性增長時,λ將成倍增長。因此很少需要使用大的值。

自由df的程度,在λ方面也被定義:

edf

其中X與B樣條基和S模型矩陣是懲罰矩陣。

你可以有他們與您的數據集關係的檢查:

spar <- seq(1, 2.5, by = 0.1) 
a <- sapply(spar, function (spar_i) unlist(smooth.spline(x, y, all.knots=TRUE, spar = spar_i)[c("df","lambda")])) 

讓我們的草圖df ~ sparλ ~ sparlog(λ) ~ spar

par(mfrow = c(1,3)) 
plot(spar, a[1, ], type = "b", main = "df ~ spar", 
    xlab = "spar", ylab = "df") 
plot(spar, a[2, ], type = "b", main = "lambda ~ spar", 
    xlab = "spar", ylab = "lambda") 
plot(spar, log(a[2,]), type = "b", main = "log(lambda) ~ spar", 
    xlab = "spar", ylab = "log(lambda)") 

plot

λ與激進的增長spar,0123之間的線性關係和spar,以及dfspar之間的比較平滑的關係。


smooth.spline()spar

擬合迭代如果我們手動指定的spar的價值,就像我們在sapply()一樣,沒有配件的迭代是爲了選擇spar完成的;否則smooth.spline()需要迭代多個spar值。如果我們

  • 指定cv = TRUE/FALSE,擬合迭代旨在最小化CV/GCV得分;
  • 指定df = mydf,擬合迭代旨在最小化(df(spar) - mydf)^2

最小化GCV很容易。我們不關心GCV評分,但是關心相應的spar。相反,當最小化(df(spar) - mydf)^2時,我們經常在迭代結束時關注df值,而不是spar!但要記住這是一個最小化問題,我們絕不保證最終的df與我們的目標值mydf相符。


爲什麼你把df = 3,但得到df = 9.864?

迭代結束時,既可以打意味着最低,或達到搜索邊界,或達到最大迭代次數。

我們距最大迭代限制(默認值500)很遠;但我們沒有達到最低限度。那麼,我們可能會到達邊界。

請不要關注df,想想spar

smooth.spline(x, y, all.knots=TRUE, df=3)$spar # 1.4999 

?smooth.spline,默認情況下,smooth.spline()搜索[-1.5, 1.5]之間spar。即,當你放df = 3時,最小化終止於搜索邊界,而不是打到df = 3

再看看我們的圖dfspar之間的關係。從圖中看來,我們需要接近2的spar值才能產生df = 3

讓我們用control.spar說法:

fit <- smooth.spline(x, y, all.knots=TRUE, df=3, control.spar = list(high = 2.5)) 
# Smoothing Parameter spar= 1.859066 lambda= 0.9855336 (14 iterations) 
# Equivalent Degrees of Freedom (Df): 3.000305 

現在你看,你結束了df = 3。我們需要一個spar = 1.86


一個更好的建議:不要使用all.knots = TRUE

瞧,你有1000個數據。用all.knots = TRUE您將使用1000個參數。希望以df = 3結束意味着在1000個參數中有997個被抑制。想象一下你需要多大的λ因此spar

請嘗試使用懲罰迴歸樣條曲線。抑制200個參數3肯定是要容易得多:

fit <- smooth.spline(x, y, nknots = 200, df=3) ## using 200 knots 
# Smoothing Parameter spar= 1.317883 lambda= 0.9853648 (16 iterations) 
# Equivalent Degrees of Freedom (Df): 3.000386 

現在,你最終df = 3沒有spar控制。