Недавно я столкнулся с подобной проблемой и не нашел ответы здесь особенно полезными.Вот альтернативный подход.
Давайте начнем с определения примеров данных из вопроса:
number_of_cycles = 2
max_y = 40
x = 1:500
a = number_of_cycles * 2*pi/length(x)
y = max_y * sin(x*a)
noise1 = max_y * 1/10 * sin(x*a*10)
y <- y + noise1
plot(x, y, type="l", ylim=range(-1.5*max_y,1.5*max_y,5), lwd = 5, col = "green")
Таким образом, зеленая линия - это набор данных, который мы хотим передать на низком уровне.и фильтр верхних частот.
Примечание: линию в этом случае можно выразить как функцию, используя кубический сплайн (spline(x,y, n = length(x))
), но с данными реального мира это будет редко, поэтому давайте предположим, что это невозможночтобы выразить набор данных как функцию.
Самый простой способ сгладить такие данные, с которыми я столкнулся, - это использовать loess
или smooth.spline
с соответствующими span
/ spar
.По мнению статистиков loess / smooth.spline, вероятно, не является правильным подходом здесь , так как он не представляет определенную модель данных в этом смысле.Альтернативой является использование обобщенных аддитивных моделей (функция gam()
из пакета mgcv ).Мой аргумент в пользу использования лёсса или сглаженного сплайна здесь заключается в том, что это проще и не имеет значения, так как нас интересует видимый результирующий паттерн.Наборы данных реального мира более сложны, чем в этом примере, и поиск определенной функции для фильтрации нескольких похожих наборов данных может быть затруднен.Если видимое совпадение хорошее, зачем усложнять его значениями R2 и p?Для меня приложение визуально, для которого лесс / сглаженные сплайны являются подходящими методами.Оба метода предполагают полиномиальные отношения с той разницей, что лесс более гибок, также используя полиномы более высокой степени, в то время как кубический сплайн всегда кубический (x ^ 2).Какой из них использовать, зависит от тенденций в наборе данных.Тем не менее, следующий шаг - применить фильтр нижних частот к набору данных, используя loess()
или smooth.spline()
:
lowpass.spline <- smooth.spline(x,y, spar = 0.6) ## Control spar for amount of smoothing
lowpass.loess <- loess(y ~ x, data = data.frame(x = x, y = y), span = 0.3) ## control span to define the amount of smoothing
lines(predict(lowpass.spline, x), col = "red", lwd = 2)
lines(predict(lowpass.loess, x), col = "blue", lwd = 2)
Красная линия сглаженасплайн-фильтр и синий лесс-фильтр.Как видите, результаты немного отличаются.Я полагаю, что одним из аргументов в пользу использования GAM было бы найти наилучшее соответствие, если бы тренды действительно были такими четкими и последовательными среди наборов данных, но для этого приложения оба эти соответствия достаточно хороши для меня.
После поискаПри установке фильтра нижних частот, фильтрация верхних частот так же проста, как вычитание значений фильтра нижних частот из y
:
highpass <- y - predict(lowpass.loess, x)
lines(x, highpass, lwd = 2)
Этот ответ приходит поздно,но я надеюсь, что это поможет кому-то еще бороться с подобной проблемой.