Diğer cevapların hepsi iyi yaklaşımlardır. Bununla birlikte, daha iyi uyum veya daha hızlı performans sağlayabilen lowess
ve dahil olmak üzere R'de bahsedilmeyen birkaç başka seçenek vardır approx
.
Avantajlar, alternatif bir veri kümesiyle daha kolay gösterilir:
sigmoid <- function(x)
{
y<-1/(1+exp(-.15*(x-100)))
return(y)
}
dat<-data.frame(x=rnorm(5000)*30+100)
dat$y<-as.numeric(as.logical(round(sigmoid(dat$x)+rnorm(5000)*.3,0)))
İşte onu oluşturan sigmoid eğrisi ile örtüşen veriler:
Bu tür veriler, bir popülasyon arasındaki ikili davranışa bakıldığında yaygındır. Örneğin, bu, bir müşterinin bir şey satın alıp almadığına (y ekseninde ikili 1/0) karşı sitede geçirdiği süreye (x ekseni) ilişkin bir grafik olabilir.
Bu işlevlerin performans farklılıklarını daha iyi göstermek için çok sayıda nokta kullanılır.
Smooth
, spline
ve bunların smooth.spline
tümü, denediğim herhangi bir parametre setiyle bunun gibi bir veri kümesinde anlamsız şeyler üretiyor, belki de gürültülü veriler için çalışmayan her noktaya eşleme eğilimleri nedeniyle.
loess
, lowess
Ve approx
işlevleri tüm üretmek kullanılabilir sonuçları, zar zor için her ne kadar approx
. Bu, hafifçe optimize edilmiş parametreleri kullanan her biri için koddur:
loessFit <- loess(y~x, dat, span = 0.6)
loessFit <- data.frame(x=loessFit$x,y=loessFit$fitted)
loessFit <- loessFit[order(loessFit$x),]
approxFit <- approx(dat,n = 15)
lowessFit <-data.frame(lowess(dat,f = .6,iter=1))
Ve sonuçlar:
plot(dat,col='gray')
curve(sigmoid,0,200,add=TRUE,col='blue',)
lines(lowessFit,col='red')
lines(loessFit,col='green')
lines(approxFit,col='purple')
legend(150,.6,
legend=c("Sigmoid","Loess","Lowess",'Approx'),
lty=c(1,1),
lwd=c(2.5,2.5),col=c("blue","green","red","purple"))
Gördüğünüz gibi lowess
, orijinal oluşturma eğrisine neredeyse mükemmel bir uyum sağlar. Loess
yakın, ancak her iki kuyrukta da garip bir sapma yaşıyor.
Sizin veri kümesi çok farklı olacak olsa da, diğer veri kümeleri hem benzer performans gösterdiğini bulduk loess
ve lowess
iyi sonuçlar üretme yeteneğine sahip. Karşılaştırmalara baktığınızda farklılıklar daha önemli hale gelir:
> microbenchmark::microbenchmark(loess(y~x, dat, span = 0.6),approx(dat,n = 20),lowess(dat,f = .6,iter=1),times=20)
Unit: milliseconds
expr min lq mean median uq max neval cld
loess(y ~ x, dat, span = 0.6) 153.034810 154.450750 156.794257 156.004357 159.23183 163.117746 20 c
approx(dat, n = 20) 1.297685 1.346773 1.689133 1.441823 1.86018 4.281735 20 a
lowess(dat, f = 0.6, iter = 1) 9.637583 10.085613 11.270911 11.350722 12.33046 12.495343 20 b
Loess
son derece yavaştır, 100 kat daha uzun sürer approx
. Hala oldukça hızlı çalışırken (lösten 15 kat daha hızlı) olduğundan Lowess
daha iyi sonuçlar verir approx
.
Loess
ayrıca, puan sayısı arttıkça 50.000 civarında kullanılamaz hale geldikçe giderek daha fazla tıkanıyor.
DÜZENLEME: Ek araştırmalar, loess
belirli veri kümeleri için daha iyi uyum sağladığını gösteriyor . Küçük bir veri kümesiyle uğraşıyorsanız veya performans dikkate alınmıyorsa, her iki işlevi de deneyin ve sonuçları karşılaştırın.