初めてデータコンペに参加してできるようになったこと・できなかったこと

初めてデータコンペに参加してきたので、そのことをまとめていきたいと思います。

コンペには以前から興味はあったのですが、Kaggleに登録して一からモデルを作るのは自分としては敷居が高くなかなか1サブができていない状況でした。ですが今回はsignateで学生限定のコンペが始まったこと、また、インドにいるため比較的自由な時間が多いことがきっかけとなりついにコンペへ参加し最後まで取り組むことができました。

コンペの概要

参加したコンペは「マイナビ × SIGNATE Student Cup 2019: 賃貸物件の家賃予測」で所在地や間取り、築年数などをヒントに、東京23区における賃貸物件の家賃予測を行うというものでした。

signate.jp

 

できるようになったこと・やったこと

初めてデータサイエンスコンペに参加してできるようになったこと・実際にやったことを以下にまとめていきます。ところどころ覚書としてコードや補足も書いていきます。

EDA

賃料との相関や外れ値の確認をした。欠損値の割合の算出、賃料の対数変換など。

特徴量作成

具体的には以下のことをした。

・2乗系

・平均値で引き算・割り算

・他の変数との掛け算(◯◯×△△)

・count系

・切り捨て・切り上げ

・数値データのカテゴリカル化

・バス、車、徒歩の時間の統一

・PCA

・欠損値かどうかのダミー変数

・南向きかどうか、高層階かどうかのフラグ

このブログが神だった。 

naotaka1128.hatenadiary.jp

この特徴量も結構効いた。

qiita.com

正規表現

与えらるデータが汚すぎて前処理が辛かった。

accsess="山陽本線\t岡山駅\t徒歩8分\t\t山手線\t東京駅\t徒歩17分"

print(re.findall(r"\d{1,2}分", accsess ))
print(re.findall(r"\D{1,3}線", accsess ))
>['8分', '17分']
>['山陽本線', '\t山手線']
こんな感じで切り取った。\tはreplace使って置換した、、。正規表現はまだまだ勉強が必要だと感じた。

 グループごとに平均を取ってfillna

df.groupby('区')["当年価格(円)"].transform(lambda x:x.fillna(x.mean()))

 結局LightGBMしか使わなかったから欠損処理はしなかったけど、地価データの欠損値を区でgroupbyして平均で埋めるのができるようになった。

LightGBMのパラメータをoptunaで最適化

以下のサイトを参考にした。どのパラメータがどういう役割かは結構勉強になった。

 

lightgbm.readthedocs.io

クロスバリデーション

 以下のサイトを参考。

upura.hatenablog.com

Adversarial Validation

CV平均スコアは1.4万出るのにLBで3万とか出たから、trainデータとtestデータで違いがあるんじゃないかと疑いAdversarial Validationやろうとした。精度50%で全く分類できなかったから分布に違いはないと結論づけた。

upura.hatenablog.com

アンサンブル

特徴量が違うモデル・パラメータが違うモデル・CVで分割したモデルなど色々混ぜた。

 

できなかったこと

精度向上

5分割のクロスバリデーションして平均スコアが1.4万出たのに、LBでは3万とか出たからずっと???っていう状況だった。目的変数(賃料)を特徴量に入れてないのにこんなにLBが低かったのが未だにわからない。どなたか教えてください。

f:id:nori0724:20191108163113p:plain

同一物件の穴埋め

住所・間取り・面積・居住階・最高階・家賃が一致するデータが計2000件弱存在してたらしい。データを良く見れてなかったから気づけなかった。

group kfold

上記に気付ければ重複したレコードがleakしないように同じfoldに入れるgroup kfoldができたらしい。group kfold はまだ理解してないから勉強したい。

ユニークな特徴量の追加

緯度経度のスクレイピングが時間もお金もかかるということでやらなかったが

住所→緯度経度→〇〇からの距離を算出

住所→緯度経度→航空写真から画像を抽出

などは思いつかなかった。

空間的な可視化

与えられた住所を緯度経度に変換して、地図上に賃料をplotすると空間的に賃料の高低を把握できたのではないかと今考えた。

その他モデルを試す

LightGBM以外をやる必要があるかは知らないが試そうとする試みはあっても良かったかも。一位のチームはCatBoostを使ってたとか。

 ※その他できなかったことは上位解法が公開され次第随時追記していきます。

振り返り

結果としては最終スコア17292で366チーム中88位でした。学生限定コンペなのでもう少し上に行きたかったなぁ・・・というのが正直なところです。CVスコアとLBスコアの差が解決せずLightGBMのお気持ちは最後まで理解できませんでした。結局一番精度が良かったのはコンペ始まって4回目に提出したモデルでした。残念。

f:id:nori0724:20191108165633p:plain

 

しかし、このコンペに参加することで多くの収穫がありました。簡単に精度が上がらなかったからこそ多くのブログを読み、Kaggleで使える知見はかなり溜まったのではないかと思います。今まで入るだけ入って一切開いていなかったKaggler Slackのbeginners-helpチャンネルも大変役に立ちました。このチャンネルからはインターンで使えるLSTMのtipsも手に入れれたので今後は毎日チェックしていきたいところです。

yutori-datascience.hatenablog.com

 初めてのコンペ参加になりましたがかなりの収穫があり参加して良かったです。マイナビコンペで思う結果が出せず結構悔しいので次はKaggleで頑張ります。

楽しいコンペでした!お疲れ様でした!

 

その他参考サイト

signate.jp


upura.hatenablog.com

employment.en-japan.com

www.slideshare.net