Kaggle Google Quest Q&A Labeling参加録

www.kaggle.com

タスク説明

f:id:bluexleoxgreen:20200211160142p:plain

  • QAサイトの質問文と解答文(+メタデータ)から質問・解答の点数を予測する
  • 採点項目は全部で30項目ある
  • 質問の形式に関するもの、質問になっていない、解答の妥当性など
  • 元のQAデータはおそらくこれ
  • 評価指標はスピアマンの順位相関係数

解法とコンペ中の動き

  • 結構早い段階でbert-baseの強いnotebookが出たので、これをベースに進めた Bert-base TF2.0 (now Huggingface transformer) | Kaggle
  • 一部の採点項目の点数が偏りすぎてルールベースで点数を決定するとスコアが伸びるという話がどこかにあった
  • それに関するdiscussionnotebookを投稿した
  • カテゴリ、ホストによって点数の分布が違うので、それらに関するfeatureを入れたモデルを作った

  • 最終的に提出したのは以下のモデルのアンサンブル

    • bert-base (TF hub) 5epoch学習、2、3、4epoch目のモデル
    • bert-large (TF hub) 5epoch学習、best epochのモデル
    • feature+distilbertのembeddingを使ったモデル
      • カテゴリ、ホストのfeatureはそれぞれの点数に対してtarget-encoding
  • 質問文に重複があるのでCVはGroupMultilabelStratifiedKFoldを使用

    • 同じ質問文のものを集約し、点数はそれらの平均値で置き換える
    • Neuron Engineerさんのありがたいml-stratifiersのMultilabelStratifiedKfoldに突っ込む
    • 集約したものを元に戻す
  • 重みの調整

    • 各モデル・foldの重みはspearmanrを最小化するようにした
    • この時、順位に関する情報が失われないようにscipyのrankdataで順位に置き換えて正規化した
  • 後処理

    • 点数に偏り(同順位)が多数あるので、spearmanrが最も高くなるように丸めた
  • 最終順位

    • Public Leaderboard 91st (Bronze)
    • Private Leaderboard 65th (Silver)

今回のコンペで覚えたtips

  • コンペ序盤は提出エラーが信じられないほど発生したので試行錯誤した f:id:bluexleoxgreen:20200211164423j:plain
  • 今回の評価指標の制約
    • 0<x<1の値を予測しないといけない
    • 列が全て同じ数値だとnanになってしまうのでエラーが出る

publicだけ予測する

  • これはnotebook onlyのあらゆるコンペで使える
  • privateの予測でエラーが出ているようだったので、しばらくはpublicのtestデータだけ予測した
  • 公開されているtest.csvのqa_idのデータだけ予測して残りを乱数で埋める
  • 遅そうだが以下でいける
sample = pd.read_csv("../input/google-quest-challenge/sample_submission.csv")
submission = pd.read_csv("../input/public_inf/submission.csv")
sub = pd.merge(sample["qa_id"], submission, on="qa_id", how='outer')
sub = sub.fillna(0)

for i in range(len(sub)):
    if int(sub.iloc[i].qa_id) not in set(submission["qa_id"].values):
        sub.iloc[i, 1:] = sub.iloc[i, 1:].apply(lambda x: random.random())
sub.to_csv("submission.csv", index=False)

推論のpythonファイルを切り出す

  • TF2.0のモデルをGPUに載せるとGPUメモリから消せなくなるバグ(?)があるようなので切り出した
  • multiprocessing使ったりimport cudaする方法も試したがうまく行かなかったので最終的にはこれで解決した
  • notebook内で! python inf.pyみたいにすれば良い

提出のデバッグ

  • 普通は提出した時のエラーがどこで発生しているのかわからない
  • 各セルの最後に! touch Aのようにファイルを生成しておき、提出ファイルを作る時に適当に公開notebookから持ってきたpublic testの予測値をsubmission.csvに突っ込むとどのセルでエラーが出て止まっているかわかる

datasetの20GB上限突破

  • datasetにアップロードできるモデルの上限は1ユーザにつき20GB
  • Bert baseだと1モデルで1.3GB、largeだと4GBなのでソロで5foldのモデルをアップロードするのは厳しい
  • notebookのoutputを利用すれば上限を突破できる
  • 1度datasetにアップロード→notebook内でcopyしてoutputに追加→datasetを削除
  • ただしnotebookの容量上限5GBがあるので、大きいデータは分割して出力する必要がある