(2016/9/20 追記)
先ほど、入賞者が公表されました!
売上予測部門<最高予測精度賞>
moemoeと遊び隊様
売上予測部門<モデリングアイデア賞>
nami3373様
新商品開発部門<ローソン賞>
いっしー様
新商品開発部門<データパティシエ賞>
0pus0ne様
上記の皆様、入賞おめでとうございます!
え、自分? つ、次頑張りますよ次…
-以降は売上予測部門のモデル提出期限直後の内容になります-
お疲れ様でした!
興奮冷めやらぬままに本記事を書いているのですが、
二ヶ月弱に及ぶ長い激闘の果てに、先日DeepAnalyticsのThe 2nd Big Data Analysis Contestが締め切られました。
発表されたてホヤホヤですが、上位を競っていた方がprivateの方で大きく順位を落としたりと、最後まで波乱含みの展開だったと思います。
1位を獲得されたdeeshiさんおめでとうございます!
ちなみに私は138人中1位(public)→4位(private)でした.
Scikit-learn初心者のコンペ初挑戦で、ラスト2週間ほどは1位を死守しながらもハラハラドキドキしつつ見守っていたので、とても感慨深いものがあります。
(まぁ本音のトコロは「これこのままなら1位狙えるやろ!」って期待してたんですが)
さて,本記事では特徴と手法、なぜ1位をひた走れたかついて、備忘録も兼ねてサクッと紹介したいと思います.
本体
github
"Data"フォルダ内に不足データを追加して、プログラムを動かすと、推定を行った後に月次推定の結果を表示させます。
また、"Data"内に4thtest.csv(テストデータに対する推定)、4thtrain.tsv(トレーニングデータに対する推定)が作成されます。
特徴とその選択
提供データ
具体的な内容は割愛しますが、IDや商品名、アピールポイントなど商品特有のデータを除く商品データとトレーニングデータのほぼ全てを利用しています。
(一部のデータは尺度が混在していたり、名義尺度になっていたため、前処理としてベクトルに直しています)
日付に関しては特別に、下記の特徴に直しました。
「開始月から何番目の月か」
「開始年から何番目の年か」
「春夏秋冬のどの季節か(4次元ベクトル)」
月に関しては単に『何月か』という情報を与えても1年分しかないトレーニングデータ内の検証ではあまり変わらないのですが、「6(月)」という情報がダブるテストデータの方で大きな差が生まれることを確認したため、何月かではなくあえて開始月から何番目の月かという情報を与えています。
追加データ
上記の提供データに加えて、下記のデータを追加しました。
地域別の収入 (2015)
(平均年収ランキング2015)
(平成27年度地域別最低賃金改定状況)
「平均年収」
「平均最低賃金」
地域を代表する主要都市の天候情報 (月次、2005-2015の10年平均)
(気象庁|過去の気象データ検索)
「平均降水量」
「平均最深積雪量」
「平均風速」
「平均雲量」
「平均雪日数」
「平均雷日数」
「平均気温」
「地域別の収入と天気を使うと良い」という話はRossman Store Salesコンペの報告にもあったので、採用していた方は多かったのではないでしょうか。
特徴選択
特徴選択にはfeature_importances_による可視化とbackward stepwise selectionを利用しました。
例えば当初は主要都市の天候情報について「平均日照時間」を含めていたのですが、feature_importances_で「平均雲量」などの他の天候情報との干渉が確認でき、backward stepwise selectionの中でも取り除くことでスコアが上がることを確認したため、最終的な特徴としては採用していません。
推定方法
みんな大好きXGBoostのXGBRegressorを利用しました。
数値操作やt-SNEなどの次元削減手法は行わず、そのまま生の特徴だけを利用しています。
またStackingも検討しましたが、見送っています。
ハイパーパラメータが多いXGBoostのチューニングはベイズ推定手法としてhyperoptがよく用いられます。
これは自前の中スペックPC(¥100,000)の処理能力では少し心もとなく困っていたのですが、代わりにそれでも十分検証できる素晴らしいグリッドサーチ手順が紹介されていたので、今回はこの手順のままにハイパーパラメータをチューニングすることができました。
こんなフツーの手法とフツーの特徴でなんで終了直前まで1位だったの?
そもそも今回のコンペでは提供データが非常に優秀でした。
実は提供データのみでもRandomForestRegressorでスコア0.156(public)が出たりします。
(実際、最初はコレで1位に立ちました)
終了時の最高スコアが0.152(public)だったことを踏まえれば、この数値は驚異的です。
下手に特徴を追加したりハイパーパラメータを設定すると、かえってスコアが下がってしまう…。
今回のコンペはいかに有効な特徴を選択しチューニングするかという勝負だったのではないかと思います。
そんな中で自分が1位をひた走れたのは、『大体月次推定になるやろ』とデータを月順に並べ替えデータを12等分し、12-Fold cross validationを行った際の横着スコアが、投げてみるとpublicスコアにある程度連動していることを発見し、効率的に特徴選択とチューニングを行えたことが一番の理由だと考えています。
(※ マトモなコンペ参加者さんはマネしないでください)
実際には新商品の都合で商品数が月ごとに異なるため、これでは厳密な月次の推定とはなりません。
しかし、その若干のゆらぎが、1月丸々にも関わらず高い精度の売上予測を可能にし、ひいては順位をそれほど落とすことのないほどに汎化性能を上げてくれていたのだと思います。
一方よくあるタイプのものでは①ランダムに並び替えてK-Fold、②月次推定、③最終月をテストデータに、④(最終月の1つ前+最終月)をテストデータにあたりでは精度を上げることが出来ませんでした。
結局の所、どのデータを信用するかでスコアが大きく変わってきたのではないかと思います。
(自分自身も最終的には横着スコアに頼りすぎて、やや過学習気味になってしまったのがツラい所)
最後に
機械学習コンペティションへの本格的な参戦は初めてだったのですが、非常に勉強になりました。
当初はRandomForestClassifierでベンチマーク切りする椿事も引き起こしましたが、
様々な手法の活用や試行錯誤の果てに、納得行く成績を残すことが出来たと思います。
また、今まであまり対面してこなかった、関数の機能性やオブジェクト設計の大切さを身に沁みて学ぶことが出来ました。
今回ほどの結果を残せるかはわかりませんが、これから開催される機械学習コンペにも、今回学べたことを活かし「折々で参加していければいいな」と考えています。
(※ 努力の果てにStackingしようとした痕跡。プログラム自体も累計で1万行は書いてたり)
さて、売上の予測は終わりましたが、The 2nd Big Data Analysis Contestはまだまだ続きます。
売上予測部門に関しては既にサクラサク話が届いていることと思いますが、新商品開発部門は厳正な審査が続きます。
私もからあげクン1年分欲しさに新商品開発部門にレポートを提出しているので、首を長くして待ちたいと思います。
末筆になりましたが現在、同じくDeepAnalyticsで開催中のコンペ人工知能は名刺をどこまで解読できるのか?!にも参加しております。
激闘を戦い抜いて本記事にたどり着いた方も、なんかよく分かんなかったけど面白そうだと思った方も、一緒に戦ってみませんか?