Python 3を使用した時系列可視化ガイド

前書き

時系列分析は、順序付けられた、多くの場合一時的なデータの調査を含む統計のブランチに属します。 時系列分析を適切に適用すると、予期しない傾向を明らかにしたり、有用な統計を抽出したり、将来の傾向を予測したりすることができます。 これらの理由から、経済学、天気予報、キャパシティプランニングなど、多くの分野に適用されています。

このチュートリアルでは、時系列分析で使用されるいくつかの一般的な手法を紹介し、時系列データの操作、視覚化に必要な反復手順を説明します。

前提条件

このガイドでは、ローカルデスクトップまたはリモートサーバーで時系列分析を行う方法について説明します。 大規模なデータセットの操作はメモリを大量に消費する可能性があるため、いずれの場合も、このガイドの計算の一部を実行するには、コンピューターに少なくとも2GB of memoryが必要です。

このチュートリアルでは、Jupyter Notebookを使用してデータを操作します。 まだお持ちでない場合は、tutorial to install and set up Jupyter Notebook for Python 3に従ってください。

[[step-1 -—- installing-packages]] ==ステップ1—パッケージのインストール

データを操作する際に多くの柔軟性を提供するpandasライブラリと、Pythonで統計計算を実行できるstatsmodelsライブラリを活用します。 一緒に使用すると、これらの2つのライブラリはPythonを拡張して機能を向上させ、分析ツールキットを大幅に増やします。

他のPythonパッケージと同様に、pandasstatsmodelspipとともにインストールできます。 まず、ローカルのプログラミング環境またはサーバーベースのプログラミング環境に移行しましょう。

cd environments
. my_env/bin/activate

ここから、プロジェクト用の新しいディレクトリを作成しましょう。 これをtimeseriesと呼び、ディレクトリに移動します。 プロジェクトを別の名前で呼ぶ場合は、ガイド全体で必ずtimeseriesの代わりに自分の名前を使用してください

mkdir timeseries
cd timeseries

これで、pandasstatsmodels、およびデータプロットパッケージmatplotlibをインストールできます。 それらの依存関係もインストールされます。

pip install pandas statsmodels matplotlib

この時点で、pandasstatsmodelsの操作を開始する準備が整いました。

[[step-2 -—- loading-time-series-data]] ==ステップ2—時系列データの読み込み

データの操作を開始するには、Jupyter Notebookを起動します。

jupyter notebook

新しいノートブックファイルを作成するには、右上のプルダウンメニューからNew>Python 3を選択します。

Create a new Python 3 notebook

これにより、必要なライブラリをロードできるノートブックが開きます(pandasmatplotlib、およびstatsmodelsを参照するために使用される標準の省略形に注意してください)。 ノートブックの上部に、次のように書く必要があります。

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

このチュートリアルの各コードブロックの後に、ALT + ENTERと入力してコードを実行し、ノートブック内の新しいコードブロックに移動する必要があります。

便利なことに、statsmodelsにはデータセットが組み込まれているため、時系列データセットをメモリに直接ロードできます。

1958年3月から2001年12月にかけてCO2サンプルを収集した「米国ハワイ州マウナロア天文台の大気サンプルからの大気CO2」というデータセットを使用します。 このデータを次のように取り込むことができます。

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]] ==ステップ3—時系列データによる索引付け

日付がpandasDataFrameのインデックスとして設定されていることに気付いたかもしれません。 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=2284freq='W-SAT'は、土曜日から毎週2,284個の日付スタンプがあることを示します。

毎週のデータは扱いにくい場合があるため、代わりに時系列の月間平均を使用しましょう。 これは、便利なresample関数を使用して取得できます。この関数を使用すると、時系列をバケット(1か月)にグループ化し、各グループ(平均)にfunctionを適用し、結果を組み合わせることができます(グループごとに1行)。

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

または、データセットをスライスして、10月の1995と10月の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 -—- handling-missing-values-in-time-series-data]] ==ステップ4—時系列データの欠落値の処理

現実の世界のデータは散らかっています。 プロットからわかるように、時系列データに欠損値が含まれることは珍しくありません。 それらをチェックする最も簡単な方法は、データを直接プロットするか、出力で欠落データを明らかにする以下のコマンドを使用することです。

y.isnull().sum()
Output5

この出力は、時系列に値が欠落している5か月があることを示しています。

通常、欠損値が多すぎない場合は、データにギャップがないように欠損値を「埋める」必要があります。 これは、fillna() commandを使用してpandasで実行できます。 単純化するために、時系列で最も近い非ヌル値で欠損値を埋めることができますが、ローリング平均が望ましい場合があることに注意することが重要です。

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

欠損値が入力されると、操作が機能したことを確認するために、もう一度null値が存在するかどうかを確認できます。

y.isnull().sum()
Output0

これらの操作を実行すると、時系列のすべての欠損値が正常に入力されたことがわかります。

[[step-5 -—- visualizing-time-series-data]] ==ステップ5—時系列データの視覚化

時系列データを操作する場合、視覚化することで多くのことが明らかになります。 注目すべきいくつかのことは次のとおりです。

  • seasonalitydoes the data display a clear periodic pattern?

  • trenddoes the data follow a consistent upwards or downward slope?

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

matplotlib APIのpandasラッパーを使用して、データセットのプロットを表示できます。

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

Timeseries Visualization Figure 1

データをプロットすると、いくつかの識別可能なパターンが表示されます。 時系列には明らかな季節性パターンと全体的な増加傾向があります。 時系列分解と呼ばれる方法を使用して、データを視覚化することもできます。 その名前が示すように、時系列分解により、時系列を3つの異なるコンポーネント(トレンド、季節性、ノイズ)に分解できます。

幸い、statsmodelsは、箱から出して季節分解を実行するための便利なseasonal_decompose関数を提供します。 さらに学習することに興味がある場合は、その元の実装のリファレンスは、次のペーパーで見つけることができます。 ]。」

以下のスクリプトは、Pythonで時系列の季節分解を実行する方法を示しています。 デフォルトでは、seasonal_decomposeは比較的小さいサイズの図を返すため、このコードチャンクの最初の2行は、出力図が視覚化するのに十分な大きさであることを保証します。

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で時系列データを視覚化および操作した経験があります。

スキルセットをさらに向上させるには、別のデータセットを読み込んで、このチュートリアルのすべての手順を繰り返します。 たとえば、pandasライブラリを使用してCSVファイルを読み取ったり、statsmodelsライブラリにプリロードされているsunspotsデータセットを使用したりできます:data = sm.datasets.sunspots.load_pandas().data

Related