野菜価格に影響する要因を探り当てよう!
Akahachi
from google.colab import files # 必要ファイルをzip圧縮したファイルをアップロードします files.upload() ! unzip ps_yasai.zip
Saving ps_yasai.zip to ps_yasai.zip Archive: ps_yasai.zip inflating: ps_yasai/submission.csv inflating: ps_yasai/train_data.csv inflating: ps_yasai/weather.csv
import warnings warnings.simplefilter('ignore') from IPython.display import display, clear_output import pandas as pd import numpy as np %matplotlib inline import matplotlib.pyplot as plt !pip install --q japanize-matplotlib import japanize_matplotlib import seaborn as sns sns.set(font="IPAexGothic") from sklearn.metrics import mean_squared_error clear_output()
train = pd.read_csv('ps_yasai/train_data.csv').rename(columns={'id':'date'}).set_index('date', drop=True) # id(日付)をindexにします sub_df = pd.read_csv('ps_yasai/submission.csv')
trainデータに欠損値はありません
train.isnull().sum().max()
0
trainデータの列数(=品目×地域)は340、品目は42種類あります
items = list(dict.fromkeys([c.split('_')[0] for c in train.columns])) train.shape[1], len(items)
(340, 42)
def plot_prices(item_list): nrow = len(item_list) fig, ax = plt.subplots(nrow, sharex=True, figsize=(8, nrow*3)) for i, item in enumerate(item_list): area_item = [c for c in train.columns if c.split('_')[0]==item] ymax = 0 for c in area_item: train[c].plot(ax=ax[i]) if train[c].max()>ymax: ymax = train[c].max() ax[i].legend(loc='center left', bbox_to_anchor=(1., .5)) ax[i].set_ylim((0, 1.1*ymax))
品目・地域ごとにバラバラに動いているのではなく、同じ品目であれば地域間である程度の連動性がありそうです。また、品目により価格に周期性がありそうです。
plot_prices(items[:4])
とはいえ、連動性・周期性は品目によりその「強さ」に違いがありそうです。
きゅうり、れんこんは連動性・周期性が強そうな品目、その他の菜類、ねぎは弱そうな品目の例です。(注) 品目数が結構多いので、一部だけを抜粋して表示します
item_list = ['きゅうり','れんこん','その他の菜類', 'ねぎ'] plot_prices(item_list)
各月の価格の幾何平均を予測値とした場合について調べます
# 評価指標がRMLSEであるため、元データを対数変換します df0 = np.log(train) date = pd.to_datetime(train.index) df0['year'] = date.year df0['month'] = date.month
display(df0.head())
5 rows × 342 columns
# Leave One Out loo = pd.DataFrame(np.zeros_like(train), index=train.index, columns=train.columns) for i in loo.index: year = df0.at[i, 'year'] month = df0.at[i, 'month'] # 例えば2016年1月の「えのきだけ_中国」は2016年以外の1月の「えのきだけ_中国」の幾何平均値を予測値とします for c in loo.columns: loo.at[i, c] = df0.loc[(df0['year']!=year) & (df0['month']==month), c].mean() # 各「品目_地域」に対してRMSLEを計算し、その平均値を算出 tot_rmlse = 0 for c in loo.columns: tot_rmlse += np.sqrt(mean_squared_error(df0[c], loo[c])) / train.shape[1] print(f"RMLSE train data: {tot_rmlse:.5f}")
RMLSE train data: 0.22453
# 各「品目_地域」の12月の幾何平均を予測値とします monthly_mean_dic = np.exp(df0[df0['month']==12][train.columns].mean()).to_dict() sub_df['y'] = sub_df['id'].map(monthly_mean_dic)
sub_df.head()
# LB: 0.27182 sub_df.to_csv('sub5.csv', index=False)
月ごとの価格の幾何平均でまずまずの精度が得られました。今回のコンペにおいて、周期性(月ごとの影響)がそれなりに意味を持つことが示されたと思います。