Прогнозирование временных рядов, имеющих дело с известными крупными заказами
У меня много наборов данных с известными выбросами (большие заказы)
data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3","14Q4","15Q1", 155782698, 159463653.4, 172741125.6, 204547180, 126049319.8, 138648461.5, 135678842.1, 242568446.1, 177019289.3, 200397120.6, 182516217.1, 306143365.6, 222890269.2, 239062450.2, 229124263.2, 370575384.7, 257757410.5, 256125841.6, 231879306.6, 419580274, 268211059, 276378232.1, 261739468.7, 429127062.8, 254776725.6, 329429882.8, 264012891.6, 496745973.9, 284484362.55),ncol=2,byrow=FALSE)
Топ-11 выбросов этой конкретной серии:
outliers <- matrix(c("14Q4","14Q2","12Q1","13Q1","14Q2","11Q1","11Q4","14Q2","13Q4","14Q4","13Q1",20193525.68, 18319234.7, 12896323.62, 12718744.01, 12353002.09, 11936190.13, 11356476.28, 11351192.31, 10101527.85, 9723641.25, 9643214.018),ncol=2,byrow=FALSE)
Какие существуют методы, позволяющие прогнозировать временные ряды, учитывающие эти выбросы?
Я уже пробовал заменить следующий самый большой выброс (так что запуск набора данных в 10 раз заменил выбросы следующим самым большим, пока 10-й набор данных не заменит все выбросы).
Я также попробовал просто удалить выбросы (так что снова запустив набор данных 10 раз каждый раз удаляя выброс, пока все 10 не будут удалены в 10-м наборе данных)
Я просто хочу указать, что удаление этих больших заказов не полностью удаляет точку данных, поскольку в этой четверти происходят другие сделки.
Мой код проверяет данные с помощью нескольких моделей прогнозирования (ARIMA, взвешенный по образцу, ARIMA, взвешенный по образцу, взвешенный ARIMA, взвешенный ARIMA, аддитивные холт-зимы и мультипликативные холт-зимы взвешиваются), поэтому это должно быть что-то которые могут быть адаптированы к этим нескольким моделям.
Вот еще несколько наборов данных, которые я использовал, у меня нет выбросов для этих серий, хотя
data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3", 26393.99306, 13820.5037, 23115.82432, 25894.41036, 14926.12574, 15855.8857, 21565.19002, 49373.89675, 27629.10141, 43248.9778, 34231.73851, 83379.26027, 54883.33752, 62863.47728, 47215.92508, 107819.9903, 53239.10602, 71853.5, 59912.7624, 168416.2995, 64565.6211, 94698.38748, 80229.9716, 169205.0023, 70485.55409, 133196.032, 78106.02227), ncol=2,byrow=FALSE)
data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3",3311.5124, 3459.15634, 2721.486863, 3286.51708, 3087.234059, 2873.810071, 2803.969394, 4336.4792, 4722.894582, 4382.349583, 3668.105825, 4410.45429, 4249.507839, 3861.148928, 3842.57616, 5223.671347, 5969.066896, 4814.551389, 3907.677816, 4944.283864, 4750.734617, 4440.221993, 3580.866991, 3942.253996, 3409.597269, 3615.729974, 3174.395507),ncol=2,byrow=FALSE)
Если это слишком сложно, то объяснение того, как в R, как только выбросы обнаруживаются с использованием определенных команд, данные обрабатываются для прогнозирования. например, сглаживание и т.д. и как я могу подойти к написанию кода самостоятельно (не используя команды, которые обнаруживают выбросы)
Ответы
Ответ 1
Ваши выбросы кажутся сезонными вариациями с наибольшими заказами, появляющимися в 4-м квартале. Многие из упомянутых вами моделей прогнозирования включают возможность сезонных корректировок. Например, простейшая модель может иметь линейную зависимость от года с поправками для всех сезонов. Код будет выглядеть так:
df <- data.frame(period= c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3",
"10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2",
"13Q3","13Q4","14Q1","14Q2","14Q3","14Q4","15Q1"),
order= c(155782698, 159463653.4, 172741125.6, 204547180, 126049319.8, 138648461.5,
135678842.1, 242568446.1, 177019289.3, 200397120.6, 182516217.1, 306143365.6,
222890269.2, 239062450.2, 229124263.2, 370575384.7, 257757410.5, 256125841.6,
231879306.6, 419580274, 268211059, 276378232.1, 261739468.7, 429127062.8, 254776725.6,
329429882.8, 264012891.6, 496745973.9, 42748656.73))
seasonal <- data.frame(year=as.numeric(substr(df$period, 1,2)), qtr=substr(df$period, 3,4), data=df$order)
ord_model <- lm(data ~ year + qtr, data=seasonal)
seasonal <- cbind(seasonal, fitted=ord_model$fitted)
library(reshape2)
library(ggplot2)
plot_fit <- melt(seasonal,id.vars=c("year", "qtr"), variable.name = "Source", value.name="Order" )
ggplot(plot_fit, aes(x=year, y = Order, colour = qtr, shape=Source)) + geom_point(size=3)
который дает результаты, показанные в таблице ниже:
![Linear fit with seasonal adjustments]()
Модели с сезонной корректировкой, но нелинейная зависимость от года может дать лучшие приемы.
Ответ 2
![enter image description here]()
Подход, который вы пытаетесь использовать для очистки ваших данных выбросов, не будет достаточно надежным, чтобы идентифицировать их. Я должен добавить, что есть бесплатный пакет outlier в R, называемый tsoutliers, но он не будет делать то, что я собираюсь показать вам....
У вас здесь интересный временной ряд. Тенденция меняется со временем с ослаблением восходящего тренда. Если вы принесете две переменные тренда с первым началом в 1 и другим, начиная с 14-го и вперед, вы будете фиксировать это изменение. Что касается сезонности, вы можете захватить высокий 4-й квартал с помощью фиктивной переменной. Модель представляет собой parsimonios, поскольку остальные 3 квартала не отличаются от среднего значения плюс отсутствие необходимости в AR12, сезонных различиях или 3 сезонных манекенах. Вы также можете зафиксировать влияние последних двух наблюдений на выбросы с двумя фиктивными переменными. Игнорируйте 49 выше слова тренда, поскольку это просто название модели, моделируемой. ![Actual, Fit, Forecasts with Confidence limits]()
Ответ 3
Вы уже сказали, что попробовали разные модели Arima, но, как уже упоминалось в WaltS, ваша серия, похоже, не содержит больших выбросов, а сезонную составляющую, которая красиво захвачена auto.arima()
в пакете forecast
myTs <- ts(as.numeric(data[,2]), start=c(2008, 1), frequency=4)
myArima <- auto.arima(myTs, lambda=0)
myForecast <- forecast(myArima)
plot(myForecast)
![enter image description here]()
где аргумент lambda=0
для auto.arima()
заставляет преобразовать (или вы можете взять журнал) данных с помощью boxcox
, чтобы учитывать возрастающую амплитуду сезонного компонента.