ビジネスの世界では、売上やPV数などの時系列データがたくさんあります。このような時系列データは、いつも完璧なコンディションで存在するわけではありません。
例えば、データの一部が欠損、つまり、欠測値の状態になっていることがあります。
別の記事で、Rでの時系列データに対する欠測値補完方法について説明しました。
今回は同じデータを使い、Pythonでの時系列データに対する欠測値補完方法について説明します。
Contents
利用データ
今回利用する時系列データのデータセットは、Airline Passengers(飛行機乗客数)です。Box and Jenkins (1976) の有名な時系列データです。サンプルデータとして、よく利用されます。
1955年5月から10月まで(背景が薄い青色の部分)を欠測させます。
欠測させると、以下のようになります。
欠測した1955年5月から10月まで(背景が薄い青色の部分)を欠測値補完してみます。
2つの方法
今回紹介するPythonでの時系列データに対する欠測値補完方法は2つです。
- PythonのPandasで頑張る
- RのimputeTSパッケージの欠測値補完関数をPythonから呼び出して使う
Rの関数をPython上で利用する方法は、以下の記事を参考にしてください。
RのimputeTSパッケージのインストール方法は、先程紹介した以下の記事を参考にしてください。
ここで登場する欠測値補完方法は以下です。
- LOCF法
- 平均値代入法
- 中央値代入法
- 線形補間法
- 多項式補間法
- スプライン補間法
- 移動平均補間法
- カルマン平滑化補間法
どういった手法なのかは、以下の記事を参考にしてください。
必要なライブラリーとデータの読み込み、関数定義
まず、必要なライブラリーを読み込みます。
以下、コードです。
# # Pythonライブラリーの読み込み # import pandas as pd import numpy as np import scipy as sp import datetime import rpy2.robjects as robjects from rpy2.robjects import pandas2ri from rpy2.robjects.packages import importr from rpy2.robjects.conversion import localconverter import matplotlib.pyplot as plt plt.style.use('ggplot') #グラフのスタイル plt.rcParams['figure.figsize'] = [12, 9] # グラフサイズ設定 # # Rライブラリーの読み込み # imputeTS = importr('imputeTS') # Rの欠測値補完関数 R_locf = robjects.r['na_locf'] R_mean = robjects.r['na_mean'] R_interpolation = robjects.r['na_interpolation'] R_ma = robjects.r['na_ma'] R_kalman = robjects.r['na.kalman']
次に、データセットを読み込みます。
以下からダウンロードできます。
AirPassengers_IMP.csv
https://www.salesanalytics.co.jp/pf7x
このURLから直接データセットを読み込めます。
以下、コードです。
# データセットの読み込み url='https://www.salesanalytics.co.jp/pf7x' #データセットのあるURL df=pd.read_csv(url, #読み込むデータのURL index_col='Month', #変数「Month」をインデックスに設定 parse_dates=True) #インデックスを日付型に設定
欠測値の数を確認してみます。
以下、コードです。
df.isnull().sum()
以下、実行結果です。
欠測値が6つあることが分かります。
Rの関数をPython上で利用するためには、PythonのデータフレームをRのデータフレームに変換したり、その逆の変換をしたりします。さらに、似たようなグラフを欠測値方法ごとに作るため、それを関数として定義し使おうと思います。
ということで、必要な関数を定義します。
以下、コードです。
# グラフ生成関数 def plot_gen(df_imp_pd): df_imp_pd.plot() plt.title('Passengers') #グラフタイトル plt.ylabel('Monthly Number of Airline Passengers') #タテ軸のラベル plt.xlabel('Month') #ヨコ軸のラベル start_datetime = datetime.datetime(1955, 5,1) end_datetime = datetime.datetime(1955, 10,1) plt.axvspan(start_datetime, end_datetime, facecolor='b', alpha=0.1) plt.show() # PythonデータフレームをR版に変換する関数 def pyr_df(df): with localconverter(robjects.default_converter + pandas2ri.converter): df_r = robjects.conversion.py2rpy(df) return df_r # RデータフレームをPython版に変換する関数(index:日付) def rpy_df(df_imp): with localconverter(robjects.default_converter + pandas2ri.converter): df_imp_pd = robjects.conversion.rpy2py(df_imp) df_imp_pd.index = pd.to_datetime(df_imp_pd.index) return df_imp_pd
PythonのPandasで頑張る
以下の欠測値補完法の実行例を説明します。
- LOCF法
- 平均値代入法
- 中央値代入法
- 線形補間法
- 多項式補間法
- スプライン補間法
LOCF法
LOCF法で欠測値補完します。
以下、コードです。
df_imp_pd = df.fillna(method = 'ffill')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(df_imp_pd)
以下、実行結果です。
平均値代入法
平均値代入法で欠測値補完します。
以下、コードです。
df_imp_pd = df.fillna(df.mean())
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(df_imp_pd)
以下、実行結果です。
中央値代入法
中央値代入法で欠測値補完します。
以下、コードです。
df_imp_pd = df.fillna(df.median())
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(df_imp_pd)
以下、実行結果です。
線形補間法
線形補間法で欠測値補完します。
以下、コードです。
df_imp_pd = df.interpolate(method='linear')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(df_imp_pd)
以下、実行結果です。
多項式補間法
多項式補間法で欠測値補完します。
以下、コードです。
df_imp_pd = df.interpolate(method='polynomial', order=5)
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(df_imp_pd)
以下、実行結果です。
スプライン補間法
スプライン補間法で欠測値補完します。
以下、コードです。
df_imp_pd = df.interpolate(method='spline', order=3)
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(df_imp_pd)
以下、実行結果です。
RのimputeTSパッケージの欠測値補完関数をPythonから呼び出して使う
以下の欠測値補完法の実行例を説明します。
- LOCF法
- 平均値代入法
- 中央値代入法
- 線形補間法
- スプライン補間法
- 移動平均補間法
- カルマン平滑化補間法
LOCF法
LOCF法で欠測値補完します。
以下、コードです。
df_imp = R_locf(pyr_df(df), option = 'locf')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
平均値代入法
平均値代入法で欠測値補完します。
以下、コードです。
df_imp = R_mean(pyr_df(df), option = 'mean')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
中央値代入法
中央値代入法で欠測値補完します。
以下、コードです。
df_imp = R_mean(pyr_df(df), option = 'median')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
線形補間法
線形補間法で欠測値補完します。
以下、コードです。
df_imp = R_interpolation(pyr_df(df), option = 'linear')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
スプライン補間法
スプライン補間法で欠測値補完します。
以下、コードです。
df_imp = R_interpolation(pyr_df(df), option = 'spline')
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
移動平均補間法
移動平均補間法で欠測値補完します。
以下、コードです。
df_imp = R_ma(pyr_df(df), k = 4)
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
カルマン平滑化補間法
カルマン平滑化補間法で欠測値補完します。
以下、コードです。
df_imp = R_kalman(pyr_df(df), model = "auto.arima")
グラフ化しどのように補完したのかを確認します。
以下、コードです。
plot_gen(rpy_df(df_imp))
以下、実行結果です。
まとめ
今回は、「Pythonでの時系列データに対する欠測値補完方法」というおお話しをしました。
Rで時系列データの欠測値補完をしたい方は、以下の記事を参考にしてください。