CARTA MARKETING FIRMのデータサイエンスエンジニアの生態を覗いてみましょう

この記事はCARTA TECH BLOGアドベントカレンダー12/14の記事です。

こんにちは!CARTA MARKETING FIRMでデータサイエンスエンジニアをやっているsakakey(さかきー)と申します!

今回は、タイトルにある通り、「CARTA MARKETING FIRMでのデータサイエンスエンジニアの生態」について書いていきます。

というのも、社内での人数が少ないこともあり、データサイエンスエンジニアの仕事というのは意外と周知されていないと感じています。

なので、この記事ではそんなデータサイエンスエンジニアが、どう言った背景でどういう仕事をしているのか、僕が携わったタスクを軸に紹介していきます。

また、24新卒であり、今年4月に現チームに配属されてから一つのタスクを長期的かつフルサイクルに行ってきた中で得た学びに関しても共有していきたいと思います。

この記事の対象読者

  • データサイエンスエンジニアに興味がある人
    • データサイエンスエンジニアがどういうことを考えて仕事をしているかを知りたい人
    • データサイエンスエンジニアのフルサイクルとは?が気になる人
  • 新卒エンジニアがスコープの長い仕事の中でどういう学びを得たのか知りたい人
  • CARTA MARKETING FIRMの広告配信システム(DSP)に興味がある人

想定所要時間

15分〜

前提

まずは、前提となる知識について簡単に触れていきます。

我々CARTA MARKETING FIRMは、デジタル広告事業の会社です。広告主さんからお金をもらって、広告を配信し、そこからマージンをもらってお金を稼いでいます。

その中で、ごちゃごちゃした色々なシステムが登場し、その間で様々な取引がなされた上で広告がメディアに配信されるのですが...

ここではSSPとDSPに焦点を当てていきます。

デジタル広告は、基本的にオークションによって出る広告が決まります。 SSPは、メディア(Webページやアプリ)の広告枠を持っていて、メディアにユーザーが訪れると、後述するDSPに「今広告枠が発生したのでオークションを開催します!」というリクエストを一斉に送ります。DSPは、広告を持っていて、SSPからきたリクエストに対して、どの広告をどのくらいの値段で出したいかを決めます。そして、各DSPから返ってきた入札額の中で、一番高いDSPが広告を出し、ユーザーに表示される、というわけです。

①広告主が広告を入稿する

②ユーザーがメディアにアクセス

③メディアからSSPに広告ほしいよと言う

④SSPから各DSPにリクエストを送信

⑤DSPがSSPに広告と入札額を返す

⑥オークションに勝利したDSPの広告がユーザーの元へ

その中で、我々データサイエンスエンジニアが何をしているかというと、オークションにおいて、どの広告をどのくらいの入札額で入札するか、ということを自動で決定するロジックを主に作っています。

広告主のKPIを満たすために、より効率的な入札ロジックを開発し、プロダクトにリリースするのが我々の目標です。

背景

まず、私が行ったタスクについて話していきます。私が今回行ったタスクは、「CVR予測モデルに新たな特徴量である離脱日数を追加する」と言うものでした。

詳しく話すと長くなってしまうので一言でまとめてしまうのですが、「入札額を決めるいくつかの機械学習モデルのうちの一つに特徴量を追加して改善しよう」と言うタスクだったわけです。

離脱日数というのは、ユーザーがとあるアプリを最後に起動してからたった時間のことで、一度アプリをインストールしたけど使わなくなってしまったユーザーにもう一度アプリを使ってもらおう!というモチベーションで広告を配信する際に効果を発揮する特徴量なわけです。効果を発揮する!ということは広告運用側の知見ではわかっていて、これまでは運用者の感覚で離脱日数を考慮していました。それを機械的にモデルで考慮して、より精度よく、効率的にしたいというのが今回のタスク、というわけですね。

このような背景で、半年(!?)に渡り僕がやってきたことを紹介していきます。

やったこと

今回のタスクでは、主に以下のプロセスのサイクルを回すことでタスクを進めていきました。

  1. 実験・検証
  2. 実装
  3. A/Bテスト
  4. 分析
  5. 再び1.へ

以下で、各フェーズで簡単にどういうことをやったか、どういう辛さ・どういう学びがあったかを話していきます。

実験・検証

どんな施策を試す場合でも、まずそれが有効かどうかを調べなければいけません。このフェーズでは、タスクに対する事前調査や、A/Bテストで得た知見からのフィードバックを受けての改善など、抽象的な課題を具体的なロジックに落とし込む作業を行いました。

例えば、最初はそもそも離脱日数ってどういう概念?どういう傾向があって、なぜモデルに入れると嬉しいの?を調査しました。python notebook上で、離脱日数のデータをこねくり回してグラフを見てみました。これによって、離脱日数使いたいよね、という漠然な課題から、どこでどのように使えばいいのかという具体的な修正まで落とし込むことができたわけです。

また、A/Bテストのフィードバックという意味でも、非常に重要なフェーズです。例えば、A/Bテストで全然まったく欲しかった結果が出なかった時(よくあります)、なぜ欲しかった結果が出なかったのか?どういう修正をするとうまくいくようになるのか?を考え、再びサイクルを進めるためには、結局データをこねくり回すしかありません。何なら、タスク全体でこのフェーズにかけた時間が一番長いです。困ったものですが、データサイエンスエンジニアの仕事のほとんどはデータを見ています。ですが、これによって、A/Bテストでうまく効果が出ないという抽象的な課題から、こう修正すればうまくいきそう、の具体的な修正を得ることができるのです。

ここで学んだ一番大切なことは、「前提を多角的・長期的な視点で検証する」です。

このフェーズに一番時間をかけるべき一番大きな理由は、前提が間違っていると全て間違うからです。今回、僕のタスクにおいても、2回ほどそもそも前提が間違ってるじゃん!!と間違いに気づき、うなだれた経験をしました。そもそも離脱日数の計算方法が間違っていたり、仮定が間違っていたり、です。

現時点では問題になっていなくても、それを使う段階になって初めてわかる問題もあります。なので、こういったことが起こらないように、一旦落ち着いて、今後どういう流れでどういったことを行うのかを整理しましょう。人に聞く・検証方法をレビューしてもらうのも効果的です。人を増やせば増やすほど多角的になりますので、どんどん人を巻き込んでいきましょう。そうすれば、後になって前提が間違っていたことに気づき、今までやってきたことが無意味だった絶望を味合わなくて済みますから...

実装

検証を行って、何をすればいいかが具体的になったら、あとはやるだけです。

とはいえ、やりたいことを実際形にするには、エンジニアとしての力が必要になります。今回でいうと、新たに離脱日数を取得するログを追加し、S3経由でDBに保存し、dbtで整形した上でそれをモデル学習バッチで使い、成果物を入札サーバーで使えるようにし、A/Bテストの準備をするという一連のかなり長いパイプラインを実装しなければなりませんでした。

これは、複数のリポジトリを跨ぎ、かつ使用されている言語・技術も違うため、ドメイン知識・コーディング知識・インフラ知識など幅広い知識が求められるものでした。

本来、これらの仕事はデータサイエンティストの仕事ではないです。しかし、我々がフルサイクルエンジニアリングという考え方に基づいて開発を行っているので、こういったことにも責任を持ってやり遂げます。フルサイクルエンジニアリングについては以下の記事を参考に。

techblog.cartaholdings.co.jp

元来、データサイエンスだけでなく様々なことをやりたいと思っていた僕にとってはこれは非常に楽しい仕事でした。成長という面でも、データサイエンスだけでなく、プロダクト全体としてどのように動いているかを理解することができました。

ここで学んだことは、シンプルに「わからないことはすぐ聞きにいく」です。先で述べた通り、今回は非常に広いスコープを持って、長いパイプラインを取り扱いました。当然、MLチーム側ではあまり管理しない部分の修正も。こういった部分に関する質問をチームを跨いでアプリケーションチームに聞きにいくフットワークの軽さが、この大きな修正を成し遂げることができた大きな理由でした。

A/Bテスト

モデルも準備できた。それを使う準備もできた。そうなればあとは実際に使ってみてテストするだけです。しかし、その前にもまだやらなければならないことはあります。それは、A/Bテストをどのような設定でやるかをドキュメント化することです。

あらかじめ、仮定と制約を明確にしていなければ、A/Bテストとして説得力のないものになってしまいます(自戒)。A/Bテストで一番重要なのは、終わった後の分析ではなく、事前の設定だと学びました。

少し具体的に列挙すると、A/Bテストの背景・目的・仮定・メトリクス・どうなれば仮定が正しいと証明されるのか・仮定が正しいならどうするのか・仮定が正しくないならどうするのかを決めます。

今回は合計で3回のA/Bテストを行いましたが、最初の1回はこれを正しく設定できていなかったので、何だかあやふやな結論が出て、説得力がなくなってしまったのが大きな反省です。

大事なことなので何回でも言いますが、A/Bテストで一番重要なのは、終わった後の分析ではなく、事前の設定です。これは、A/Bテストに限らず様々なものに言えると思います。

あるアクションを起こす時、なぜそれをするのか・それをすると何が嬉しいのか・他に手段はないか・アクションを起こして何がどうなれば成功なのかを常に考えることが大事ですね。

分析

さて、A/Bテストが終了したあとは、A/Bテストの結果を分析しなければなりません。といっても、全てが仮定通りになっていればそこまで難しいことはありません。事前に設定したメトリクスを見て、事前に決めた効果が出ていれば、事前に考えておいたことをやるだけですから。

しかし、現実はほとんどの場合そうなってくれません。うまくいかなかった場合、何かがうまくいっていないのです。

今回私は、先で述べたように3回のA/Bテストを実施しました。

  1. CVR予測モデルAの実験①
  2. CVR予測モデルAの実験②
  3. CVR予測モデルBの実験

そして、それぞれ以下のような理由でうまくいきませんでした;;

1. CVR予測モデルAの実験①

うまくいかなかったこと:

  • 出て欲しい結果が出なかった
  • 分析方法が曖昧で、結果に信憑性がなくなってしまった

原因:

  • 仮定に反する傾向のデータが大きな割合で入り込んでいた
  • 事前に分析方法やメトリクスなどの実験後のことを具体的に詰めきれていなかった

2. CVR予測モデルAの実験②

うまくいかなかったこと:

  • 結果を見てリリースするかどうかに悩んでしまった
    • 本当にリリースしていいのか?になった
  • 前提となる計算方法の間違いや考慮していなかった情報に後から気づいた

原因:

  • 多少改善したが、実験後のことをまだまだ詰めきれていなかった
  • 前提となる部分を完全には確認しきれていなかった

3. CVR予測モデルBの実験

うまくいかなかったこと:

  • 分析結果が全然仮定と違った

原因:

  • そもそもA/Bテストのユーザー振り分けがイケてなかった
  • 外れ値のデータが悪さをしていた

ですが、最終的に全てを乗り越えた先で、綺麗に仮定通りの効果が出ていることを示すグラフを拝むことができました。本当に長かった....

サイクルを回す

ここまでで、僕が何回かサイクルを回す中でやってきたことについて話してきました。

1回目のサイクルでは何もかもうまくいかず、それでもうまくいかない原因を探求し続けて進んだ結果、最後には望んだ結果を得ることができました。

この全体を通して学んだことというか、全体で最も重要だなと思ったことは、「自分で意思決定できることに気づくこと」だと思いました。

例えば、1回目のA/Bテストの結果を見て、これはダメだと見切りをつけることもできたわけです。新しくログを生やさずに、既存のログに離脱日数を入れてそれをモデル学習に使うこともできました。そして、それらの意思決定は、自分ではなく先輩やチームメンバーに相談して意思決定してもらっていました。しかし、実はこれらの意思決定は、新卒だろうと誰だろうと下すことができるわけです。

もちろんその決定を下すに足るファクトがあることが前提ですが、何かを自分で決めて、その上でそれをレビューしてもらう、ということが、新卒という立場から抜け出す上で一番重要だなと感じました。

その辺は過去に以下の記事にまとめてあります。

techblog.cartaholdings.co.jp

こういった機械学習モデルの改善のようなタスクは、やろうと思えば一生できてしまうので、それをやるコストとビジネス上の利益をきちんと考えてサイクルを回すのが重要です。そして、それをどこまで回すのかを決定するのは他の誰でもない自分です。

まとめ

この記事では、私が入社してから最も長く携わってきたタスクを軸に、学んだことや仕事の中で考えていることなどを紹介してきました。

実際にやったこととして、実験・検証、 実装、A/Bテスト、分析を紹介し、そのサイクルを回す上で学んだことや考えたことについて話してきました。

学んだ大切なこととして、「前提を多角的・長期的な視点で検証する」「わからないことはすぐ聞きにいく」「自分で意思決定できることに気づくこと」を挙げました。

今振り返ってみると、かなり多くのことをやってきたなと思います。ここで挙げたタスク以外にも、細かな改善や修正などもたくさん行ってきました。自分としては時間をかけすぎたと思ってはいるのですが、大変な仕事をしたぞ、ということも、次やるときは半分の時間でできるぞ、という自信もあるので、結果的には良い学びだったと思います。

しかし、まだissueはcloseしていません。現時点ではまだこの機能をリリースできていないのです。

ここから先も、ここで学んだことを活かして、最終的には「自分で課題を見つけて自分で解決できるエンジニア」になるのが当面の目標です。

非常に長い記事をここまで見てくださった方、ありがとうございました。

この記事は、4月の僕がこれを読んでいたら未来が変わっていたな、というものを詰め込んだので、データサイエンスエンジニアとしてこれからやっていく方も、データサイエンスエンジニアを知りたい・コラボレーションしたい方もこの記事で少しでもデータサイエンスエンジニアへの解像度が上がってくれていれば幸いです。