4th place solution
運営者様、参加者の皆様、お疲れ様でした。
4位の解法(Public7位:0.77231,Private4位:0.71864)を共有します。
ベースラインを作成するにあたって、@yuuuukiさんの公開コードを大きく参考にさせていただいていました。
name列からの特徴抽出が精度にかなり効いている印象で、NLPの処理の勉強になりました。コードを公開した参加者の皆様やコンペを開催してくださった運営者様ありがとうございました。
モデル
LightGBMのシングルモデル(Foldごとの予測結果の単純平均)
Validation
KFold(n_splits=5)
host_idでGroupKFoldしたら、LBが下がったためCVとLBは大きくずれますがKFoldで検証していました。
特徴量
特徴量としては下記の要素で作ったものをLightGBMのgainのimportance上位300のみを残して採用しました。
集約特徴
agg_feats = ['minimum_nights', 'number_of_reviews', 'reviews_per_month', 'availability_365']
key_feats = ['room_type', 'neighbourhood']
としてそれぞれの平均・分散
位置情報特徴
- 最寄駅名称
- 最寄駅までの距離
- 緯度
- 経度
- 重心からの距離
- 区ごとの重心からの距離
- 緯度経度を小数第3位までで切り捨て、グルーピング
name特徴
- どの言語か?(英語、日本語、中国語などのそれぞれの確率をfasttextで推論し追加)
- 単語数、文字数
- tfidfの結果を次元圧縮、SVD(48次元)、NMF(30次元)
- tfidfでtrainとtestで合計出現頻度が20以上の単語はそのままフラグ化
- Bert, sentenceTransformer, pipeline, universal-sentence-encoder-multilingualでそれぞれ特徴抽出したものをPCAで20次元ずつに次元圧縮
- 出現率が高そうな単語の個別フラグ
'wi-fi', 'free', 'min ', 'skytree', 'sale', '★', 'Uhome', '★Free WiFi★', '【年初特价】', 'Akihabara', 'near', 'only', 'private', 'month', 'new'
日付特徴
カテゴリのエンコーディング
- ラベルエンコーディング('neighbourhood', 'room_type', 'station_name', 'lat-lon'(緯度経度のグループ))
- カウントエンコーディング('neighbourhood', 'room_type', 'station_name', 'lat-lon'(緯度経度のグループ))
- ターゲットエンコーディング('neighbourhood'のみ)
その他の特徴量
- 経営期間(総レビュー数/1月あたりのレビュー)
df['business_period'] = df['number_of_reviews'] / df['reviews_per_month']
- 宿泊可能日数と最小宿泊日数の差
df['diff_availability'] = df['availability_365'] - df['minimum_nights']
df['div_availability'] = df['availability_365'] / df['minimum_nights']
その他
- ターゲットについては対数を取った値で学習・予測
- pseudo labelingを行うと安定してLBがよくなった
- name特徴の追加による精度向上の影響が大きかった
- 位置情報はあまり大きく影響がなかった印象
- FoldごとのCVの値の分散が大きく安定しなかった(一部の価格の高いデータの影響?)
- LightGBMのハイパーパラメータ(手動でチューニング)
"num_leaves":63,
"max_depth":-1,
"learning_rate":0.01,
"n_estimators":10000,
"subsample":0.8,
"subsample_freq":1,
"colsample_bytree":0.6,
"objective":'RMSE',
"eval_metric":'RMSE',
"early_stopping_rounds":50,
"verbose":100,