Slide 1

Slide 1 text

Airbnbの機械学習導入から学ぶ Jun Ernesto Okumura Photo by Etienne Boulanger on Unsplash

Slide 2

Slide 2 text

Motivation ● KDD2020においてAirbnbの論文がとてもよかった ○ 過去のEmbedding論文(KDD2018)などのアルゴリズムも参考になったが、 その後は機械学習導入に関するポストモーテム論文が多く執筆されている ● 試行錯誤のプロセスやしくじりポイント含め、プロジェクトとして学ぶべき点が多かったため、 備忘的に内容をまとめます Disclaimer ● 内容について意見・コメントがある場合は Twitter: @pacocat までご連絡ください ● 本資料で掲載されているグラフは断りのない限り当該論文のものを利用しています

Slide 3

Slide 3 text

Outline Airbnbの推薦アルゴリズムと、その後の改良のプロセスについて紹介します Real-time Personalization using Embeddings for Search Ranking at Airbnb Grbovic & Cheng 2018 (KDD 2018) Applying Deep Learning To Airbnb Search Haldar et al. 2019 (KDD 2019) Improving Deep Learning For Airbnb Search Haldar et al. 2020 (KDD 2020) 1 2 3

Slide 4

Slide 4 text

Photo by Etienne Boulanger on Unsplash Real-time Personalization using Embeddings for Search Ranking at Airbnb Grbovic & Cheng 2018 (KDD 2018) 1

Slide 5

Slide 5 text

Overview 概要 ● 検索スコアのアルゴリズムにEmbedding特徴を導入し、 Cold Startにも対応できるよう拡張した ● 結果、類似宿モジュールのCTR+21%(予約数+4.8%)、全体のNDCUも改善 Airbnbのサービス特徴 ● 「宿泊場所を貸し出すホスト」と「宿泊を希望するゲスト」をマッチングする Two-sided market(ゲストの希望だけでなく、ホストが受け入れるかも大切) ● ECやストリーミングといったサービスと比較して予約頻度が高くない ○ ゲストの旅行目的での利用はせいぜい年に 1,2回程度(最大でも365回しか使えない) ○ 受け入れ側可能なゲスト数・日数も限られている ● 検索はマーケット(ドメイン; 地域)を横断しない ○ パリに行きたい人はアメリカや日本を検索することなく、パリという地域内でのみ検索を行う

Slide 6

Slide 6 text

サービス利用の流れ User A ● ゲストが希望条件で検索→候補をクリックして検討→予約→ホストが承認 候補となる宿のクリック ※ Session 30min以上行動がなかった 場合は別Sessionとして扱う Session 予約(booking) ※ 意図的に訪れたページのみを考慮するため、学習時は30sec以上滞在したクリックに限っている ※ 学習時は2つ以上のクリックがあるセッションのみを利用 ⇒その後、ホストが承認、  もしくはリジェクトを行う

Slide 7

Slide 7 text

本論文で扱っているビジネス課題と貢献 1. 関連する宿をリアルタイムで最適化して予約率を向上させたい ○ セッション中にクリックされた宿 ※から、よりユーザーの好みに関連するものを上位に表示 ○ クリックされた宿のEmbedding特徴を推薦モデルに入力することで解決 2. 予約履歴をもとに長期的な利用を促したい ○ ユーザーの旅行頻度は年に1,2度程度と情報がスパース ○ ユーザーや宿の属性をグルーピングすることで合理的な Embeddingを実現 ※ 論文では宿を”listing”として表現している

Slide 8

Slide 8 text

話題① Skip Gram Modelを用いたEmbedding ● あるセッションでクリックされた宿 から、前後でクリックされた宿を予測するタスク を解いて、宿に関する分散表現を獲得 … … Session : の周辺にある の出現確率 : のEmbedding

Slide 9

Slide 9 text

Negative Sampling Approach ● Targetの勾配を求めるには に比例した計算が必要になり非現実的 ● そこでNegative Sampleのアプローチを用いる ○ Positive pairsとNegative pairsをサンプリングし、以下のように最適化 Positive sample クリックされた とコンテキスト ( 周辺のクリック)のペア Negative sample 全セッションからランダムにサンプル

Slide 10

Slide 10 text

Booking Listing as Global Context ● 周辺のクリック(local context)だけでなく、最終的に予約される宿かどうかの情報 (global context)も埋め込みたい ○ 予約された宿とのsimilarityの項を追加することで実現 ○ Local contextはセッション中をスライドする点に注意 Local Context(Skip Gram Model) Global Context … … …

Slide 11

Slide 11 text

Adapting Training for Congregated Search ● Airbnbはサービス特性上、検索される地域の制約がある ○ パリを条件に設定している人はアメリカや日本の宿を求めていない ○ Negative Sampleをランダムにすると意味のない地域の情報が混ざる ● 新たに同一地域からランダムにNegative pairsを抽出して利用 Local Context(Skip Gram Model) Global Context 同一地域内の Negative Sample

Slide 12

Slide 12 text

学習とCold Startへの対応 ● 8億のセッション※を利用して学習 ● Embeddingの次元数はd=32次元 ● 推論時のCold Start対応 ○ 新着の宿はクリック情報を持たないため、以下の情報で代替する ■ 新着宿から10mile以内、同一タイプ(Private Roomなど)、 同一料金帯($20-25など)でEmbeddingが計算できる宿を3つ抽出して平均化 ※ 宿の数は450万に及ぶ(論文投稿時点)

Slide 13

Slide 13 text

Embeddingの検証1: k-means, similarity ● K-meansを使い、カリフォルニアの宿をクラスタリング ○ 納得感のある地域特性が反映されていた ● 宿の特徴ごとにcosine similarityで検証 ○ 部屋のタイプや料金が近ければEmbeddingのsimilarityも高いことを確認

Slide 14

Slide 14 text

Embeddingの検証2: Evaluation Tool ● 定性的に確認を行うための検証ツールを独自に開発 Demonstration of Similar Listing Algorithm using Listing Embeddings (last accessed: 2020-08-26) https://www.youtube.com/watch?v=1kJSAG91TrI

Slide 15

Slide 15 text

Similar ListingへのEmbeddingの活用 ● 宿の詳細ページには「類似宿」を表示するカルーセルがある ● 宿のEmbeddingを用いて類似度の高い宿を表示した結果、 A/BテストでCTRが21%の向上、カルーセル内の予約が4.9%向上

Slide 16

Slide 16 text

話題② User Type、Listing TypeのEmbeddings ● 短期的にセッション中の推薦を改善するだけでなく、長期的にユーザーの好みを反 映した推薦を実現したいが、サービス特性上の困難がある ○ 予約を含むセッションはクリックセッションよりも桁で少ない ○ ゲストの予約情報が少ない(多くのユーザーは過去に 1度の予約情報しかない) ○ ホストの予約情報が少ない( 5-10件しか予約されていない宿も多い) ○ 次の予約まで時間が空くためユーザー属性も変化する ゲスト・ホストを個別に扱うのではなく、属性ごとにグルーピングする

Slide 17

Slide 17 text

Listing type buckets ● 地域はUS ● 2名まで宿泊可能 ● ベッド1つ ● ベッドルーム1つ ● バスルーム1つ ● 平均料金$60.8 ● ゲストあたり平均料金$29.3 ● レビュー数5つ(全て星5) ● 新規ゲストの受け入れ率100% US_lt1_pn3_pg3_r3_5s4_c2_b1_bd2_bt2_nu3 mapping

Slide 18

Slide 18 text

User type buckets ● SF在住 ● MacBookからアクセス ● 言語は英語を設定 ● プロフィールと写真は設定済み ● 83.4%のホストが星5で評価 ● 過去に3度の予約 ● 過去予約の平均料金が$52.52 ● ゲストあたりの平均料金は$31.85 ● 8.24件のレビュー ● 76.1%を星5で評価 SF_lg1_dt1_f p1_pp1_nb1_ppn2_ppg3_c2_nr3_l5s3_g5s3 ※ 過去に予約していなくても、上位5項目(赤枠)の情報は使えるので、Cold Start文脈でも嬉しい mapping

Slide 19

Slide 19 text

User type, Listing typeの学習 ● ユーザーの予約履歴から (user_type, listing_type)のタプルを抽出※ ● Skip Gram Modelを用いてEmbeddingを学習 ○ ホストによるリジェクトがある場合は明示的な Negative Sampleとして扱う ※同一ユーザーでもuser_typeは変化しうる点に注意

Slide 20

Slide 20 text

Training Procedure user_typeのEmbedding学習 listing_typeのEmbedding学習 Skip Gram Model Explicit Negative Sample

Slide 21

Slide 21 text

Type Embeddingの学習詳細 ● 基本的にはlisting embeddingと同様 ● 学習には予約セッションのみを使い、5倍にoversampleを行った ● Embeddingの次元はd=32、windowはm=5に固定 ○ dを増やせば表現力は上がるが、メモリの使用量とトレードオフがある ● 学習システム ○ パイプラインはAirflowで構築 ○ MapReduce(300 mapper & single reducer) ○ Dailyでフルスクラッチ学習 ※ ※ 追加データに対してinclementalに学習するよりもオフライン評価が良かった

Slide 22

Slide 22 text

オフライン評価 ● 予約した宿を、それ以前にどれだけ上位にランクできていたかで評価 ○ ランキング(縦軸)は低いほどよい 予約宿のランキング 予約前のクリック Search Ranking: 既存システム (クリック履歴を使っているため次第にrankが上がる) d32 reg: skip gram modelを使ったEmbedding d32 book: global contextを追加したEmbedding d32 book+neg: 同一地域のNegative pairを使ったEmbedding d32 book+reg が最も予約宿を上位にランクできた

Slide 23

Slide 23 text

EmbeddingのSearch Ranking Modelへの導入 ● ある検索で i 番目に表示された宿の特徴量 , ラベル※ を考える ● 過去30日の予約セッションを集めて学習データを構築 Description 1 予約が成立 0.25 ホストに連絡が行われたが予約はされなかった -0.4 ホストからリジェクトが行われた 0.01 クリックが発生 0 クリックが発生しなかった ※ ラベルは検索から1週間後の状態にもとづいて割り当てる

Slide 24

Slide 24 text

特徴量 ● Listing features ○ 一泊あたりの料金、宿泊タイプ、部屋数、リジェクト率、 … ● Query features ○ ゲスト数、宿泊日数、リード時間、 … ● User features ○ 過去の平均予約料金、ユーザー評価、 … ● Cross-features ○ 検索地と宿泊地の距離、ゲスト数と受入可能ゲスト数の差、宿の料金と過去の予約料金と の差、リジェクト率、セッション内で対象宿がクリックされていた割合、 … ● Embedding features(後述) ○ 6種類のlisting feature + user_type & listing_type feature

Slide 25

Slide 25 text

Embedding Features ● ユーザーの過去2週間の行動履歴から、以下の宿のEmbeddingを抽出 ○ (clicked listing ids) : クリックした宿 ○ (long clicked listing ids) : 60sec以上閲覧した宿 ○ (skipped listing ids) : クリックされずにスキップした宿 ○ (wishlisted listing ids) : ウィッシュリストに入れた宿 ○ (inquired listing ids) : ホストに問い合わせしたが予約しなかった宿 ○ (booked listing ids) : 予約した宿 ● 抽出されたEmbeddingを地域ごとに平均化 ● スコアリング対象の宿に対してcosine similarityの最大値を特徴とする

Slide 26

Slide 26 text

User-type & Listing-type Embedding Feature ● Listing embeddingと同様に計算 ○ 50万ずつのuser-type & listing-typeに対して5000万の予約セッションを用意

Slide 27

Slide 27 text

Search Ranking Model ● LambdaRankが使えるよう拡張したGBDTで学習 ● 学習されたモデルは宿のスコアリングに使用(NDCGで評価) ● 結果、CoverageやImportanceが高いFeatureを作ることができた

Slide 28

Slide 28 text

オンライン評価 ● DCU (Discounted Cumulative Utility)でbookingが+2.58%と大きく改善 ○ 対してRejectionはほぼフラットであった ● NDCUも2.27%の改善 ネガティブインパクトは小さい 検索メトリックが改善

Slide 29

Slide 29 text

Photo by Etienne Boulanger on Unsplash Applying Deep Learning To Airbnb Search Haldar et al. 2019 (KDD 2019) 2

Slide 30

Slide 30 text

Overview 概要 ● Search Rankingモデルの変遷を振り返った論文 ● 多くの失敗事例や得られた知見をまとめられている 背景 ● GBDTの活用(前論文)によって予約率は大きく向上した ● 一方で、その後は目覚ましい改善はなかった ○ 様々な試行錯誤にも関わらず、アーキテクチャは複雑になる一方だった ● 最終的に、単純なDeepモデルに立ち返ることで改善を達成 ● 過去モデルの歴史を俯瞰しながら失敗したこと・学習したことをまとめている

Slide 31

Slide 31 text

Search Ranking Modelの変遷 ● 各メトリクスは継続して向上しているが、そこには様々な失敗があった※ ※ ここで紹介されているGBDT/FM NNは前論文とは別モデルと思われる(Lambdarank NNとの中間状態だった?)

Slide 32

Slide 32 text

“Don’t be a hero”※ by Andrej Karpathy ● 複雑なモデルアーキテクチャーではなく簡単なものからスタートすべき ● Airbnbのランキングモデルは様々な独自の改良を加えた結果、複雑で制御ができな いものになってしまった。最終的には単純なDeepモデルに落ち着いた。 ※ A Recipe for Training Neural Networks (Karpathy 2019) http://karpathy.github.io/2019/04/25/recipe/ I’ve seen a lot of people who are eager to get crazy and creative in stacking up the lego blocks of the neural net toolbox in various exotic architectures that make sense to them. Resist this temptation strongly in the early stages of your project.

Slide 33

Slide 33 text

モデルの変遷1: Simple NN→LambdaRank NN ● LambdaRank※1の導入よってNDCGを直接最適化できるようになった ○ Pairwise: {booked-listing, not-booked listing}ペアに対して順番を学習(Rank学習) ○ ペアを入れ替えることで、損失が大きくなるものは大きな勾配を与える ※2 ※1: From RankNet to LambdaRank to LambdaMART: An Overview https://www.microsoft.com/en-us/research/publication/from-ranknet-to-lambdarank-to-lambdamart-an-overview/ ※2: 例えば、9位と10位を間違えるよりも1位と2位を間違える方が問題なので勾配が大きくなる ● 32ユニットの中間層を1つだけもつ単純なNN(w/ ReLU activation) ● 宿に対して予約するかしないかの 2値予測を行っていた ● 入力は前論文に使われていたものとほぼ同じ SImple NN LambdaRank NN

Slide 34

Slide 34 text

モデルの変遷2: GBDT/FM NN ※ Deep & Cross Network for Ad Click Predictions https://dl.acm.org/doi/10.1145/3124749.3124754 ● GBDTとFM(Factorization Machine)の出力をNNの入力として使うモデル ● FMはクエリと宿を32次元のベクトルに埋め込むことで、宿の予約確率を出力する ● Deep & Cross Network※に触発されて、GBDT/FM/NNの各強みを活用しようとした GBDT/FM NN

Slide 35

Slide 35 text

モデルの変遷3: Deep NN ● モデルの複雑化に伴い、技術的な負債が無視できないようになってきた ● そこで、過去のモデルを全て廃止し、 2層の隠れ層を持ったDeepモデルに置き換えた ○ 195次元の入力→第1中間層(127 unit w/ ReLU)→第2中間層(83 unit w/ReLU) ● 特徴は最小限のエンジニアリングで決めている ○ 料金、アメニティ、過去の予約数、 … ○ ダイナミックプライシングで使われているモデルの出力 ※ ○ 前論文で紹介した(過去に閲覧した宿に関する) Embedding特徴 ※ Customized Regression Model for Airbnb Dynamic Pricing https://www.kdd.org/kdd2018/accepted-papers/view/customized-regression-model-for-airbnb-dynamic-pricing Deep NN

Slide 36

Slide 36 text

上手くいかなかった手法1: Listing ID ● NLPやYouTubeの推薦※などの成功事例からlisting idを特徴に使えると考えた ● 一方で、実際にlisting idを入れてみると過学習に陥った ○ 単語や動画とは異なり、 1つのアイテム(宿)に大量の予約を受け入れることはできないし、ユーザー が入れられる予約にも上限があるサービス特性 idを入れるとTrain NDCGが早々に1になる

Slide 37

Slide 37 text

上手くいかなかった手法2: Multi-task Learning ● 予約数が限られているのであれば、より数の大きいクリックを活用できないかと考えた ● 予約予測とページ閲覧時間予測のマルチタスク学習に着手 ※1 ○ しかし、閲覧時間は明らかに改善したにも関わらず、予約数は増えなかった ※2 ○ 調べると、本来の目的とは異なったページの閲覧が増えているだけだった ※3 ※1: 予約数とクリック数のスケールが桁で異なるため、予約予測の精度を維持するために   予約のLossに大きな重みを付けたり、さらにlong_viewのLabelをlogで変換している ※2: Airbnbでは閲覧時間と予約に相関があるにも関わらず ※3: 高級/希少な宿、説明が長い宿、説明が面白い宿、など予約目的とは異なる宿の閲覧 予約までのクリック数分布 1つの予約までに数十〜数百の宿が閲覧されている

Slide 38

Slide 38 text

特徴量エンジニアリング1: Feature Normalization ● NNを使えば自動的に特徴量が選択・加工される期待があったが甘かった ● 初期にはGBDTの特徴量をそのままNNに与えたが、精度が極端に悪くなった ○ GBDTは特徴の順序が重要だが、 NNではスケールに影響を受けるため前処理が必要 ● 正規化※ ○ 正規分布のような特徴の分布に対しては標準化 ○ べき乗分布に対しては logを取る ※ 当たり前のことを書いていると思われるが、この論文では全体的にこのレベルの「しくじり」も含めて正直に書かれている

Slide 39

Slide 39 text

特徴量エンジニアリング2: Feature distribution ● 特徴の分布がなめらかになっているかをしっかり確認した ● Spotting bugs ○ 複数のバグを見つけた ■ 通貨レートの変換がおかしくなっている地域がある ■ 28日以上の宿泊に対して dialy料金ではなくmonthly料金が設定されている ● Facilitating generalization ○ 入力の特異な変化に対してどれだけ影響を受けるか確かめた ■ 特徴(例えば料金)を 2x, 3x, 4x, ..のように変化させ、NDCGの変化を観測 ■ 結果、出力は安定しており、特異な入力に対しても影響を受けにくいことが分かった

Slide 40

Slide 40 text

特徴量エンジニアリング3: Geometric Feature ● 緯度経度は若干特殊な変換が必要となった ○ 地域によって特徴的な緯度・経度の分布は異なる ○ 表示している地図の中心からの距離を特徴にし、 logを取ることでなめらかな入力を実現した

Slide 41

Slide 41 text

特徴量エンジニアリング4: Feature Completeness ● 分布を見ることで、足りていない特徴にも気づくことができる ○ 宿のクオリティを表すことを期待して、空いている宿泊日数を入れていた ※ ○ しかし、宿によって予約可能な最低日数は異なり、カレンダー依存でもある(分布が特異) ○ ここで足りていなかったのは平均滞在日数。実際平均滞在日数で正規化することで、 なめらかな分布を得ることができた。 ※ 人気の宿は早々と予約されあまり空きがないといった仮説

Slide 42

Slide 42 text

High cardinality categorical features ● Listing idは失敗したが、カーディナリティの高い地理情報は上手く活用できた ○ 都市内の地域を表す特徴を頑張って手作りしていたが、 DNNに表現学習を任せた ○ S2 cell※を使うことでEmbeddingを獲得した ■ 例えば、San FransiscoのEmbarcaderoは539058204に位置しており、 {“San Francisco”, 539058204} -> 71829521と表現できる(このカテゴリを入力に使った) ※ 階層的に地球上の位置を表現するコード(以下の説明が詳しい) https://s2geometry.io/devguide/s2cell_hierarchy.html

Slide 43

Slide 43 text

System Engineering ● Protobufs and Datasets ○ GDBTモデルではcsvで訓練データを入力しており、 DNNでもパイプラインを使いまわしていた ○ しかし、GPUが25%しか使えず、feed_dictを通じたcsvのパースがボトルネックと判明 ○ そこで、パイプラインを作り直し、 Protobufとtf.data.Dataset※を使った ■ 学習が17倍早くなり、GPU利用率も90%に達するようになった ● Refactoring static features ○ 宿の特徴(場所やベッド数)は基本変化せず、毎回全て読み込むのはボトルネックになる ○ そのため、準静的な特徴は事前に listing idでインデックスされたベクトルとして固めておいた ■ GPUメモリに乗せることで、 CPUからのロードを必要とせずに効率化することができた ※ https://www.tensorflow.org/guide/data ※ その他、Javaのライブラリを開発してLatencyを改善した話などあるがここでは割愛

Slide 44

Slide 44 text

Hyperparameters ● GBDTからNNの移行に従って、ハイパーパラメータの調整も未知の領域だった ● FOMO(fear-of-missing-out;取り残されることへの恐怖)から、多くの事例をサーベイして試行錯 誤したが、最終的に以下に落ち着いた ○ 正則化はDropoutではなくData Augumentationを活用 ■ Dropoutは流石に効くだろうと思っていたがそうでもなかった ■ (hand-madeな)ランダムな摂動を加えた Data Augumentationを利用 ■ オフラインのNDCGを1%改善したが、オンラインでは有意差が出ていない ○ 初期化 ■ 重みを全部ゼロにするしくじりなどを経て、最終的に Xavier初期化に落ち着いた ○ LazyAdamOptimizerを活用 ■ 大きなEmbedding計算の収束が早かった ○ Batch sizeは200を利用

Slide 45

Slide 45 text

特徴量選択 ● GBDTではFeature Importanceを見ることで特徴量の重要度を判断していたが、 NNではどのように特徴量を抜き差しするか試行錯誤を行った ○ Ablation Test: ある特徴を落としてパフォーマンスへの影響度を計測 ■ 大きくパフォーマンスが変化しなかった ■ 宿を表現する特徴は相互に関連しており、特徴を 1つ落としても、他の特徴の組み合わせで再 現できてしまうような状況があったのでは ※1 ○ Permutation Test: ある特徴をシャッフルしてパフォーマンスへの影響を計測 ■ 直感的でない結果が得られた ● 例えば予約数を予測するのに一番影響があったのは宿の部屋数だった ● 特徴が全て独立という仮定を置いてしまっているので判断に注意する必要がある ※2 ■ 一方で「役に立たない特徴」をあぶり出すのには使えた ● シャッフルしても影響ない特徴は落してもいい ※1:「テセウスの船のパラドックス(Ship of Theseus paradox)」と表現されている ※2: 実際は、部屋数は値段やゲスト人数やアメニティと相関していると考えられる

Slide 46

Slide 46 text

特徴量選択: TopBot Analysis ● 内製で開発しているTop-bottom analyzerの略 ○ 検索結果の上位と下位の宿に対して特徴の分布を観察し、ランキングへの特徴の影響を可視化 ○ 以下の例では、値段の安い宿ほどランキング上位にいきやすい一方で、レビュー数はランキングに影 響がないことが分かる(料金の方がより重要な特徴)

Slide 47

Slide 47 text

Retrospective ● Airbnbでは”Don’t be a hero”に反して、モデルが複雑化し制御が困難になった ● 一度アーキテクチャを見直し、DNNの特徴を磨くことで過去のモデルを超えながらも効率的に Serveできるモデルができあがった(DNN活用の土俵に立てた)

Slide 48

Slide 48 text

Photo by Etienne Boulanger on Unsplash Improving Deep Learning For Airbnb Search Haldar et al. 2020 (KDD 2020) 3

Slide 49

Slide 49 text

Overview 概要 ● 前論文では「Deepモデルのスタートポイントに立つまで」を書いたが、 その後どのような改善を行ってきたのか、1年間の軌跡をまとめた論文 ● 3つの改良を行い予約数で+1.1%という改善を達成 紹介されている改善 1. ユーザーの求める検索結果への適用※ 2. Cold Start問題の改善 3. 表示位置バイアスの除去 ※ ユーザーは安い宿を好む傾向があるが、これを反映するアーキテクチャの試行錯誤

Slide 50

Slide 50 text

「ユーザーが先、モデルが後」 ● DNNモデルに移行後、様々な事例を参考にしながらアーキテクチャの改善を行ったが、パフォー マンスがなかなか上がらなかった ○ 例えば、クエリと宿の関係をより関連付けて学習するため、 Wide & Deepモデル※1や Attentionベースのモデル※2を試したが、目立った変化は起きなかった ※1: Wide & Deep Learning for Recommender Systems https://dl.acm.org/doi/10.1145/2988450.2988454 ※2: Attention Is All You Need https://papers.nips.cc/paper/7181-attention-is-all-you-need Download paper → Implement → A/B test というループを辞め、 “User lead, model follows”の基本に立ち返ることにした

Slide 51

Slide 51 text

話題1: ゲストは何を求めているのか? ● ランク付けされた料金(の中央値)と予約された料金を比較すると乖離が見られた ⇒ ゲストはより安い宿を望んでいる ● 「より安い宿を提案するようなアーキテクチャは作れるか?」という問いに向き合う 表示されている宿よりも安い料金の宿が予約されている

Slide 52

Slide 52 text

1. Enforcing Cheaper Is Better ● 最初に試したのは、料金特徴を DNNから明示的に分離する手法 ○ 最終層を以下のようにモデル化して、高い料金に対してペナルティのような効果が働くようにしている (w, bはtrainableな重みで、最終的に w=0.33, b=-0.9となった;左図) 料金を特徴から除外 料金に対して単調に応答する関数(学習結果は左図) 平均料金は-5.7%となったが予約数は-1.5%となりビジネス毀損が発生 ● 料金が他の特徴と強く結びついていたため underfitした可能性? ● 実際、Train/TestのNDCGも減少していた

Slide 53

Slide 53 text

2. Generalized Monotonicity ● 次に考えたのは、入力に対して単調に変化する構造の導入 ○ より強い”Cheaper is better”の学習を期待 ① priceに対して単調な入力 ② wightを2乗して中間層への入力が単調になるよう調整  ③ 活性化関数にtanhを使い、単調性を維持 ④ 他の中間層でもweightは2乗することで単調な応答で制約 予約数が-1.6%となり再び失敗

Slide 54

Slide 54 text

3. Soft Monotonicity ● これまでは料金に対して単調に出力が変わるようアーキテクチャを制御してきたが、 入力にヒントだけを与えて、後は DNNの表現力を最大限活かしてあげればいいのでは? ● {予約あり, 予約なし} のペアだけでなく、{料金が安い,料金が高い} という情報を追加 ○ 予約があった宿は上位に、料金が安い宿は上位に、というランク学習になる ○ パラメータαで両者の学習の程度を制御 平均料金は-3.3%となったが、予約数は-0.67%となり引き続きネガティブな結果に

Slide 55

Slide 55 text

試行錯誤を経た状況整理 ● ここまでの結果から「表示する料金は確かに下げられているのに、それがユーザーにとってメリッ トとなっていない」という状況が分かってきた ● 料金に対して検索スコアを plot※すると元のDNNは”cheaper is better”を理解している ⇒ ではなぜそれでもなおユーザーの予約料金の分布は偏っていたのか? ⇒ 問題は表示している宿が高いことではなく、 検索条件(地域)に対して適切な料金の提案がで きていないことではないのか? ※ Individual Conditional Expectation (ICE) plots(以下論文も参照) Peeking Inside the Black Box: Visualizing Statistical Learning With Plots of Individual Conditional Expectation (Goldstein et al 2015) https://doi.org/10.1080/10618600.2014.907095

Slide 56

Slide 56 text

料金差分のDrill Down ● 検索に対して適切な料金提案ができているか確かめるため、地域ごとに料金差を確認 ○ New YorkやSan Franciscoといった人気地域では料金差はほぼ観測されなかった ○ 一方で、Tail Cityで分散が大きかった ⇒原因(の1つ)はTail Cityに対して適切な料金の宿を出せなかったこと 人気の地域は料金の提案と予約料金の差が小さい Tail Cityでの料金乖離が顕著

Slide 57

Slide 57 text

4. Two Tower Architecture ● 検索クエリと結果の関連を正しく学習するため Two Tower Architectureを提案 ○ Pairwiseで学習をするのは同様 ○ ユーザー・クエリに関する DNN出力との距離に対して Lossを定義している 平均料金は-2.3%に、予約数は+0.6%の改善! ● パラメータ数も小さくなり、 Latencyが33%減少する副次的効果も

Slide 58

Slide 58 text

Two Tower Architectureの評価 ● ICE curveは、安い宿に高スコアを与えるだけでなく、特徴的な料金に山をもつ分布に ○ “Cheaper is better” から “Right price for the trip” へ ● 様々なクエリ毎に中央の DNNによる100次元の出力の t-SNE plotを作成※ ○ 料金や地域でクラスタができているわけではなく、宿泊人数(例えば家族旅行か、単独旅行 か)、都市、宿泊日数などの検索文脈によってクラスタが形成されている ※ ラベルは都市名/ゲスト数/宿泊日数、 色は料金(緑ほど安く、青ほど高い) 検索に応じた特徴的な料金帯の山

Slide 59

Slide 59 text

話題2: Cold Start問題の改善 ● 新着宿は、どのようなユーザーが宿泊してきたかという統計情報がない ○ 「十分データのある宿」と「新着宿」を比べると、 NDCGで-6%という大きな開き ○ ゲストのエンゲージメントに関する特徴 ※1を抜くとNDCGは-4.5%の落ち込み ⇒ 新しく登録された宿が土俵に立つのは難しい ● Explore-ExploitそしてのCold Start問題 ○ ゲストは蓄積データを最大限活用( Exploit)することで適切な宿を知りたい ○ プラットフォームとしては、新着宿を露出させることでデータを溜め( Explore)、長期的なユー ザー価値につなげていきたい ○ コストを払ってでも新着宿をブーストしていきたいが許容度もバラバラなはず ※2 ※1: 受け入れてきたゲストに関する情報や宿泊数などの統計 ※2: 例えば、宿が多い人気都市では的外れな新着宿のブーストも気にならないかもしれないが、宿の少ない地域では事情は異なる

Slide 60

Slide 60 text

ユーザーエンゲージメントの予測 ● 新着宿が他の宿と異なるのはエンゲージメント特徴の有無 ⇒新着宿に対して事前にエンゲージメント特徴の影響が予測できれば良い ● エンゲージメント特徴の予測手順 ○ 1億オーダーの検索結果に対して、 Top100の宿から1件ずつランダムサンプル ⇒ 十分閲覧されている宿のデータセットができる ○ サンプルした宿に対してランク と割引ランク を定義する ○ エンゲージメント特徴を抜いて、これらの特徴を予測モデルで補完 ■ このモデルによるランクを とする ○ によってモデルを評価(0に近いほど良い)

Slide 61

Slide 61 text

予測モデルと結果 ● 以下の2モデルを比較した 1. ベースライン: ハンドメイドなデフォルト値(既存で運用していた値) 2. 周辺の宿の平均値: 地理的に近く、タイプが同一の宿の特徴平均 ■ ゲスト人数が2人の新着宿の場合、近くにあるゲスト人数 2人の宿の平均を使う ● オフライン評価: ベースラインに対してエンゲージメント予測の 2乗誤差が42%減少 ● オンライン評価: 新着宿の予約が+14%に改善!(全体でも+0.38%の改善)

Slide 62

Slide 62 text

話題3: Positional Bias ● 新着宿が上位に表示されにくいのと同様、ブティックホテルなどに関しても、 データの少なさが原因で上位に上がりにくくなる仮説があった ○ 学習データ少ないタイプの宿は positional biasによって上位にランクされにくくなる ● これまではユーザーフォーカスで現象を理解しようとしていたが、 暗中模索になってしまったので過去文献に助けを求めることにした

Slide 63

Slide 63 text

Related Work ● ユーザー がクエリ を発行し、 番目に表示された宿 を予約するかどうかは 以下のモデルで表すことができる ※1 ※ Click Models for Web Search (Chuklin et al. 2015) https://doi.org/10.2200/S00654ED1V01Y201507ICR043 : のもと表示された宿 が予約したい宿である確率 (本来求めたいもの) : のもと 番目に表示された宿がクリックされる確率 (モバイル端末でアクセスしていたらあまり深くまで探索されないなどユー ザーとクエリに依存した応答をする)

Slide 64

Slide 64 text

Related Work ● Positional biasの影響を除くには、propensity model を 構築して、訓練データをこの逆数で重み付けすれば良い ※1 ○ 一般的には、counterfactuals を集めるために検索結果に介入(ランダム化など) する必要があるが、今回はそのような介入を行わず実際の検索結果だけを使う ※2 ● この論文ではPropensity modelを頑張って作るのではなく、positionをDNNの入力として直接導 入するアプローチを提案 ※1 Unbiased Learning-to-Rank with Biased Feedback (Joachims et al. 2017) https://dl.acm.org/doi/10.1145/3018661.3018699 ※2 予約できる日数がカレンダーやホスト依存であったりと、同じクエリでも同じ宿は様々な位置に表示されている

Slide 65

Slide 65 text

Position As Control Variable ● Two Tower Modelを以下のようにpositional biasのフレームで解釈する ● ここで、表示位置 への依存を表現 ● が と独立であればpositional biasへの影響はノイズとみなせる ● 実際にランク付けする際には と置くことでバイアスの入らない評価ができる Relevance prediction Positional bias ※ 今回は十分なデータがあるため、これらのノイズは無視できると仮定する

Slide 66

Slide 66 text

Position Dropout ● Position biasは正しく学習できるようになるが、今度は relevance predictionが位置に依存するよ うになり学習が毀損される可能性がある ○ 実際、position featureを入れることでNDCGが1.3%減少 ● そこで、確率的に position featureを0にする dropoutを導入 ○ Dropout rateは、NDCGとのトレードオフを考え0.15に設定 dropoutを入れないとNDCGの精度が落ちる Dropoutを入れすぎるとpositional biasが考慮できなくなる

Slide 67

Slide 67 text

結果 ● positon biasを学習するとオンライン評価で +0.7%の予約数改善があった ● 3つのアプローチを全て導入することで、最終的に +1.1%の予約数改善を実現した But the highlight of our journey is the realization that to push the boundaries of our DNNs, the inspiration was not going to come from some external source. For that we had to follow the lead of our users.

Slide 68

Slide 68 text

まとめ(所感) ● Airbnbの検索モデルの変遷をKDD2018-2020をもとに紹介 ※1 ● 継続的にビジネス価値を生み続けているが、そこには多くの失敗もあった ○ 紹介論文はプロセスや失敗を丁寧に説明している点で学びがあるものだった ● 一貫していたのはモデルを不必要に複雑化させない ※2、ユーザー理解の重要性 の2点 ○ 特に後者は、文献の手法をそのまま導入するサイクルではなく、サービス利用者をちゃんと理解しな がらstep by stepで進めるという点でとても重要 ※3 ※1: dynamic pricingの導入(KDD2018)や多様性の導入(KDD2020)など他にも面白い文献は多かったが今回は3本に絞った ※2: とは言え他のAirbnb論文で提案されている手法は結構複雑だったりするが、    あくまで「腹落ちしてない状態でやみくもに外部知見を取りれるのはやめましょう」という意味で理解 ※3: 自分が関わるサービスでもこうした姿勢を意識していきたい