Руководство по визуализации временных рядов с помощью Python 3

Вступление

Анализ временных рядов относится к разделу статистики, который включает изучение упорядоченных, часто временных данных. При соответствующем применении анализ временных рядов может выявить неожиданные тенденции, извлечь полезную статистику и даже прогнозировать тенденции на будущее. По этим причинам он применяется во многих областях, включая экономику, прогнозирование погоды и планирование мощностей, и многое другое.

В этом уроке мы представим некоторые общие методы, используемые в анализе временных рядов, и пройдемся по итерационным шагам, необходимым для манипулирования, визуализации данных временных рядов.

Предпосылки

В этом руководстве будет рассказано, как выполнять анализ временных рядов на локальном компьютере или на удаленном сервере. Работа с большими наборами данных может потребовать много памяти, поэтому в любом случае компьютеру потребуется не менее2GB of memory для выполнения некоторых вычислений в этом руководстве.

В этом руководстве мы будем использоватьJupyter Notebook для работы с данными. Если у вас его еще нет, следуйте нашимtutorial to install and set up Jupyter Notebook for Python 3.

[[step-1 -—- install-packages]] == Шаг 1. Установка пакетов

Мы будем использовать библиотекуpandas, которая предлагает большую гибкость при работе с данными, и библиотекуstatsmodels, которая позволяет нам выполнять статистические вычисления на Python. Вместе эти две библиотеки расширяют Python, предлагая более широкие функциональные возможности и значительно расширяя наш аналитический инструментарий.

Как и в случае с другими пакетами Python, мы можем установитьpandas иstatsmodels с помощьюpip. Во-первых, давайте перейдем в нашу локальную среду программирования или среду программирования на основе сервера:

cd environments
. my_env/bin/activate

Отсюда давайте создадим новый каталог для нашего проекта. Мы назовем егоtimeseries, а затем перейдем в каталог. Если вы назвали проект другим именем, не забудьте заменитьtimeseries своим именем на протяжении всего руководства.

mkdir timeseries
cd timeseries

Теперь мы можем установитьpandas,statsmodels и пакет построения графиков данныхmatplotlib. Их зависимости также будут установлены:

pip install pandas statsmodels matplotlib

На этом этапе мы готовы начать работу сpandas иstatsmodels.

[[step-2 -—- loading-time-series-data]] == Шаг 2 - Загрузка данных временного ряда

Чтобы начать работать с нашими данными, мы запустим Jupyter Notebook:

jupyter notebook

Чтобы создать новый файл записной книжки, выберитеNew>Python 3 в правом верхнем раскрывающемся меню:

Create a new Python 3 notebook

Это откроет записную книжку, которая позволит нам загрузить необходимые библиотеки (обратите внимание на стандартные сокращения, используемые для ссылок наpandas,matplotlib иstatsmodels). В верхней части нашей записной книжки мы должны написать следующее:

import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt

После каждого блока кода в этом руководстве вы должны вводитьALT + ENTER, чтобы запустить код и перейти в новый блок кода в записной книжке.

Удобно, чтоstatsmodels поставляется со встроенными наборами данных, поэтому мы можем загрузить набор данных временных рядов прямо в память.

Мы будем работать с набором данных, который называется «Атмосферный CO2 из непрерывных проб воздуха в обсерватории Мауна-Лоа, Гавайи, США», который собирал образцы CO2 с марта 1958 года по декабрь 2001 года. Мы можем внести эти данные следующим образом:

data = sm.datasets.co2.load_pandas()
co2 = data.data

Давайте посмотрим, как выглядят первые 5 строк наших временных рядов:

print(co2.head(5))
Output              co2
1958-03-29  316.1
1958-04-05  317.3
1958-04-12  317.6
1958-04-19  317.5
1958-04-26  316.4

После импорта наших пакетов и готовности набора данных CO2 мы можем приступить к индексации наших данных.

[[step-3 -—- indexing-with-time-series-data]] == Step 3 - Indexing-with-time-series-data

Вы могли заметить, что даты были установлены как индекс нашего фрейма данныхpandas. При работе с данными временных рядов в Python мы должны убедиться, что даты используются в качестве индекса, поэтому всегда проверяйте это, что мы можем сделать, выполнив следующее:

co2.index
OutputDatetimeIndex(['1958-03-29', '1958-04-05', '1958-04-12', '1958-04-19',
               '1958-04-26', '1958-05-03', '1958-05-10', '1958-05-17',
               '1958-05-24', '1958-05-31',
               ...
               '2001-10-27', '2001-11-03', '2001-11-10', '2001-11-17',
               '2001-11-24', '2001-12-01', '2001-12-08', '2001-12-15',
               '2001-12-22', '2001-12-29'],
              dtype='datetime64[ns]', length=2284, freq='W-SAT')

Полеdtype=datetime[ns] подтверждает, что наш индекс состоит из объектов отметки даты, аlength=2284 иfreq='W-SAT' говорят нам, что у нас есть 2284 еженедельных отметки даты, начиная с субботы.

С еженедельными данными может быть сложно работать, поэтому давайте вместо этого будем использовать среднемесячные значения наших временных рядов. Этого можно добиться, используя удобную функциюresample, которая позволяет нам сгруппировать временные ряды в сегменты (1 месяц), применитьfunction к каждой группе (среднее значение) и объединить результат ( по одной строке на группу).

y = co2['co2'].resample('MS').mean()

Здесь терминMS означает, что мы группируем данные в сегменты по месяцам и гарантируем, что мы используем начало каждого месяца в качестве метки времени:

y.head(5)
Output1958-03-01    316.100
1958-04-01    317.200
1958-05-01    317.120
1958-06-01    315.800
1958-07-01    315.625
Freq: MS, Name: co2, dtype: float64

Интересной особенностьюpandas является его способность обрабатывать индексы отметок даты, что позволяет нам быстро разрезать наши данные. Например, мы можем разрезать наш набор данных, чтобы получать только те точки данных, которые поступают после года1990:

y['1990':]
Output1990-01-01    353.650
1990-02-01    354.650
               ...
2001-11-01    369.375
2001-12-01    371.020
Freq: MS, Name: co2, dtype: float64

Или мы можем разрезать наш набор данных, чтобы получать только точки данных между октябрем1995 и октябрем1996:

y['1995-10-01':'1996-10-01']
Output1995-10-01    357.850
1995-11-01    359.475
1995-12-01    360.700
1996-01-01    362.025
1996-02-01    363.175
1996-03-01    364.060
1996-04-01    364.700
1996-05-01    365.325
1996-06-01    364.880
1996-07-01    363.475
1996-08-01    361.320
1996-09-01    359.400
1996-10-01    359.625
Freq: MS, Name: co2, dtype: float64

При правильной индексации наших данных для работы с временными данными мы можем перейти к обработке значений, которые могут отсутствовать.

[[step-4 -—- processing-missing-values-in-time-series-data]] == Шаг 4 - Обработка отсутствующих значений в данных временного ряда

Данные реального мира имеют тенденцию быть грязными. Как видно из графика, данные временных рядов нередко содержат пропущенные значения. Самый простой способ проверить это - либо напрямую отобразить данные, либо с помощью приведенной ниже команды, которая покажет недостающие данные в выводе:

y.isnull().sum()
Output5

Этот вывод говорит нам, что в нашем временном ряду 5 месяцев с пропущенными значениями.

Как правило, мы должны «заполнить» пропущенные значения, если их не слишком много, чтобы у нас не было пробелов в данных. Мы можем сделать это вpandas, используяfillna() command. Для простоты мы можем заполнить пропущенные значения ближайшим ненулевым значением в нашем временном ряду, хотя важно отметить, что скользящее среднее иногда было бы предпочтительным.

y = y.fillna(y.bfill())

Заполнив пропущенные значения, мы можем еще раз проверить, существуют ли какие-либо нулевые значения, чтобы убедиться, что наша операция работает:

y.isnull().sum()
Output0

После выполнения этих операций мы видим, что мы успешно заполнили все пропущенные значения в наших временных рядах.

[[step-5 -—- visualizing-time-series-data]] == Шаг 5 - Визуализация данных временного ряда

При работе с данными временных рядов многое можно выявить путем их визуализации. Несколько вещей, на которые стоит обратить внимание:

  • seasonality:does the data display a clear periodic pattern?

  • trend:does the data follow a consistent upwards or downward slope?

  • noise:are there any outlier points or missing values that are not consistent with the rest of the data?

Мы можем использовать оболочкуpandas вокруг APImatplotlib для отображения графика нашего набора данных:

y.plot(figsize=(15, 6))
plt.show()

Timeseries Visualization Figure 1

Некоторые различимые шаблоны появляются, когда мы наносим данные. Временные ряды имеют явную модель сезонности, а также общую тенденцию к росту. Мы также можем визуализировать наши данные, используя метод, называемый декомпозицией временных рядов. Как следует из названия, декомпозиция временных рядов позволяет нам разбивать наш временной ряд на три отдельных компонента: тренд, сезонность и шум.

К счастью,statsmodels предоставляет удобную функциюseasonal_decompose для выполнения сезонной декомпозиции из коробки. Если вы заинтересованы в получении дополнительной информации, ссылку на оригинальную реализацию можно найти в следующей статье: «http://www.wessa.net/download/stl.pdf[STL: Процедура разложения по сезонным трендам на основе Loess ] «.

Сценарий ниже показывает, как выполнить сезонную декомпозицию временных рядов в Python. По умолчаниюseasonal_decompose возвращает цифру относительно небольшого размера, поэтому первые две строки этого фрагмента кода гарантируют, что выходная цифра достаточно велика, чтобы мы могли ее визуализировать.

from pylab import rcParams
rcParams['figure.figsize'] = 11, 9

decomposition = sm.tsa.seasonal_decompose(y, model='additive')
fig = decomposition.plot()
plt.show()

Timeseries Seasonal-Trend Decomposition Visualization Figure 2

Использование разложения по временным рядам облегчает быструю идентификацию изменяющегося среднего или изменения данных. График выше ясно показывает тенденцию роста наших данных, наряду с их ежегодной сезонностью. Их можно использовать для пониманияstructure нашего временного ряда. Интуиция позади декомпозиции временных рядов важна, поскольку многие методы прогнозирования основываются на этой концепции структурированной декомпозиции для получения прогнозов.

Заключение

Если вы следовали этому руководству, у вас теперь есть опыт визуализации и манипулирования данными временных рядов в Python.

Чтобы еще больше улучшить свой набор навыков, вы можете загрузить другой набор данных и повторить все шаги этого урока. Например, вы можете прочитать CSV-файл с помощью библиотекиpandas или использовать набор данныхsunspots, который предварительно загружен с библиотекойstatsmodels:data = sm.datasets.sunspots.load_pandas().data.

Related