Pythonでの時系列データに対する欠測値補完方法

Pythonでの時系列データに対する欠測値補完方法

ビジネスの世界では、売上やPV数などの時系列データがたくさんあります。このような時系列データは、いつも完璧なコンディションで存在するわけではありません。

例えば、データの一部が欠損、つまり、欠測値の状態になっていることがあります。

別の記事で、Rでの時系列データに対する欠測値補完方法について説明しました。

RのimputeTSパッケージを使った時系列データの欠測値補完

 

今回は同じデータを使い、Pythonでの時系列データに対する欠測値補完方法について説明します。

 

利用データ

今回利用する時系列データのデータセットは、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で時系列データの欠測値補完をしたい方は、以下の記事を参考にしてください。

RのimputeTSパッケージを使った時系列データの欠測値補完