【Kaggle入門ー時系列分析】 Store Sales – Time Series Forecasting – EDA

※アフィリエイト広告を利用しています。

はじめに

Kaggleは、英語のページしかありません。そこで、日本語で読みたい方向けに記事を作成しました。

Store Salesの概要の説明が前のブログ記事で済みました。

次に実際にGoogle Colabを動かして、与えられたデータに対してEDA(Explanatory Data Analysis:探索的データ分析)をしてみましょう!

データのインポート

必要なものをインポートします。

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import statsmodels.api as sm
import plotly.express as px
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline

pd.set_option('display.max_columns', None)
pd.options.display.float_format = '{:.2f}'.format

下の2行について説明します。pandasの表示設定を変更しています。

pd.set_option()の引数に、display.max_columnsNoneに設定すると、DataFrame省略せずに全て表示できるようになります。

また、pd.options.display.float_format = ‘{:.2f}’.formatとすることで、DataFrame内の小数点以下を2桁まで表示するように設定できます。

次に、ドライブをマウントしてください。

from google.colab import drive
drive.mount('/content/drive')

そして、データをインポートします。
注意‘/kaggle/Store Sales/train.csv’←の部分はドライブのフォルダ構成によって内容が異なるので注意してください。

train = pd.read_csv('/content/drive/MyDrive/kaggle/Store Sales/train.csv')
test = pd.read_csv('/content/drive/MyDrive/kaggle/Store Sales/test.csv')
stores = pd.read_csv('/content/drive/MyDrive/kaggle/Store Sales/stores.csv')
transactions = pd.read_csv('/content/drive/MyDrive/kaggle/Store Sales/transactions.csv').sort_values(['store_nbr','date'])

traintesttransactionsdateを文字列型から日付型変換します。

train['date'] = pd.to_datetime(train.date)
test['date'] = pd.to_datetime(test.date)
transactions['date'] = pd.to_datetime(transactions.date)

trainonpromotiontrainsalesstoresclusterの型を以下の( )内のものに変換します。

train.onpromotion = train.onpromotion.astype("float16")
train.sales = train.sales.astype("float32")
stores.cluster = stores.cluster.astype("int8")

EDA

transactionの中身を見てみましょう。

売上高取引高スピアマンの順位相関係数を見てみます。

スピアマンの順位相関係数とは、元の値を順位に直し、その順位を用いて相関係数を計算したものです

traindate,store_nbrをもとに売上合計算出し、これと売上高が記載されているtrainsations結合tempに格納します。

そして、temp売上合計transactions(取引高)スピアマン順位相関係数をみます。

temp = pd.merge(train.groupby(['date','store_nbr']).sales.sum().reset_index(),transactions,how='left')
print('売上高と取引高のスピアマン順位相関係数:{:,.4f}'.format(temp.corr('spearman').sales.loc['transactions']))

0.8以上あるので、かなり強い相関があります。

次に、transactions(取引高)‘store_nbr’,’date’でソートした上で、x軸にdate、Y軸にtransactions(取引高)これを、‘store_nbr’ごとに色を分けてラインチャートで見てみます。

px.line(transactions.sort_values(['store_nbr','date']),x='date',y='transactions',color='store_nbr',title='取引')

店舗売上は常に年末に増加していることがよみとれます。

次は、月毎にtransactions(取引高)箱ひげ図を見てみます。

a = transactions.copy()
a['year'] = a.date.dt.year
a['month'] = a.date.dt.month
px.box(a,x='year',y='transactions',color='month',title='月ごとの取引')

2017年を除き年末に取引高が増加していることがよみとれます。

それでは、月次平均売上高ラインチャートで見てみます。

a = transactions.set_index('date').resample('M').transactions.mean().reset_index()
a['year'] = a.date.dt.year
px.line(a,x='date',y='transactions',color='year',title='月次平均売上高')

salestransactionsの散布図を確認してみましょう。

px.scatter(temp,x='transactions',y='sales',trendline='ols',trendline_color_override='red')

前述したように、スピアマンの順位相関係数でも確認できましたが、散布図を見ても両者に高い相関があることがわかります。

次は、曜日による平均売上高ラインチャートを見てみます。

a =transactions.copy()
a['year'] = a.date.dt.year
a['dayofweek'] = a.date.dt.dayofweek+1
a = a.groupby(['year','dayofweek']).transactions.mean().reset_index()
px.line(a,x='dayofweek',y='transactions',color='year',title='曜日平均売上高')

が月曜日、が日曜日です。が一番多いので、土曜日の売上高が大きいことがわかります。

下記のブログ記事でも書きましたが、エクアドルは石油に依存している国であり、その経済的健康は石油価格のショックに対して非常に脆弱です。そこで、原油価格を見てましょう。
>>【Kaggle入門】 Store Sales – Time Series Forecasting

oil = pd.read_csv('/content/drive/MyDrive/kaggle/Store Sales/oil.csv')
oil['date'] = pd.to_datetime(oil.date)
#dcoilwticoはアメリカのテキサス州とニューメキシコ州を中心に産出される原油価格 
oil= oil.set_index('date').dcoilwtico.resample('D').sum().reset_index()
oil['dcoilwtico'] = np.where(oil['dcoilwtico']==0,np.nan,oil['dcoilwtico'])
#interpolate()は前後の値を補完したもの
oil['dcoilwtico_interpolated'] = oil.dcoilwtico.interpolate()

p= oil.melt(id_vars=['date']+list(oil.keys()[5:]),var_name='Legend')
px.line(p.sort_values(['Legend','date'],ascending=[False,True]),x='date',y='value',color='Legend',title='原油価格')

前後の値を補完した原油価格sales、transactionsのそれぞれのスピアマンの順位相関係数を見てみます。

temp = pd.merge(temp,oil,how='left')
print('原油価格とのスピアマンの順位相関係数')
print(temp.drop(['store_nbr','dcoilwtico'],axis=1).corr('spearman').dcoilwtico_interpolated.loc[['sales','transactions']],'\n')

これをみると、原油価格sales負の相関原油価格取引高ほぼ無関係ということがわかる。

そこで、散布図を見てみましょう。

fig,axes = plt.subplots(1,2,figsize=(15,5))
temp.plot.scatter(x = "dcoilwtico_interpolated", y = "transactions", ax=axes[0])
temp.plot.scatter(x = "dcoilwtico_interpolated", y = "sales", ax=axes[1], color = "r")
axes[0].set_title('Daily oil price & Transactions', fontsize = 15)
axes[1].set_title('Daily Oil Price & Sales', fontsize = 15);

原油価格取引高ほぼ無関係原油価格sales負の相関というのが散布図を見てもわかります。

次に、日次による総売上高ラインチャートを見てみます。

a = train.set_index('date').groupby('store_nbr').resample('D').sales.sum().reset_index()
px.line(a,x='date',y='sales',color='store_nbr',title='日次総売上高')

次に、製品群による次の総売上高ラインチャートを見てみましょう。

a = train.set_index('date').groupby('family').resample('D').sales.sum().reset_index()
px.line(a,x='date',y='sales',color='family',title='製品群の日次売上高')

最後に、どの商品が売れているか調べてみました。

a = train.groupby('family').sales.mean().sort_values(ascending=False).reset_index()
px.bar(a,y='family',x='sales',color='family',title='どの商品が売れているか')

Kaggleで悩んだら

「Kaggle で勝つデータ分析の技術」

データ分析の最も有名なコンペティションプラットフォームであるKaggleにおけるテクニックや事例を、現時点で最新のものを整理した書籍。特徴量の作り方バリデーションパラメータチューニングなどについて、一般的な書籍ではあまり言及されないポイント等に解説。
>>【書評】Kaggleで勝つデータ分析の技術

以下の書籍は、Kaggleを始める方には本当にオススメの書籍です。Kaggleわからないこと悩んだことがあった方は、購入を検討してみください。

本だけでは物足りないという方は、動画のプラットフォームで学ぶこともオススメです。興味がございましたら、以下の無料オンライン説明会に参加してみてはいかがでしょうか。