簡體   English   中英

R中小數據集的樣條函數

[英]Spline functions for small data sets in R

我一直在嘗試使用R中可用的各種不同的樣條函數來表征非常小的數據集。 我想如果使用更大的數據集,任何數量的曲線都可以像我期望的那樣運行,但是這種情況下的數據是有限的。 以下代碼顯示了我正在使用的數據類型的示例:

library(ggplot2); library(stats)

dat <- data.frame(x = c(0.333, 0.5, 1, 2, 3, 4, 5),
                  y = c(5.875e-03, 1.225e-02, 3.902e-02, 8.942e-03,
                        4.277e-03, 1.938e-03, 1.131e-03))


mod <- splinefun(dat$x, dat$y, method = "monoH.FC")
mod <- data.frame(x = seq(0.333, 5, by = 0.1), y = mod(seq(0.333, 5, by = 0.1)))

ggplot() + geom_point(data = dat, aes(x = x, y = y)) +
geom_line(data = mod, aes(x = x, y = y))

曲線示例

到目前為止,最適合使用單調Hermite樣條,但仍然存在一些問題。

直觀地說,我可以告訴您這里的曲線應該是什么樣子。 它應該在x = 1處有最大值,並且在x = 2.5處不應該有該下降。 曲線似乎不應該很難重新創建。 它是不對稱的,具有左偏斜和可預測的尾巴。

有沒有一種“更好”的方法來產生更適合擬合(我認為是)通用數據集的樣條函數,或者是否有比樣條線更好的工具將曲線擬合到小數據集?

聽起來您想要的是使擬合更接近中間的線性,我認為您可以通過將中點內插為真實點來強制這樣做:

dat2 = data.frame(x = union(dat$x,dat$x - c(0,diff(dat$x)/2)), 
                  y = interp1(dat$x,dat$y,xi = union(dat$x,dat$x - c(0,diff(dat$x)/2))))

interp1可能在這里是不必要的, union(dat$y,dat$y - c(0,diff(dat$y)/2))應該做同樣的事情,但是上面的代碼有效。)

編輯:注意,為了使diff工作,您需要先對數據進行正確排序

這將創建一個新的data.frame,其點在先前的點之間,如果現在進行樣條化,則將加權更線性的擬合

EDIT2:您還可以通過這種方式使用帶有權重的平滑樣條線,並將點之間的權重設置為低於主要點的權重:

mod <- splinefun(dat$x, dat$y,method = 'monoH.FC')
mod2 <- data.frame(x = seq(0.333, 5, by = 0.1), y = mod(seq(0.333, 5, by = 0.1)))


# A set of weights, where each point in-between is weighted half as much
dat2$w <- rep(c(0.5,1),ceiling(length(dat2$x)/2))[-1]

# Smoothing Spline
modelspline <- smooth.spline(dat2$x, dat2$y,dat2$w)

# Plot points
xplot <- seq(min(dat2$x),max(dat2$x),by = 0.1)

# And Plot comparison
ggplot() + 
  geom_point(data = dat, aes(x = x, y = y)) + 
  geom_line(data = mod2, aes(x = x, y = y)) + 
  geom_line(data = data.frame(predict(modelspline,xplot)),
        aes(x = x, y = y),color = 'red')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM