ギークなエンジニアを目指す男

機械学習系の知識を蓄えようとするブログ

ProbSpace「YouTube動画視聴回数予測コンペ」参加メモ 〜MLflow Trackingによる実験管理を添えて〜

f:id:taxa_program:20200705095550p:plain:w800

こんにちは。takapy(@takapy0210)です。

今回はProbSpaceで開催されていた「YouTube動画視聴回数予測」コンペに参加し、その中でMLflow Trackingで実験管理を行ってみましたので、簡単に振り返りをしようと思います。

ちなみに結果はPrublic 13th → Private 10thでした。

prob.space

コンペの概要

YouTube APIとして公開されているメタデータを用いて動画の視聴回数を予測する、というものでした。

データには

  • 動画コンテンツの質的指標となるlike/dislike・コメント数
  • SEOとして重要とされているタイトル名・説明文・タグ・投稿時間

といった情報が含まれており、いわゆる"マルチモーダル"なデータセットで、かつ身近なサービスのデータということもあり、分析していてとても楽しかったです。

評価指標はRMSLE(Root Mean Squared Log Error)でした。

開催直後に1subだけしたものの、その後あまり参加できず、最後の10日間くらいでフルコミットしました。

Solution

簡単にSolutionをまとめておきます。

モデルはLightGBM / Catboostを試しましたが、自分の環境ではLightGBMの方がスコアが良かった(CV / LB共に)ため、最終的にはLightGBM * 5モデルを用いました。

詳細はコードを公開しましたので、こちらを参照ください。

github.com

特徴量

日付

  • 年, 月, 日に変換
  • 曜日, 週末
  • それぞれを三角関数を通して変換
  • データ収集日と動画公開日の差分
  • 1日あたりのlike数 / dislike数 / comment数

など

テキスト(主にtitle, description, tags)

  • 文字列の長さ
  • BERT*1とTF-IDF*2で埋め込み→UMAP*3(10dim)& t-SNE*4(2dim)で圧縮
  • musicnurseryなどの特定ワードが含まれているか

など

BERTを用いてテキストの埋め込みを取得する方法は下記を参照にしました。

kaeru-nantoka.hatenablog.com

集計特徴量

  • カテゴリごと
  • 動画公開日の「年, 月」ごと
  • 動画公開日からデータ収集日までの月数をbin分割したものごと

に sum, mean, std, ,max, min, meanと自身との差分を算出

など

CV

  • KFold(k=5)

ここはもっと工夫の余地があったと思います。反省。

その他の工夫

自分の環境では、特徴量を増減させることでカテゴリごとのスコアがかなり変動しました。
そこで、LBのスコアが同等で使用した特徴量が異なる5つのモデルの中から、カテゴリごとに一番良いスコアを出しているモデルを選択し、そのカテゴリの予測値は選択したモデルの予測値を用いる、ということをしました。

結果的にはこれが一番スコアが良かったです。

カテゴリ毎にスコアを出して、それぞれベストなモデルを選択する、といった部分では後述するMLflow Trackingを用いることで比較的低コストで行うことができました。

comments_disabled, ratings_disabledそれぞれのコメント数やlikes/dislikesを予測して欠損値補完する、といった工夫は他の参加者の方も結構やっていたのですが、自分の頭からはすっかり抜け落ちていました。。。

MLflow Trackingによる実験管理

以降で簡単に MLflow*5の使用感などをお伝えします。

使用するにあたり、以下を参考にしました。

upura.hatenablog.com

MLflowによる機械学習モデルのライフサイクルの管理

また、Podcastでも使用感などを話しましたので、よければ聞いてみてください。

anchor.fm

ML flowとは

機械学習ライフサイクル(実験・再現・デプロイ)を支援するためのオープンソースプラットフォームであり、大別して以下3点の機能があります。

  • MLflow Tracking
    • 実験周りのコードや設定・結果の記録
  • MLflow Projects
    • どこでも再現できるようにするためのパッケージング
  • MLflow Models
    • モデルを各環境にデプロイするための方法やフォーマット

クイックスタート

公式のサンプル*6を動かしてみるのが一番手っ取り早いと思います。

以下で公式サンプルを少し改変したコードで簡単にみていきます。
pipでインストール後以下のようなサンプルコードを作成しこれを実行します。

実験のログを残す箇所は

  • log_param
  • log_metric
  • log_artifact
  • set_tag

あたりです。

import mlflow
from mlflow import log_metric, log_param, log_artifact, set_tag

if __name__ == "__main__":

    tracking_uri = '~/mlflow/mlruns'
    mlflow.set_tracking_uri(tracking_uri)
    mlflow.set_experiment("test-experiment")
    mlflow.start_run(run_name='run_name001')

    # Log a parameter (key-value pair)
    log_param('param1', 42)

    # Log a metric; metrics can be updated throughout the run
    log_metric('fold1_score', 9.99)
    log_metric('fold2_score', 9.92)
    log_metric('fold3_score', 9.78)

    # Log an artifact (output file)
    with open("output.txt", "w") as f:
        f.write("Hello world sample!")

    log_artifact("output.txt")

    set_tag('tag1', 'this is tag1')
    set_tag('tag2', 'this is tag2')

    mlflow.end_run()

例えば上記をsample.pyというファイルで保存している場合

$ python sample.py

その後、~/mlflowに移動し下記コマンドでmlflowのダッシュボードが起動します

$ mlflow ui

この状態でブラウザでhttp://localhost:5000 にアクセスすると、上記で実行した実験の結果が表示されます。

f:id:taxa_program:20200705121321p:plain
MLflow UIのサンプル

コンペでの使用例と所感

今回のコンペでは、今までloggerで出力していたもの(CVのスコアなど)に加えて、モデルのハイパーパラメータなどを保存する形で使用しました。

以下のようにlog_paramにはCVやモデルのパラメータ、各種設定を辞書形式で保存し、

f:id:taxa_program:20200705121538p:plain
管理例(メトリクス)

log_metricには、各CVスコアとカテゴリごとのスコア、tagにはLBというKeyに対して、LBでのスコアを記載するように管理しました。

f:id:taxa_program:20200705121739p:plain
管理例(CVスコア)

これにより、どのモデルが「どんなパラメータ, 特徴量, CVで学習させたもの」か、そして「それぞれのCVスコアとLBのスコア」を一覧で確認することができ、とても便利でした。

「その他の工夫」項でも述べましたが、このダッシュボードのおかげて、モデルごとのカテゴリのスコアが管理することができたので、「このカテゴリの予測値は、このモデルのものを使用する」といったことが比較的低コストで実践できました。

また、モデルごとにスコアを比較し簡単なプロットもできたりします。

f:id:taxa_program:20200705122715p:plain
fold0のスコアと全データのスコアの散布図

今回紹介した管理方法(log_paramにどのような値を保存するか、など)はあくまで自分が試してみた方法なので、いくつも改善できる箇所はあると思います。今後も試行錯誤しながらより良い形にしていければと思います。

最後に

参加者及び運営の皆様、楽しいコンペをありがとうございました。

今回は本格的に参加してから締め切りまでの期間が短く、サムネイル(画像)の特徴量はほぼ手付かずでした。また、CVの切り方も特に工夫していなかったのが反省点です。

この辺りは他の参加者の方の解法を参考に勉強しようと思います。