8th place solution(ルールベース)

参加者の皆様お疲れ様でした。また、運営の方々、本コンペを開催してくださりありがとうございました。

8thのソリューションを共有します。

価格データの11月と12月だけでどこまで予想できるかな、という試みです。気象データは値段に一定反映済みだろうということと、価格データも毎年似たような動きをするだろうし11月の価格からそう大きく外れることはないだろう、という仮定のもと試してみました。


処理の概要

  1. 2019/11に過去の12月/11月値段比率をかけて2019/12の値とする
  2. 野菜ごとに過去の価格推移をグラフでみて、1の方法だとうまくいかなそうな3つは、過去12月の平均値か、2019/11のままとする
  3. 外れ値をトリミング
import pandas as pd
import numpy as np
from google.colab import drive
drive.mount('/content/drive')
folder_path = [FOLDER_PATH]
  1. 2019年11月の価格に、2016と2018の12月/11月比を掛けて、2019/12を予想する。(2017は動態が微妙に異なるため除外)
train_df = pd.read_csv(folder_path + "train_data.csv")
train_df.set_index('id', inplace=True)
train_df = train_df.T
nov_dec_ratio_2016 = train_df["2016-12-01"] / train_df["2016-11-01"]
nov_dec_ratio_2018 = train_df["2018-12-01"] / train_df["2018-11-01"]
nov_dec_ratio = (nov_dec_ratio_2016 + nov_dec_ratio_2018) / 2
pred = (train_df["2019-11-01"] * nov_dec_ratio).round(0)# (参考:ここまででpublic 0.14525、private 0.16944
  1. 野菜ごとの価格推移を眺めてみて、特異な3種類の野菜だけ特別な対応をいれる(みつば:3年間の12月の平均、キャベツとにんじん:2019/11のまま)
#みつばは12月に必ず高騰する。2016-18の12月の平均値を使うことにする
dec_ave = ((train_df["2016-12-01"] + train_df["2017-12-01"] + train_df["2018-12-01"]) / 3).round(0)
combined_df = pd.concat([pred, dec_ave], axis=1, keys=['pred', 'pred_sub'])
condition = combined_df.index.str.contains('みつば')
pred = pd.Series([combined_df.loc[idx, 'pred_sub'] if cond else combined_df.loc[idx, 'pred'] for idx, cond in zip(combined_df.index, condition)], index=combined_df.index)
#キャベツは上がったり下がったりを繰り返す。12月/11月比がx0.6-0.7になってしまっているが、これはたまたま。2019/11の値のままにする
combined_df = pd.concat([train_df["2019-11-01"], pred], axis=1, keys=['nov_val', 'pred'])
condition = combined_df.index.str.contains('キャベツ')
pred = pd.Series([combined_df.loc[idx, 'nov_val'] if cond else combined_df.loc[idx, 'pred'] for idx, cond in zip(combined_df.index, condition)], index=combined_df.index)
#にんじんは直近安定しているが過去の暴騰暴落の影響で12月/11月比がx0.67。にんじんは小さい価格なので影響が大きく、あまり外したくない。直近は横ばいなので2019/11の値のままにする
combined_df = pd.concat([train_df["2019-11-01"], pred], axis=1, keys=['nov_val', 'pred'])
condition = combined_df.index.str.contains('にんじん')
pred = pd.Series([combined_df.loc[idx, 'nov_val'] if cond else combined_df.loc[idx, 'pred'] for idx, cond in zip(combined_df.index, condition)], index=combined_df.index)
  1. 過去の5%-95%の値に収まるようにトリミング(評価指標的に、大外れすると悪影響が大きいので)
min_df = train_df.min(axis=1)
max_df = train_df.max(axis=1)
diff = max_df - min_df

min_df = min_df + diff * 0.05
max_df = max_df - diff * 0.05
pred = np.where(pred < min_df, min_df, pred)
pred = np.where(pred > max_df, max_df, pred)
pred = pd.Series(pred,index=train_df.index).round(0)

submit file作成

pred_upd = pd.DataFrame(pred).reset_index()
pred_upd.columns = ["id", "y"]
pred_upd.to_csv("submit.csv", index=False) #public 0.12259、private 0.14407

添付データ

  • Aws4 request&x amz signedheaders=host&x amz signature=376a16c2550b8d9ebc396b65d3b5d2699cd1bc6f0ef086ac948dd1cac74a18e7
    tanuking0

    キャベツの処理がないほうがprivate良かったみたいです

    Favicon
    new user
    コメントするには 新規登録 もしくは ログイン が必要です。