Kiva/クラウドファンディングの資金調達額予測

マルチモーダルコンペティション!Ridgelinezとの共同開催です

賞金: 200,000 参加ユーザー数: 231 3年弱前に終了
スポンサー
Ridgelinez株式会社

3rd Place Solution

参加者の皆様,お疲れさまでした.
運営の方,トピック公開してくださった方々,ありがとうございました.大変勉強になりました.

3位の解法です.遅くなってしまってすみません.
自然言語のデータを扱うコンペは初めてでいろいろと調べながらコードを書いていました.
普通はこういう手法を使うんだよ,などありましたらぜひ教えて下さい.

コード

https://github.com/nakayama-r/Probspace-kiva-3rd

特徴量
  • 生データ
    • ORIGINAL_LANGUAGE
    • ACTIVITY_NAME
    • SECTOR_NAME
    • COUNTRY_NAME
    • CURRENCY
    • REPAYMENT_INTERVAL
    • DISTRIBUTION_MODEL
  • 生データの組み合わせ特徴
    • COUNTRY+CURRENCY
    • TOWN_NAME+COUNTRY_NAME
    • CURRENCY_POLICY+CURRENCY_EXCHANGE_COVERAGE_RATE+CURRENCY
      など
  • TAGSのOneHot化
  • DESCRIPTION_TRANSLATEDを特徴ベクトル化
    • https://zenn.dev/koukyo1994/articles/9b1da2482d8ba1 を参考にしました.
    • BM25によるベクトル化→SVDで50次元に圧縮
    • GloVeで単語ベクトルを取得→SWEMで文章ベクトル化
    • Universal Sentence Encoderによる文章ベクトル
  • 希望金額
    DESCRIPTION_TRANSLATEDに希望金額が記載されている場合があり,たいていはその希望金額通りに融資が行われているようです.
    最初はDESCRIPTION_TRANSLATEDに記載されている数字で一番大きいものを希望金額として抽出していました.
    これでも大幅に精度は改善したのですが,収入額や年齢,購入予定の品物の個数などを抽出してしまっているものも多くあったので以下のようにもう少し丁寧にやることにしました.

    1. DESCRIPTION_TRANSLATEDから数字が入っているsentenceだけを取り出し抽出候補とする.
    2. CURRENCYごとに希望金額が書かれたsentenceの一例(PHPなら"requested a PHP 25,000 loan through NWTF to purchase")を決めておき,候補のsentenceとのcosine類似度をUniversal Sentence Encoderの文章ベクトルから算出する.
    3. 類似度がしきい値よりも大きかったsentenceに書かれた数値を希望金額として抽出する.

      あとは,学習データでLOAN_AMOUNTと希望金額の対応関係からUSDとの交換レートを求めてCURRENCYごとに中央値を取り,最終的な通貨交換レートとしました.
      またその交換レートを使って希望金額をUSDに変換した値も特徴としました.
      類似度のしきい値はかなりいいかげんにCURRENCYごとに0.2~0.4くらいにしています.
      こんなことをして交換レートを求めなくても公開されている情報使ったほうが正確じゃないかなと思ってトピックで質問しましたが外部データは利用不可でした.
      (融資を募っている期間中にレートが上下してしまうので予測に使ってほしくない,とかでしょうか.)  

  • 類似文章のLOAN_AMOUNT

    1. 各CURRENCYごとにDESCRIPTION_TRANSLATEDのUniversal Sentence Encoderによる文章ベクトルを取得し自分とそれ以外の文章とのcosine類似度を算出
    2. 学習データでは,類似度の大きい順に5つの文章を選びその中からランダムに1つ選んでその文章のLOAN_AMOUNTを特徴に追加
    3. テストデータでは,類似度の大きい5つの文章のLOAN_AMOUNTをそれぞれ追加して予測し,5つの予測値のmedianを最終的な予測とする.(Test Time Augmentationみたいなものです.)

      CURRENCYの他に,同一のACTIVITY_NAME,CURRENCY_POLICY+CURRENCY_EXCHANGE_COVERAGE_RATE+CURRENCY特徴でも同じ手順で類似文章のLOAN_AMOUNTを追加しました.
      元ネタはhttps://www.kaggle.com/c/ventilator-pressure-prediction/discussion/285282

CV
  • CURRENCYでStratifiedKFold
  • 5 Folds
    • CVとLBの乖離が激しすぎてあまりうまくいった印象がないです.
モデル

以下の5つのモデルを最終的なaveragingに利用しました.

LigihtGBM
- 使用した特徴量 :上記の全て
- Loss : Psuedo-Huber Loss
単純なNeural Net
- 使用した特徴量 :生データ,TAGSのOneHot化,CLIPによる画像特徴,希望金額,類似文章のLOAN_AMOUNT
- カテゴリ変数はすべてTarget Encordingしました.
- Loss : Psuedo-Huber Loss

以下のBERT系列のモデルは全てDESCRIPTION_TRANSLATEDを入力し,その出力にその他の特徴をconcatして予測Headに入力しています.

BART
- https://huggingface.co/facebook/bart-base
- 使用した特徴量 :DESCRIPTION_TRANSLATED
- Loss : L1 Loss
- encoderの最終層以外は重みを固定してfinetuning
BERT
- https://huggingface.co/bert-base-cased
- 回帰ではなくLOAN_AMOUNTの金額を400クラスに分割して分類問題として予測
- 使用した特徴量 :生データ,TAGSのOneHot化,CLIPによる画像特徴,希望金額,類似文章のLOAN_AMOUNT
- Loss : focal Loss
- 最終3層以外は重みを固定してfinetuning
- 各層のCLSトークンをConcatenateして予測Headに入力
Distlibert
- https://huggingface.co/distilbert-base-cased
- 使用した特徴量 :生データ,TAGSのOneHot化,CLIPによる画像特徴,希望金額,類似文章のLOAN_AMOUNT
- Loss : Psuedo-Huber Loss
- 最終層以外は重みを固定してfinetuning
- 各層のCLSトークンをConcatenateして予測Headに入力
averaging

上記5つのモデルを加重平均したもので,CV:191.671867,Public:250.08713, Private:246.06379でした.



最後の方は希望金額をさらに正確に抽出しようと時間を使っていたのですが,単純に抽出する以上の精度にはなりませんでした. (そもそもこの希望金額を機械学習で良い感じに決めるためのコンペのような気もするので実際は使えない特徴かもしれません...)

画像は使う予定はなかったのですが最終日試したCLIPの特徴でCVが大幅に改善しました.
蓋を開けてみると学習データにoverfitした様子でしたがaveragingの際の多様性には寄与していたようです.

Aws4 request&x amz signedheaders=host&x amz signature=c157e4ade08f0c27562a1e52d1c8cf28c3b4c17407fd69fe5aa8b9670a33595d
ProbSpace_official

bananabanana様

3rd Place solutionの公開、ありがとうございました。 オープンレビュー期間については、2/27までと設定させていただきます。

どうぞよろしくお願いいたします。

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