1st Place Solution

ProbSpace運営の方々、本コンペを開催していただき、誠にありがとうございました。 また、共にご参加していた参加者の皆様も対戦ありがとうございました。最後までハラハラドキドキしながらコンペに取り組むことができ、とても楽しかったです。

使用したデータ

モデリング:citesありのデータ
特徴量:集約でcitesなしのデータも使いました。text系の情報(title、abstract)もcitesなしのデータ含めて分散表現に変えてPCAをかけていました。

モデル

LightGBM×7のensemble(seed=42、pseudo labeling、seed averagingなし)

  • 6つは目的変数をnp.log1p(cites) - np.log1p(doi_cites)に変換して学習。  6つのモデルの違いは1〜6で共通(一部CVを見て変更した)特徴量セットにそれぞれ以下のものを追加したモデル。
    • title、abstractのword2vecをそれぞれPCAで20次元に次元削減
    • title、abstractのword2vec×tfidfをそれぞれPCAで20次元に次元削減
    • title、abstractのscdvをそれぞれPCAで20次元に次元削減
    • title、abstractのfasttextをそれぞれPCAで20次元に次元削減
    • title、abstractのscibertをそれぞれPCAで20次元に次元削減(ただし、citesありのtrainデータとtestデータのみを使ってPCA)
    • title、abstractの「scibertのCLSトークンとSEPトークンを除外した単語のベクトルの平均」をそれぞれPCAで20次元に次元削減(ただし、citesありのtrainデータとtestデータのみを使ってPCA)

5番目、6番目については https://prob.space/topics/columbia2131-Post0cf3bc9feaa1640eee20 を参考にさせていただきました。  

  • 1つは目的変数をnp.log1p(cites)のまま学習。
    • title、abstractのword2vecをそれぞれPCAで20次元に次元削減  に特徴量セットを加えたものを説明変数としました。

モデルのベースはszdrさんのhttps://prob.space/topics/szdr-Post03b9586ec09ee194e133 と https://prob.space/topics/szdr-Post716eef35860ab4e936eb を参考にさせていただきました。

テキストデータの前処理

textheroを用いました。

custom_pipeline = [preprocessing.fillna
         ,preprocessing.lowercase
         ,preprocessing.remove_digits
         ,preprocessing.remove_punctuation
         ,preprocessing.remove_diacritics
         ,preprocessing.remove_whitespace
         ,preprocessing.remove_stopwords]

の7つの処理を入れました。

特徴量について

各モデル120前後の特徴量です。全て書くと煩雑になるので、特に効いた特徴量について以下にまとめます。

  • textデータ
    • title、abstractのword2vecをそれぞれPCAで20次元に次元削減
    • title、abstractのword2vec×tfidfをそれぞれPCAで20次元に次元削減
    • title、abstractのscdvをそれぞれPCAで20次元に次元削減
    • title、abstractのfasttextをそれぞれPCAで20次元に次元削減
      word2vecやfasttextは学習済みモデルではなく、citesなし含めた全データでスクラッチで学習させたものを使いました。
    • title、abstractのscibertをそれぞれPCAで20次元に次元削減
    • title、abstractの「scibertのCLSトークンとSEPトークンを除外した単語のベクトルの平均」をそれぞれPCAで20次元に次元削減
    • abstractのtfidfにkmeansをかけたもの(n_clusters=20)
  • categoryデータ
    • 著者ごとにdoi_citesをスコア化
      • authors_parsedとdoi_citesを利用して著者ごとのdoi_citesのカウント、平均、分散、最大値を算出し、それを基に複数著者のdoi_citesの合計、平均、分散、最大値を出し、行に当てはめる。
    • categoryごとにdoi_citesをスコア化
      • categoriesとdoi_citesを利用してcategoryごとのdoi_citesのカウント、平均、分散、最大値を算出し、それを基にcategoriesのdoi_citesの合計、平均、分散、最大値を出し、行に当てはめる。
    • report-noがnullかどうか
    • 以下のトピックhttps://prob.space/competitions/citation_prediction/discussions/pn11-Postbc1b4fff9039ae354198 の中のhttps://gist.github.com/TomDemeranville/8699224 の「doi-prefix-publishers.csv」を見てdoiからひとつめの/以前の部分を取り出し(例:10.1088/0954-3899/25/7/332 なら10.1088を取り出し)、journalという変数としてcount encodingやtarget encoding、集約を行なった。
    • categoriesの最初のカテゴリーをfirst_categoryとし、そのtarget encoding。
  • 数値データ
    • doi_cites
    • commentsから表の数やページ数を算出。
    • versionsから時刻特徴量
      • 論文が投稿された時刻
      • 論文が最後に更新された時刻
      • 最後の更新と投稿された時刻の差分
      • 論文が何回更新されたか
    • update_dateから年、月の情報
    • doi_cites / 論文が投稿された時刻 などdoi_citesと効いている数値変数の割り算

CV

どのモデルもcitesでStratifiedKFold(n_splits=5、seed=42)です。

効かなかったこと

  • Tabnet、Catboost、RandomForestなど他のモデル全般
  • doi_citesをauthorsで集約した変数(複数著者のまま集約するとカーディナリティが高すぎてうまくいかなかったのだと思います)
  • doi_citesをcategoriesで集約した変数
  • first_categoryとjournal以外のtarget encoding
  • submitter情報(どう入れても下がりました...)
  • commentsをword2vecなどで分散表現にしたもの

などです。

コード

https://github.com/Pirototo/ProbSpace-citation_prediction-1st-solution

最後に

今回の自分の中での鍵はnp.log1p(cites) - np.log1p(doi_cites)と目的変数を差分に変換できるかどうかでした。
これによりCVが0.491→0.486まで上昇することができました。
正直他の特徴量は皆さんの方が作り込んでいると思っております。

繰り返しになりますが、本コンペを開催していただきまして誠にありがとうございました。  

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