Глава 7. Узнаем будущее: анализ временных рядов
7.3. Построение временного ряда
Анализ временного ряда часто строится вокруг объяснения выяв-0 ленного тренда и циклических колебаний значений ряда в рамках неко- торой статистической модели.
Найденная модель позволяет: прогнозировать будущие значения ря- да (forecasting), генерировать искусственный временной ряд, все стати- стические характеристики которого эквивалентны исходному (simula- tion), и заполнять пробелы в исходном временном ряду наиболее веро- ятными значениями.
Нужно отличать экстраполяцию временного ряда (прогноз буду- щих значений ряда) от интерполяции (заполнение пробелов между имеющимися данными ряда). Не всегда модели ряда, пригодные для интерполяции, можно использовать для прогноза. Например, полином (степенное уравнение с коэффициентами) очень хорошо сглаживает ис-0 ходный ряд значений и позволяет получить оценку показателя, который описывает данный ряд в промежутках между значениями ряда. Но ес- ли мы попытаемся продлить полином за стартовое значение ряда, то получим совершенно случайный результат. Вместе с тем обычный ли- нейный тренд, хотя и не столь изощренно следует изгибам внутри ряда, дает устойчивый прогноз развития ряда в будущем.
Разные участки ряда могут описывать различные статистические модели, в этом случае говорят, что ряднестационарный. Нестационар- ный временной ряд во многих случаях удается превратить в стационар- ный путем преобразования данных.
В базовые возможностиRвходят средства для представления и ана- лиза временных рядов. Основным типом временн0 ых данных является0
«ts», который представляет собой временной ряд, состоящий из значе- ний, разделенных одинаковыми интервалами времени. Временные ряды0 могут быть образованы и неравномерно отстоящими друг от друга зна- чениями. В этом случае следует воспользоваться специальными типами данных — zoo и its, которые становятся доступными после загрузки пакетов с теми же именами.
Часто необходимо обрабатывать календарные даты. По умолчанию read.table() считывает все нечисловые даты (например, «12/15/04»
или «2004-12-15»), как факторы. Поэтому после загрузки таких дан- ных при помощи read.table() нужно обязательно применить функ- циюas.Date(). Она «понимает» описание шаблона даты и преобразует строки символов в тип данных Date. В последних версияхR она рабо- тает и с факторами:
> dates.df <- data.frame(dates=c("2011-01-01","2011-01-02", + "2011-01-03","2011-01-04","2011-01-05"))
> str(dates.df$dates)
Factor w/ 5 levels "2011-01-01","2011-01-02",..: 1 2 3 4 5
> dates.1 <- as.Date(dates.df$dates, "%Y-%m-%d")
> str(dates.1)
Date[1:5], format: "2011-01-01" "2011-01-02" "2011-01-03"
"2011-01-04" ...
А вот как создаются временные ряды типа ts:
> ts(1:10, # ряд данных + frequency = 4, # поквартально
+ start = c(1959, 2)) # начинаем во втором квартале 1959 года Qtr1 Qtr2 Qtr3 Qtr4
1959 1 2 3
1960 4 5 6 7
1961 8 9 10
Можно конвертировать сразу матрицу, тогда каждая колонка мат- рицы станет отдельным временным рядом:0
# матрица данных из трех столбцов
> z <- ts(matrix(rnorm(300), 100, 3),
+ start=c(1961, 1), # начинаем в 1-й месяц 1961 года + frequency=12) # помесячно
class(z)
[1] "mts" "ts" # тип данных -- многомерный временной ряд Ряды отображаются графически с помощью стандартной функции plot()(рис. 54):
> plot(z,
+ plot.type="single", # поместить все ряды на одном графике + lty=1:3) # типы линий временных рядов
Методы для анализа временных рядов и их моделирования включа-0 ют ARIMA-модели, реализованные в функциях arima(),AR()и VAR(), структурные модели вStructTS(), функции автокорреляции и частной автокорреляции в acf() и pacf(), классическую декомпозицию вре- менного ряда в decompose(), STL-декомпозицию в stl(), скользящее среднее и авторегрессивный фильтр в filter().
Покажем на примере, как применить некоторые из этих функций.
В текстовом файлеleaf2-4.txtв директорииdataзаписаны результа- ты длившихся трое суток непрерывных наблюдений над хищным рас- тением росянкой. Листья этого растения постоянно открываются и за- крываются «в надежде» поймать и затем переварить мелкое насекомое.
Файл содержит результаты наблюдений над четвертым листом второго растения, поэтому он так называется. Состояние листа отмечали каж-
1962 1964 1966 1968
−3−2−1012
Рис. 54. График трех временных рядов с общими осями времени0 дые 40 минут, всего в сутки делали 36 наблюдений. Попробуем сделать временной ряд из колонки FORM, в которой закодированы изменения формы пластинки листа (1 — практически плоская, 2 — вогнутая); это шкальные данные, поскольку можно представить себе форму = 1.5.
Сначала посмотрим, как устроен файл данных, при помощи команды file.show("data/leaf2-4.txt"):
K.UVL;FORM;ZAGN;OTOGN;SVEZH;POLUPER;OSTATKI 2;1;2;2;1;0;1
1;1;2;1;0;1;1 1;1;2;1;1;0;1 2;2;3;1;1;0;0 1;2;3;1;1;0;0 ...
Теперь можно загружать его:
> leaf <- read.table("data/leaf2-4.txt", head=TRUE,
+ as.is=TRUE, sep=";")
Сразу стоит посмотреть, все ли в порядке:0
> str(leaf)
’data.frame’: 80 obs. of 7 variables:
$ K.UVL : int 2 1 1 2 1 1 1 1 1 1 ...
$ FORM : int 1 1 1 2 2 2 2 2 2 2 ...
$ ZAGN : int 2 2 2 3 3 3 2 2 2 2 ...
$ OTOGN : int 2 1 1 1 1 1 1 1 1 1 ...
$ SVEZH : int 1 0 1 1 1 1 1 1 1 1 ...
$ POLUPER: int 0 1 0 0 0 0 0 0 0 0 ...
$ OSTATKI: int 1 1 1 0 0 0 1 1 1 1 ...
> summary(leaf)
K.UVL FORM ZAGN
Min. :1.000 Min. :1.0 Min. :1.0 1st Qu.:1.000 1st Qu.:1.0 1st Qu.:2.0 Median :1.000 Median :2.0 Median :2.0 Mean :1.325 Mean :1.7 Mean :2.5 3rd Qu.:2.000 3rd Qu.:2.0 3rd Qu.:3.0 Max. :2.000 Max. :2.0 Max. :4.0
OTOGN SVEZH POLUPER
Min. :0.00 Min. :0.0000 Min. :0.000 1st Qu.:0.00 1st Qu.:0.0000 1st Qu.:1.000 Median :1.00 Median :0.0000 Median :1.000 Mean :0.75 Mean :0.1625 Mean :0.925 3rd Qu.:1.00 3rd Qu.:0.0000 3rd Qu.:1.000 Max. :2.00 Max. :1.0000 Max. :2.000
OSTATKI Min. :0.0000 1st Qu.:0.0000 Median :1.0000 Mean :0.6125 3rd Qu.:1.0000 Max. :2.0000
Все загрузилось правильно, видимых ошибок и выбросов нет. Теперь преобразуем колонку FORMво временной ряд:
> forma <- ts(leaf$FORM, frequency=36) Проверим:
> str(forma)
Time-Series [1:80] from 1 to 3.19: 1 1 1 2 2 2 2 2 2 2 ...
Все правильно, наблюдения велись чуть больше трех (3.19) суток.
Ну вот, а теперь попробуем понять, насколько наши данные периодичны и есть ли в них тренд (рис. 55):
> (acf(forma, main=""))
Autocorrelations of series ‘forma’, by lag
0.0000 0.0278 0.0556 0.0833 0.1111 0.1389 0.1667 0.1944 0.2222 1.000 0.614 0.287 0.079 0.074 0.068 -0.038 -0.085 -0.132 0.2500 0.2778
-0.137 -0.024
0.3056 0.3333 0.3611 0.3889 0.4167 0.4444 0.4722 0.5000 0.5278 0.030 0.025 -0.082 -0.087 0.027 0.021 -0.043 -0.090 -0.137
0.0 0.1 0.2 0.3 0.4 0.5
−0.20.00.20.40.60.81.0
Lag
ACF
Рис. 55. График автокорреляций для состояния формы листа росянки
Эта команда («auto-correlation function», ACF) выводит коэффици- енты автокорреляции и рисует график автокорреляции, на котором в нашем случае можно увидеть, что значимой периодичности нет — все пики лежат внутри обозначенного пунктиром доверительного интерва- ла, за исключением самых первых пиков, которые соответствуют авто- корреляции без лага или с очень маленьким лагом. По сути, это пока- зывает, что в пределах 0.05 суток (у нас период наблюдений — сутки), то есть около 1 часа, следующее состояние листа будет таким же, как и текущее, а вот на больших интервалах таких предсказаний сделать0 нельзя. То, что волнообразный график пиков как бы затухает, говорит о том, что в наших данных возможен тренд. Проверим это (рис. 56):
> plot(stl(forma, s.window="periodic")$time.series, main="")
−0.4−0.20.00.2seasonal 1.71.81.92.0trend −0.6−0.20.20.6
1.0 1.5 2.0 2.5 3.0
remainder
Time
Рис. 56. График сезонной декомпозиции для состояния формы листа росянки. Возможный тренд изображен на среднем графике
Действительно, наблюдается тенденция к уменьшению значения фор- мы с течением времени. Мы выяснили это при помощи функцииstl()
(названа по имени метода, STL — «Seasonal Decomposition of Time Se- ries by Loess»), которая вычленяет из временного ряда три компоненты:
сезонную (в данном случае суточную), тренд и случайную, при помощи сглаживания данных методом LOESS.
Задача. Попробуйте понять, имеет ли другой признак того же листа (K.UVL, коэффициент увлажнения, отражающий степень «мокрости»
листа) такую же периодичность и тренд.