Інші відповіді - це хороші підходи. Однак є кілька інших варіантів у R, про які не згадувалось, включаючи lowessтаapprox , які можуть забезпечити кращі підходи або швидшу продуктивність.
Переваги легше продемонструвати за допомогою альтернативного набору даних:
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)))
Ось дані, накладені на сигмоподібну криву, яка їх породила:

Цей тип даних є загальним при розгляді бінарної поведінки серед населення. Наприклад, це може бути графік того, чи купував клієнт щось (двійковий файл 1/0 на осі y) проти кількості часу, проведеного ним на сайті (вісь x).
Велика кількість балів використовується для кращого демонстрування відмінностей у виконанні цих функцій.
Smooth, splineІsmooth.spline всі продукти тарабарщина на наборі даних , як це з будь-яким набором параметрів я пробував, можливо , з - за їх схильність до карти в будь-яку точку, що не робить роботу для зашумлених даних.
В loess, lowessі approxфункції все одно виконують потрібні результати, хоча навряд за approx. Це код для кожного з використанням злегка оптимізованих параметрів:
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))
І результати:
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"))

Як бачите, lowessзабезпечує майже ідеальне припасування до вихідної генеруючої кривої. Loessблизько, але відчуває дивне відхилення в обох хвостах.
Незважаючи на те, що ваш набір даних буде сильно відрізнятися, я виявив, що інші набори даних працюють однаково, і те, loessі інше і lowessможе дати хороші результати. Різниці стають більш суттєвими, якщо поглянути на еталони:
> 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надзвичайно повільний, приймаючи 100x стільки, скільки approx. Lowessприносить кращі результати, ніж approx, хоча при цьому працює досить швидко (в 15 разів швидше, ніж лесс).
Loess також стає все більш заглибленим, оскільки кількість очок збільшується, стаючи непридатною близько 50 000.
РЕДАКТУВАТИ: Додаткове дослідження показує, що loessкраще підходить для певних наборів даних. Якщо ви маєте справу з невеликим набором даних або продуктивність не є проблемою, спробуйте обидві функції та порівняйте результати.