こんにちは、コネヒトでアプリケーションエンジニアをしているaboです。今年の夏はいかがお過ごしでしょうか。とても暑い日が続いていますが、桃なんかは今が食べ頃なので冷やして食べると美味しいです。
さて、先日私の所属するテクノロジー推進グループで、プッシュ通知開封率予測モデリングコンペを行いました!私は主催者ではありませんが、機械学習未経験として参加した立場から、ブログにまとめようと思います。
テクノロジー推進グループとは?
元々コネヒトでは、機械学習エンジニアとインフラエンジニアとでタッグを組んで、サービスに機械学習を組み込んでいました。以下に2つの事例を紹介します。機械学習でサービスを良くする事例ができたことで、社内からの注目も高まっています。
ただ、機械学習をサービスに組み込むプロセスに課題もありました。機械学習のモデルを実装することはできても、サービスに組み込む際は他チームにいるアプリケーションエンジニアの手を借りないといけないため、リソース調整や詳細設計にコストがかかっていました。会社として機械学習のチャレンジをよりたくさん繰り返していくにあたって、よりスピード感のある組織体制にする必要がありました。
そこで今期から生まれたのがテクノロジー推進グループで、主に「機械学習を使ってサービスを成長させる」ことを目的としたチームです。
チーム構成は
の計3人(コンペ後にアプリケーションエンジニアが1人増えて今は計4人)です。
機械学習の実装をメインで担当するのは機械学習エンジニアですが、インフラエンジニアにも機械学習の実装経験があるため、相互に技術的な相談やPRのレビューなどを行っています。また、アプリケーションエンジニアをチーム内に置くことによって、前述した課題の解決をはかっています。このアプリケーションエンジニアが私で、必要に応じてサーバーサイドやiOSのコードを書いたりしています。
コンペ形式に至った経緯
テクノロジー推進グループでは発足当初、データ分析をもとに仮説を立てて(あるいは仮説を裏付けるデータ分析を行い)、施策(A/Bテストなど)に昇華させて、実装していく、という動きをしていました。ただこのデータ分析に少し手詰まり感があったのと、なにより毎週毎週繰り返されるデータ分析に少しマンネリ感も感じていました。これはチームメンバー全員が感じていた課題でした。
そんなときに、施策の一つであった「プッシュ通知 × 機械学習」について、機械学習エンジニアとインフラエンジニアのメンバーがkaggleなどのコンペ参加経験があることから、「優勝者のモデルを採用するコンペ形式でやってみると楽しいんじゃないか!!!」ということになりました。せっかくONE TEAMになったので、機械学習未経験の私はもっと機械学習の理解を深めたかったですし、チームとしての一体感も上がりそうな予感がしました。とてもワクワクするようなコンペの開催が決まりました。
コンペの設計
コンペの設計は機械学習エンジニアである @takapy がやってくれました。
ママリでは1日に数回、人気の投稿(ユーザーによる質問)をプッシュ通知で配信していて、開封率が高い通知が事前に分かれば、ユーザーがママリを開いてくれる頻度が高くなることが期待でき、また手作業で行っている投稿の選定工数の削減にも繋がります。今回のコンペでは、投稿本文やカテゴリー、プッシュ日時、投稿者の属性、実際の開封率(学習データのみ)など15個の特徴量が用意され、期間は約2週間で行いました。
また、コンペ開催前に機械学習エンジニアがJupyter Notebookの基本的な使い方や、特徴量の追加やモデルの生成方法など一連の流れをレクチャーしてくれたため、未経験の私でもすんなりコンペに参加することができました!
コンペを盛り上げるために、途中で中間報告を挟んだのですが、その時点では優勝候補筆頭の機械学習エンジニアがビリだったので、予想以上に盛り上がりました ✊ この時点でそれぞれがどうアプローチしたかを共有しあって、今後の参考にし合いました。
コンペの最終結果は...機械学習エンジニアが優勝!
中間報告でお尻に火がついた彼が追い上げ、機械学習エンジニアの優勝で幕を閉じました!
参加者がコンペでやったこと
参加した3人がそれぞれやったことを紹介します。
takapy(機械学習エンジニア)がやったこと
- 最初にベースラインのnotebookを作っていたので、EDA的な事はあまりしていない
- 一度100以上の特徴量を作って、そこから数十個にselection
- pseudo labeling
- trainの外れ値を学習データから除外
- テキストはTF-IDFで変換し、下記手法を試して一番よかったUMAPを採用(BERTも試したけど、TF-IDFの方がよかった)
- NMF
- UMAP
- t-SNE
- SVD
- Optunaでハイパーパラメータチューニング
shnagai(インフラエンジニア)がやったこと
- cluster以外は、質問に紐づく情報だからclusterをどう表現するかが鍵かなーと思ったりした
- test,trainを色々と見比べる
- cluster,category_id軸に平均、最大、最小開封率を特徴量として追加
- cluster平均開封率*category_id(最大、最小開封率)を追加
- 特徴量毎の開封率分布みて得量ありそうなものを特徴量にしていく
- wednesdayフラグ、q_freshness(qの新鮮度)
- GridSearchでパラメータチューニングを実施
- FeatureImportanceをみながら寄与度低い特徴量は削っていくアプローチ
- テキスト
- テキストではうまくモデリング出来なかった
- tfidf化して、次元圧縮を色々試す
- 次元数 2,10,100,300
- pca(TruncatedSVD),nmap
abo(アプリケーションエンジニア)がやったこと
- 質問者の属性は不要そうなので全削除、そのほかは消してスコアが悪くなったら戻すの繰り返し
- 質問についているそれぞれのタグを出現頻度に応じて数値化(TF/IDFのようなもの)
- LightGBMのパラメータ、num_iterationsとnum_leavesの調整
- 質問本文の数値化をいろいろ試したがスコアをあげることはできなかった
- (モデリングとはズレますが)やったことのログを細かく残した
参加者の感想
参加した3人の感想を紹介します。
takapy(機械学習エンジニア)の感想
- オンライン/オフライン含めていくつかのコンペに参加したことはあるが、設計側になったのは初めてで、かなり考えることが多く大変だった(今回はクローズドなコンペだったので、そこまでプレッシャーはなかったが、これはオープンなコンペとなると、主催者側の苦労は計り知れない・・・。主催されている方々の凄さを改めて思い知りました)
- マルチモーダルデータだったので、タスクとして難しかった
- データ量がそこまで多くなかったので、特徴量を足したり引いたりいろいろ実験できてたのはよかった(初めてモデリングするメンバーもいたので、この辺りが手軽にできたのは良かった)
- ベースラインのnotebookを作って共有し、「まぁここからそんなにスコア伸びないだろ」と思って前半は優雅に過ごしていたところ、他のメンバーが試行錯誤してスコアを伸ばしきたので、焦った&楽しく参加できた!
- 自身のスキルを他者に分配することで、チームのベースとなるスキル・知識の底上げもできて良かった。
shnagai(インフラエンジニア)の感想
- 悔しすぎる
- でもめちゃ楽しかったし、これ系好きだなーと思ったのでどっかのコンペチャレンジしてみようかな
- テキストをうまく使えなかったので、たかぱいの解法知りたい
- Jリーグの時はドメイン知識的なやつを使えてうまく結果に繋がったけど今回はうまく出来なかった。。。
- 色々と知識が断片化してることに気づいたから、実際に手を動かすの大事だよな
- またやりたい!!
abo(アプリケーションエンジニア)の感想
- 予測結果と実際の開封率の差を説明変数でグルーピングして可視化することで何かしらインサイトを得て、アプローチに幅を出したかった
- ログを細かく残したことによって、何をしてスコアが上がったのか下がったのかを忘れないし、あとから見直す材料になった
- スコアが良くなった時も、なかなか良くならない時も、楽しかった!
- 初見のことをたくさん学べた(お二人に分からないことを聞きまくった)
- 同僚の @takapy と @shnagai すげー!って思った
- Python/Pandasが手に馴染んでないのでそういう意味でのもどかしさはあって悔しい
また、コンペを開催していなければ、もっと言えばテクノロジー推進グループになっていなければ、絶対見ないであろう機械学習系の記事もたくさん読みました。領域の違う人が同じチームになったことで生まれた良い効果なのではないかと思います。
おわりに
今回は、今期から誕生したテクノロジー推進グループでの、ユニークな取り組みを紹介しました。機械学習未経験の私が参加してみて、自チームのコアである機械学習がより身近に感じるようになりました。
また、優勝したモデルで実際にA/Bテストしたりサービス運用に組み込んだ話は @takapy がブログにしてくれると思うので、気になった方はもう少しお待ちください。
コネヒトではこんな感じでやり方を工夫しながら楽しく仕事をしています!現在全職種募集中ですので、まずはお話だけでも聞きに来てください〜。 hrmos.co