Upgrade to Pro — share decks privately, control downloads, hide ads and more …

検索結果の品質向上 / Improvement of The Quality of Search Results

85da685d91fda190e2e3162d0de248a4?s=47 Recruit
August 19, 2021

検索結果の品質向上 / Improvement of The Quality of Search Results

2021年度リクルート エンジニアコース新人研修の講義資料です

85da685d91fda190e2e3162d0de248a4?s=128

Recruit

August 19, 2021
Tweet

Transcript

  1. 検索結果の品質向上 守谷 純之介 (株)リクルート プロダクト統括本部 プロダクト開発統括室 プロダクトディベロップメント室 横断エンジニアリングユニット 横断エンジニアリング部 検索ソリューショングループ

    © Recruit Co., Ltd., 2021. 1
  2. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 2
  3. 目標 • プリミティブな検索エンジンを作ってみよう • どのようなデータ構造を採用すればいいの? • どんな実装をすれば良いの? • 分散システムの良いところ・悪いところを、 作って理解しよう

    • 検索品質の改善とは何か?理解しよう • どんなことが問題になるのか? • そもそも品質って何? © Recruit Co., Ltd., 2021. 3
  4. 自己紹介 守谷 純之介(モリヤ ジュンノスケ) • 2002〜2003: ポスドク研究員 • 2003〜2004: ベンチャー企業の何でも屋さん

    • 2004〜2013: ポータルサイトの検索屋さん • 2013〜: リクルート • Qass: 検索チーム • Bazz: 自動応答 Bot © Recruit Co., Ltd., 2021. 4 Compiler が好きです。 何の貢献もできないけど… 著者の Aho & Ullman は 2020年度チューリング賞受賞!! https://awards.acm.org/about/2020-turing
  5. Bazz: 自動応答 Bot © Recruit Co., Ltd., 2021. 5 https://help.jalan.net/s/

  6. Qass: 検索チームのシンプル API サービスを担当 © Recruit Co., Ltd., 2021. 6

    サジェスト or オートコンプリート
  7. Qass: 検索チームのシンプル API サービスを担当 © Recruit Co., Ltd., 2021. 7

    ちょっと変わった検索 Document かわいい 美味しい 和風 Document には 書いていないけど…
  8. Qass: 検索チームのシンプル API サービスを担当 © Recruit Co., Ltd., 2021. 8

    ちょっと変わった検索 Document Document を 分差表現して… [0.23, 0.54,…] [0.22, 0.58,…] ユーザーの好み Document A Document B Document C
  9. コサイン類似度 © Recruit Co., Ltd., 2021. 9 𝑠𝑖𝑚 𝑎, 𝑏

    = cos 𝜃 = 𝑎 ∙ 𝑏 | 𝑎 | ∙ | 𝑏 | 𝑎 𝑏 𝜃 Document A ユーザーの好み
  10. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 10
  11. 今日は扱わない検索 © Recruit Co., Ltd., 2021. 11 The Art of

    Computer Programming, Volume 3: Sorting and Searching The Flexible Pattern Matching in Strings: Practical On-Line Search Algorithms for Texts and Biological Sequences $ grep $ awk $ sed 正規表現
  12. 今日扱う検索 ① © Recruit Co., Ltd., 2021. 12 Introduction to

    Information Retrieval Modern Information Retrieval Information Retrieval: Implementing and Evaluating Search Engines IR=情報検索
  13. 今日扱う検索 ② © Recruit Co., Ltd., 2021. 13 IR=情報検索 情報検索

    :検索エンジンの実装と評価 情報検索の基礎
  14. 今日扱う検索 ③ © Recruit Co., Ltd., 2021. 14 の index

    の index
  15. 今日扱う検索!! © Recruit Co., Ltd., 2021. 15 Java で実装された 検索ライブラリ

    Lucene 利用 利用 Solr 検索エンジン、全文検索
  16. 今日扱う検索!!!!! © Recruit Co., Ltd., 2021. 16 Elasticsearch server Apache

    Solr 入門 株式会社リクルートテクノロジーズ (監修)
  17. 2つの検索 © Recruit Co., Ltd., 2021. 17 特徴\タイプ 逐次検索 Index

    型検索 事前処理 Pros: なし(コスト小) Cons: あり(コスト大) 検索速度 Cons: 時間大 Pros: 時間小 メモリー使用量 Pros: メモリー小 Cons: メモリー大 典型的な手法 grep: • Knuth–Morris–Pratt 法 • Boyer-Moore 法 転置インデックス • N-gramインデックス • 形態素インデックス 全てはユーザー体験向 上の為に!!
  18. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 18
  19. 転置インデックスでの2つのフェーズ © Recruit Co., Ltd., 2021. 19 Search & Indexing

    Apache Book Car Dog … 10, 25 … 2, 57 … 15, 17 …98, 101
  20. Indexing: 事前準備=転置 index の作成 © Recruit Co., Ltd., 2021. 20

    Linuxは、狭義には Linuxカーネル、広義に は… 検索対象 最新版となるLinux4.20 のリリース 転置 index Linux カーネル リリース A B A A B B
  21. Search: AND 検索 © Recruit Co., Ltd., 2021. 21 転置

    index Linux カーネル リリース A A B B 検索クエリ: Linux AND カーネル ∩ Merge [A, B] [B] [B]
  22. Search: OR 検索 © Recruit Co., Ltd., 2021. 22 転置

    index Linux カーネル リリース A A B B 検索クエリ: リリース OR カーネル ∪ Merge [B] [A] [A, B]
  23. Search: マージは大変 © Recruit Co., Ltd., 2021. 23 転置 index

    Linux カーネル リリース A A B B 転置 Index の検索における Merge はコアであり、コストが超高い
  24. 転置 Index (Inverted Index) とは? 1.ドキュメントに含まれる特性 をキー (全文検索などでは Term) にして、集合を紐付け

    るリスト構造 (Posting List) 2.ドキュメントのリストはソー ト済み 3.通常は単語の現れた位置情報 も格納 (フレーズ検索) © Recruit Co., Ltd., 2021. 24 転置 index Linux カーネル リリース A A B B
  25. 目標 • プリミティブな検索エンジンを作ってみよう • どのようなデータ構造を採用すればいいの? • どんな実装をすれば良いの? • 分散システムの良いところ・悪いところを、 作って理解しよう

    • 検索品質を改善してみよう • どんな方法がとれるの? • そもそも品質って何? © Recruit Co., Ltd., 2021. 25
  26. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 26
  27. 2つの検索戦略 © Recruit Co., Ltd., 2021. 27 転置 index Linux

    カーネル リリース A A B B 1. TAAT = Term At A Time 2. DAAT = Document At A Time
  28. 2つの検索戦略 © Recruit Co., Ltd., 2021. 28 転置 index Linux

    カーネル リリース A A B B 1. TAAT = Term At A Time 2. DAAT = Document At A Time
  29. TAAT (Term At A Time) における AND 検索 © Recruit

    Co., Ltd., 2021. 29 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 1.「mmap」の posting list を accumulator に追加: acc0 = [1,5] 2.「Linux」の posting list か ら、次のルールで新しい accumulator acc 1 を作成: acc0 に有 ⇒ 追加 acc0 に無 ⇒ 無視 acc1 = [1, 5] 検索クエリ: Linux AND mmap 要素数の少ない Posting List から開始するのが効率的
  30. TAAT (Term At A Time) における OR 検索 © Recruit

    Co., Ltd., 2021. 30 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 1.「mmap」の posting list を accumulator に追加: acc0 = [1,5] 2.「Linux」の posting list を accumulator に追加: acc1 = [1, 3, 5, 6] 検索クエリ: Linux OR mmap 効率的な方法はない…
  31. 2つの検索戦略 © Recruit Co., Ltd., 2021. 31 転置 index Linux

    カーネル リリース A A B B 1. TAAT = Term At A Time 2. DAAT = Document At A Time
  32. DAAT (Document At A Time) の基本 © Recruit Co., Ltd.,

    2021. 32 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 1 1 1 2 3 3 4 5 5 6 6 7 • TAAT は横串 • DAAT は縦串
  33. DAAT (Document At A Time) における AND 検索 © Recruit

    Co., Ltd., 2021. 33 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 • Term 毎にカーソルを準備 • 各カーソルを移動し、共通の ドキュメントを発見したら、 accumulator に追加 検索クエリ: Linux AND mmap acc = []
  34. DAAT (Document At A Time) における AND 検索 © Recruit

    Co., Ltd., 2021. 34 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 • Term 毎にカーソルを準備 • 各カーソルを移動し、共通の ドキュメントを発見したら、 accumulator に追加 検索クエリ: Linux AND mmap acc = [1]
  35. DAAT (Document At A Time) における AND 検索 © Recruit

    Co., Ltd., 2021. 35 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 • Term 毎にカーソルを準備 • 各カーソルを移動し、共通の ドキュメントを発見したら、 accumulator に追加 検索クエリ: Linux AND mmap acc = [1]
  36. DAAT (Document At A Time) における AND 検索 © Recruit

    Co., Ltd., 2021. 36 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 • Term 毎にカーソルを準備 • 各カーソルを移動し、共通の ドキュメントを発見したら、 accumulator に追加 検索クエリ: Linux AND mmap acc = [1, 5]
  37. DAAT (Document At A Time) における OR 検索 © Recruit

    Co., Ltd., 2021. 37 50,241件 10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 ① ② 1 1 1 2 3 3 4 5 5 6 6 7 • Term 毎にカーソルを準備して、 全ての要素を重複なく追加 検索クエリ: Linux OR mmap 効率的な方法はない…
  38. TAAT vs DAAT © Recruit Co., Ltd., 2021. 38 50,241件

    10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 1 1 1 2 3 3 4 5 5 6 6 7 • メモリ使用量が多いのは TAAT • OR 検索では差異なし • かなりプリミティブな作り
  39. TAAT vs DAAT © Recruit Co., Ltd., 2021. 39 50,241件

    10,320件 30,483件 500,020件 UNIX BSD mmap kernel Linux 520件 1 1 1 2 3 3 4 5 5 6 6 7 S. Ding and T. Suel. Faster top-k document retrieval using block-max indexes. In Proceedings of the 34th Annual International ACM SIGIR Conference on Research and development in Information Retrieval, pages 993-1002, 2011. ↑の成果は Lucene 8 (2019/3/14 リリース) で実装 • https://fosdem.org/2019/schedule/event/apache_lucene_solr_8/attachments/slides/3325/export/events/attachments/apache_lucene_so lr_8/slides/3325/SchindlerLucene8Slides.pdf • https://medium.com/@mocobeta/lucene-8-%E3%81%AE-top-k- %E3%82%AF%E3%82%A8%E3%83%AA%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B7%E3%83%B3%E3%82 %B0%E6%9C%80%E9%81%A9%E5%8C%96-1-%E5%B0%8E%E5%85%A5%E7%B7%A8-5a6387076e8e 今でも効率的なアルゴリズムの研究が続いている
  40. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 40
  41. 実装することなんてあるの? © Recruit Co., Ltd., 2021. 41 Java で実装された 検索ライブラリ

    Lucene 利用 利用 Solr 検索エンジン、全文検索 No… since 2010 since 2004 since 1999
  42. Lucene © Recruit Co., Ltd., 2021. 42 • 転置インデックスを提供 •

    検索の戦略は DAAT • 検索の非常にネイティブな機能のみ提供 • 様々な検索機能 Boolean Query, Range Query、Fuzzy Query • スコアリング機能 設計が非常に優秀な証ですね。 since 1999
  43. Lucene がベースにしているアーキテクチャを知ろう! © Recruit Co., Ltd., 2021. 43 Data Structure?

    Where and How?
  44. Lucene がベースにしているアーキテクチャを知ろう! © Recruit Co., Ltd., 2021. 44 Data Structure?

    Where and How?
  45. 一般的な index のデータ構造 © Recruit Co., Ltd., 2021. 45 •

    B木(B-tree) • B+木(B+-tree) • B*木(B*-tree) • Skip-List
  46. Posting List (Skip List) © Recruit Co., Ltd., 2021. 46

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 291 53395 53395 ものすごく疎な部分がある
  47. Posting List (Skip List) © Recruit Co., Ltd., 2021. 47

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 291 53395 53395 ものすごく疎な部分がある
  48. Posting List (Skip List) © Recruit Co., Ltd., 2021. 48

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 291 53395 53395 ものすごく疎な部分がある 53,392回も比較する!?
  49. Posting List (Skip List) © Recruit Co., Ltd., 2021. 49

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 183 291 291 53395 53395 53395 53395 53395 53395 特定の間隔でジャンプ(Skip) する冗長なリストをもつ
  50. Posting List (Skip List) © Recruit Co., Ltd., 2021. 50

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 183 291 291 53395 53395 53395 53395 53395 53395
  51. Posting List (Skip List) © Recruit Co., Ltd., 2021. 51

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 183 291 291 53395 53395 53395 53395 53395 53395
  52. Posting List (Skip List) © Recruit Co., Ltd., 2021. 52

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 183 291 291 53395 53395 53395 53395 53395 53395
  53. Posting List (Skip List) © Recruit Co., Ltd., 2021. 53

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 183 291 291 53395 53395 53395 53395 53395 53395
  54. Posting List (Skip List) © Recruit Co., Ltd., 2021. 54

    4,820,483件 93,832,732件 car book 0件 53,392件 1 3 3 183 183 291 291 53395 53395 53395 53395 53395 53395 見回る回数が少ない!! ※ スキップの段数に依存 ※ スキップの間隔に依存
  55. Lucene の Posting List (Skip List) © Recruit Co., Ltd.,

    2021. 55 • https://github.com/apache/lucene/blob/main/lucene/core/src/java/org/apache/lucene/codecs/MultiLevelSkipListWriter.java • https://github.com/apache/lucene/blob/main/lucene/core/src/java/org/apache/lucene/codecs/MultiLevelSkipListReader.java * Example for skipInterval = 3: * c (skip level 2) * c c c (skip level 1) * x x x x x x x x x x (skip level 0) * d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d (posting list) * 3 6 9 12 15 18 21 24 27 30 (df) * * d – document * x - skip data * c - skip data with child pointer
  56. Lucene の Posting List (Skip List) © Recruit Co., Ltd.,

    2021. 56 Apache Lucene - Index File Formats
  57. 一般的な index のデータ構造 © Recruit Co., Ltd., 2021. 57 •

    B木(B-tree) • B+木(B+-tree) • B*木(B*-tree) • Skip-List
  58. B+木 © Recruit Co., Ltd., 2021. 58 • 葉ブロックがデータを表す •

    内部ブロックは index(データをもたない) • 条件「各ブロックは a 個以上 b 個以下(例では2個以上3個以下)のエントリを必ずもつ」 を満たすように、木の構造を変形する • 範囲指定のクエリに対して、強力に動作 • ブロックデバイス(葉ブロックと内部ブロックを格納)との相性が抜群 30 50 7 12 22 30 39 52 55 73 内部ブロック 葉ブロック 15以上?
  59. ブロックデバイス © Recruit Co., Ltd., 2021. 59 • ブロック単位で読み書き •

    ブロックの大きさはブロックサイズ • ブロックサイズは結構大きい(Linux のデフォルトは 4 KB) • 1 bit 書き換えても、ブロックごと書き換えられる 残念ながら SSD も ブロックデバイス
  60. Lucene がベースにしているアーキテクチャを知ろう! © Recruit Co., Ltd., 2021. 60 Data Structure?

    Where and How?
  61. ブロックデバイス?メモリーの間違いでは? © Recruit Co., Ltd., 2021. 61

  62. 無邪気にメモリーには置けない… © Recruit Co., Ltd., 2021. 62 揮発

  63. 他にもすることがある!Search のマージは大変 © Recruit Co., Ltd., 2021. 63 転置 index

    Linux カーネル リリース A A B B 転置 Index の検索における Merge はコアであり、コストが超高い
  64. それではどうするのか? © Recruit Co., Ltd., 2021. 64

  65. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 65 • 転置インデックスの構造を知る

    • Indexing と Search のフェーズが分離されていることを知る • 転置インデックス上での検索の動作原理を実装していみる • 永続的なインデックスの保存方法を知る(一旦、ファイルに保存してみよう) • メモリー上への配置は結構時間がかかることを知る 課題のゴール
  66. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 66 • Python

    3 系ならば Good • Python 2 系でも OK • 環境を整えてみたかったら、 pyenv がお勧め Python の実行環境 課題の参考資料をダウンロード • practice-2021-01-inverted-index.tgz をダウンロード • 中身はまだ見ないでね♪ • 酷いプログラムなので、社会人生活では参考にするのをやめよう!
  67. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 67 • 転置インデックスを実装して、AND

    と OR 検索してみよう • 転置インデックスをファイルに保存でき るようにしよう • 2つのフェーズを実装 • インデックス作成フェーズ • 検索フェーズ • 検索の戦略は TAAT で OK 課題 00000 00001 00002 00003 FFFFF 00001 Python の辞書ファイル Posting List のファイル(index) 10〜50個 00024 00001 00001 00099 00032 00033 00055 00025
  68. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 要求される仕様 • ファイルに保存できること

    • Term は擬似的に 0〜F の長さ 5 の全ての組合 せ(00000 〜 FFFFF で総数 1,048,576 = 16^5) • ドキュメントの ID は 0 〜 100 をランダムに生 成 • 各 Term は 10 個から 50 個のランダムな個数 のドキュメントをもつ 00000 00001 00002 00003 FFFFF 00001 Python の辞書ファイル Posting List のファイル(index) 10〜50個 00024 00001 00001 00099 00032 00033 00055 00025
  69. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 要求される仕様 • ファイルに保存できること

    • Term は擬似的に 0〜F の長さ 5 の全ての組合 せ(00000 〜 FFFFF で総数 1,048,576 = 16^5) • ドキュメントの ID は 0 〜 100 をランダムに生 成 • 各 Term は 10 個から 50 個のランダムな個数 のドキュメントをもつ 00000 00001 00002 00003 FFFFF 00001 Python の辞書ファイル Posting List のファイル(index) 10〜50個 00024 00001 00001 00099 00032 00033 00055 00025
  70. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 70 参考資料の解説① •

    mmap_* は見ないでね • 「課題が分からん!」という人(多分、 皆さんそうかも…)は以下を参考に • dic_index.py • dic_search.py • dic_* は「python のオブジェクトを ファイルに保存」版 • ゴールは「Posting List のファイルを 普通の文字列のファイル」にしてみる こと • 「Python の辞書ファイル」はそのまま 「Python のオブジェクトをファイルに 保存」でも OK です • 以下は、その実装の一例になります: • file_index.py • file_search.py 00000 00001 00002 00003 FFFFF 00001 Python の辞書ファイル Posting List のファイル(index) 10〜50個 00024 00001 00001 00099 00032 00033 00055 00025
  71. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 71 参考資料の解説② •

    index.py • 課題のキーワードと Posting List を作ってくれるクラス • ここは面倒、という方は使ってもらって OK • search.py • Posting List に対して、AND と OR 検索を提供するクラス • ものすごくはっしょってあり、set を使って楽しています • TAAT を仮定しています • TAAT と DAAT に興味があった人は、DAAT を実装するのも OK (Level5)
  72. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 72 参考資料の解説③ •

    dic_index.py と dic_search.py の使い方 # インデックス生成 $ ./index.py # 検索(検索対象は ) $ ./search.py
  73. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 73 参考資料の解説④ 作業時は、生成するサイズを小さくしましょう!!

    (時間がかかるので…) index.py の NUM_OF_KEYWORDS を小さくすれば OK
  74. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 74 参考資料の解説⑤ •

    file_index.py で採用したデータ構造 000FF 00012 0003200036…00093¥n Term 保持している ドキュメントの個数 5桁の ドキュメント ID 改行コード
  75. Practice①: 転置インデックスを実装してみよう © Recruit Co., Ltd., 2021. 75 課題のレベル •

    Level0: dic_index.py と dic_search.py を実行して中身をみて、「課題が何なのか?」だけでも知る • Level1: 疲れたので、file_index.py と file_search.py を実行だけしてみる • Level2: file_index.py と file_search.py を参考に作ってみる(完成しなくても OK) • Level3: 保存される Posting List のフォーマットが見にくいので、変えてみる • Level4: 自力で file_index.py と file_search.py を作る • Level5: TAAT ではなく、DAAT で検索を書き換える(search.py)
  76. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 76
  77. 実際はどうなの? © Recruit Co., Ltd., 2021. 77

  78. Lucene がベースにしているアーキテクチャを知ろう! © Recruit Co., Ltd., 2021. 78 Data Structure?

    Where and How?
  79. mmap © Recruit Co., Ltd., 2021. 79

  80. mmap © Recruit Co., Ltd., 2021. 80 • システムコール •

    システムコールだけど、ユーザープロセスの 仮想アドレス空間に作成されるので、コンテ クストスイッチが少ない: (ユーザー空間 vs カーネル空間) • メモリマップトファイルとして扱えるので、 追加・削除・更新が楽 • 複数のプロセス間で共有もできる • 【注意】Java の世界から逸脱している (Java のヒープ外でアロケートされてる) • 【おまけ】C で malloc すると内部では mmap が呼ばれる
  81. mmap © Recruit Co., Ltd., 2021. 81 0x00000 実メモリ 0x00000

    プロセスA 実アドレス 0x00000 プロセスB 仮想アドレス 仮想アドレス ファイル
  82. Elasticsearch の推奨設定 © Recruit Co., Ltd., 2021. 82 “The standard

    recommendation is to give 50% of the available memory to Elasticsearch heap, while leaving the other 50% free. It won’t go unused; Lucene will happily gobble up whatever is left over.” 【注意】Java の世界から逸脱している(Java のヒープ外でアロケートされてる)
  83. Lucene の index 格納 © Recruit Co., Ltd., 2021. 83

    https://lucene.apache.org/core/8_0_0/core/org/apache/lucene/store/FSDirectory.html org.apache.lucene.store(3種類選べる) 1. SimpleFSDirectory.java • java.nio.ByteBuffer 2. NIOFSDirectory.java • java.nio.ByteBuffer 3. MMapDirectory.java • java.nio.MappedByteBuffer
  84. Indeed の独自実装: util-mmap © Recruit Co., Ltd., 2021. 84 MappedByteBuffer

    の既知の制約を克服: – 安全にアンマップできない – サイズが 2GB (int) を超えるファイルをマップできない – スレッドセーフではない • https://jp.engineering.indeedblog.com/blog/2015/02/util-mmap- %E3%81%A7%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%9E%E3%83%83%E3%83%94%E3%83 %B3%E3%82%B0/ • https://github.com/indeedeng/util/tree/master/mmap
  85. おまけ: それでも Disk からデータは引き出す © Recruit Co., Ltd., 2021. 85

    • 一番検索で良く使うのは検索結果 • ブロックサイズを意識して格納 • ディスクへのアクセスは猛烈に遅いが ディスクキャッシュは早い • トレードオフが十分ならば圧縮して格納する
  86. おまけ: 圧縮のトレードオフ © Recruit Co., Ltd., 2021. 86 読み込み完了 100MB/s

    5,000KB 50ms 25ms 30GB/s =30,720MB/s 2,500KB 50%圧縮 読み込み完了 15ms 10ms=解凍 300倍位速い!
  87. Luceneで利用できる圧縮方式 © Recruit Co., Ltd., 2021. 87 LZ4 • https://lucene.apache.org/core/8_0_0/core/org/apache/lucene/codecs/lucene50/Lucene50StoredFieldsFormat.html

    • https://gigazine.net/news/20120824-dragonquest-backstage-cedec2012/ • 圧縮率は低いが、圧縮速度が速い • 色々なところで使われている: – OS: Linux, FreeBSD – Hadoop, Cassandra – Nintendo Switch – ドラゴンクエストXのセーブデータ ふっかつのじゅもん あおういえ いうあおえ えいあうお うおあいえ うおあいえ おえいうお
  88. Practice②: 転置インデックスを mmap で実装してみよう © Recruit Co., Ltd., 2021. 88

    • 転置インデックスを mmap で実装し、共有できることを知ろう(共有メモリ) • Update して、他のプロセスからどう見えるか?知ろう 課題のゴール
  89. Practice②: 転置インデックスを mmap で実装してみよう © Recruit Co., Ltd., 2021. 89

    要求される仕様 • 扱う index は Practice①と同じ • 簡単な http サーバーを立ち上げて、検索と update が出来るようにしよう • update は Posting List の内容を入れ替えて見る (追加・削除はせず、入れ替え)だけで OK • 検索は • /and?term=AAAAA,BBBBBで AND 検索 • /or?term=AAAA,BBBBBで OR 検索 • Update は • /update?term=AAAAA&old=00023&ne w=00032 で 00023 を 00032 へ update • 複数プロセスを立ち上げて、それぞれ検索し、他 のプロセスが update した内容が反映されるのを 確かめよう • Posting List を mmap で実装しよう Index
  90. Practice②: 転置インデックスを mmap で実装してみよう © Recruit Co., Ltd., 2021. 90

    参考資料の解説① • file_index.py と file_search.py とかなり似通った作りになります。 • update 機能は別途切り出して mmap_update.py 等を作成(同名ファイルがあるので注意!) • 新たに http サーバーを作りますが、面倒ならば、mmap_server.py をご参考に • mmap_server.py で各リクエストに対して、mmap_index.py, mmap_search.py, mmap_update.py が動くイメージ
  91. Practice②: 転置インデックスを mmap で実装してみよう © Recruit Co., Ltd., 2021. 91

    参考資料の解説② • 課題のゴールは以下の作成: • mmap_index.py(インデックス作成自体は、実はしていません。file_index.py が出力したファイルで OK) • mmap_search.py • mmap_update.py • mmap_server.py
  92. Practice②: 転置インデックスを mmap で実装してみよう © Recruit Co., Ltd., 2021. 92

    参考資料の解説② • mmap_server.py の使い方 # サーバー立ち上げ(port 番号指定) $ ./mmap_server.py 8000 & # サーバー停止 $ fg (して、Ctrl-C) # ブラウザ • http://localhost:8000/and?term=AAAAA,BBBBB • http://localhost:8000/or?term=AAAAA,BBBBB • http://localhost:8000/update?term=AAAAA&old=00096 &new=00097
  93. Practice②: 転置インデックスを mmap で実装してみよう © Recruit Co., Ltd., 2021. 93

    課題のレベル • Level0: mmap_server.py を実行して中身をみて、「課題が何なのか?」だけでも知る • Level1: 疲れたので、mmap_server.py で遊ぶ • Level2: 複数サーバーを立ち上げて、共通メモリの動作を学ぶ • Level3: mmap_index.py と mmap_search.py を作る • Level4: サーバーを自力で作る • Level5: 全部自力で作る # サーバーを複数立ち上げ $ ./mmap_server.py 8000 & $ ./mmap_server.py 8001 & $ ./mmap_server.py 8002 & # あるサーバーから update を実行して、 # 他のサーバーので検索結果が変化するのを確認
  94. Lucene がベースにしているアーキテクチャを知ろう! © Recruit Co., Ltd., 2021. 94 Data Structure?

    Where and How?
  95. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 95
  96. マルチプロセスというか、そもそも1台に置けないのですけど… © Recruit Co., Ltd., 2021. 96

  97. Solr や Elasticsearch は何を提供してくれているの? © Recruit Co., Ltd., 2021. 97

    • RESTfull なAPIの提供 • 管理機能の提供 • クラスタリング機能を提供
  98. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 98
  99. 50,241件 10,320件 520件 30,483件 500,020件 1. 同じキーが同じサーバーにいる必要がない ⇒ mmap が別のサーバーにあっても良い【分散】

    2. マージさえできればよい ⇒ mmap が複数のサーバーにあってもよい【重複】 UNIX BSD mmap kernel Linux 分散検索 © Recruit Co., Ltd., 2021. 99
  100. 分散検索: indexing UNIX mmap Linux UNIX mmap Linux UNIX mmap

    Linux © Recruit Co., Ltd., 2021. 100
  101. 分散検索: 概念(Elasticsearch の用語にて) • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 •

    可用性(Availability) • 負荷分散(Load Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! © Recruit Co., Ltd., 2021. 101
  102. 分散検索: ノード • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 • 可用性(Availability)

    • 負荷分散(Load Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! © Recruit Co., Ltd., 2021. 102
  103. 分散検索: シャード • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 • 可用性(Availability)

    • 負荷分散(Load Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! A Shard C Shard B Shard C Shard A Shard B Shard 103 © Recruit Co., Ltd., 2021.
  104. • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 • 可用性(Availability) • 負荷分散(Load

    Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! シャード A, B, C 全部が生存 欠損なしで 検索続行 分散検索: 可用性(Availability) 104 A Shard C Shard B Shard C Shard A Shard B Shard ✗
  105. • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 • 可用性(Availability) • 負荷分散(Load

    Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! シャード A と B に関する 検索 シャード A と B に関する 検索 シャード A と B に関する 検索 105 A Shard C Shard B Shard C Shard A Shard B Shard 分散検索: 負荷分散(Load Balance)
  106. • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 • 可用性(Availability) • 負荷分散(Load

    Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! hash(XXX) mod (# of Shard) = C Doc ID: XXX 106 A Shard C Shard B Shard C Shard A Shard B Shard 分散検索: ルーティング
  107. 分散検索 • 各サーバーをノードと呼ぶ • 各ノードは複数のシャード(部分index)をもつ • シャードは以下を提供 • 可用性(Availability) •

    負荷分散(Load Balance) • ドキュメント単位でルーティング • どのシャードに格納するのかは、あなた次第! 107 A Shard C Shard B Shard C Shard A Shard B Shard
  108. 分散検索: Index の構成 • サーバー(シャード)は本来非常に多い(ここでは3台) • シャードに含まれるドキュメント数には上限有り(100万等) • どのサーバーも、自分の担当の検索は非常に高速(対象が100万位しかないから) •

    入り切らなくなってきたら、サーバーを足す (スケールアップではなく、スケールアウト) < 1000,000 < 1000,000 < 1000,000 © Recruit Co., Ltd., 2021. 108 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円
  109. 分散検索: Two Phase Search, query and fetch • query phase:

    どのサーバーにマッチする結果がどれだけあるのか? ⇒ メモリ上+ネットワークトラフィック小で解決 • fetch phase: 見つけた結果を整形(スニペット生成、等)して返却結果を作成 ⇒ 高負荷な処理を実行 109 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  110. 分散検索: Two Phase Search, query and fetch 【重要】各サーバは他のサーバーの安いアイスクリームを知らない!! クエリー:アイスクリーム ORDER

    BY 安い順 LIMIT 3 110 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  111. 分散検索: Two Phase Search, query and fetch クエリー:アイスクリーム ORDER BY

    安い順 LIMIT 3 [50, 120, 200] [10, 220, 320] [300, 500, 720] [10, 50, 120] 111 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  112. 分散検索: Two Phase Search, query and fetch クエリー:アイスクリーム ORDER BY

    安い順 LIMIT 3 [10, 50, 120] 112 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  113. 分散検索: Two Phase Search, query and fetch Q: 100位〜102位まで取ってくるには? クエリー:アイスクリーム

    ORDER BY 安い順 LIMIT 3 OFFSET 100 A: 各サーバーから102件取得してくる 113 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  114. 分散検索: Two Phase Search, query and fetch Q: 嘘でしょ? クエリー:アイスクリーム

    ORDER BY 安い順 LIMIT 3 OFFSET 100 A: 本当です。 114 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  115. 分散検索: Two Phase Search, query and fetch Q: 事前に準備とかできないの? クエリー:アイスクリーム

    ORDER BY 安い順 LIMIT 3 OFFSET 100 A: できないです… 115 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  116. 分散検索: Two Phase Search, query and fetch クエリー:(アイスクリーム AND すいか味)ORDER

    BY 安い順 LIMIT 3 OFFSET 100 116 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021.
  117. 分散検索: Two Phase Search, query and fetch クエリー:(アイスクリーム AND すいか味)ORDER

    BY 安い順 LIMIT 3 OFFSET 100 117 Shard A アイスクリーム 200円 50円 850円 120円 Shard B アイスクリーム 320円 220円 10円 900円 Shard C アイスクリーム 850円 300円 500円 720円 © Recruit Co., Ltd., 2021. 【重要】もちろんキャッシュを使えて、最重要!
  118. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 118
  119. Practice③: 分散検索を実装してみよう © Recruit Co., Ltd., 2021. 119 • 分散検索がどのように動くのか?理

    解しよう • 可用性を上げるにはどうしたらよい か?体験しよう • スケールすると(インデックスサイ ズが大きくなると)何が大変になる か?理解しよう 課題のゴール Index
  120. Practice③: 分散検索を実装してみよう © Recruit Co., Ltd., 2021. 120 要求される仕様 •

    扱う index は Practice②と同じ • 通信は http • 分散検索は • /and?term=AAAAA,BBBBBで AND 検索 • /or?term=AAAA,BBBBBで OR 検索 • 分散させずに、ローカルで解決する検索は • /_and?term=AAAAA,BBBBBで AND 検索 • /_or?term=AAAA,BBBBBで OR 検索 • マージ処理(実際の AND と OR の処理)はリク エストを受け取ったサーバーで OK • 分散検索時には、各ノードで一つの term に対す る処理(単に Posting List を返すだけの処理)だ け行えば OK(_and でも _or でもどちらを使っ ても構わない) • term に従ってサーバーを固定してみる Index
  121. Practice③: 分散検索を実装してみよう © Recruit Co., Ltd., 2021. 121 参考資料の解説① •

    mmap_server.py と mmap_search.py を改造すれば OK • /_and と /_or は mmap_server.py の AND 処理と OR 処理と同じ • 今回のサーバーは ThreadingHTTPServer を使わないと詰まってしまう(何故か?は調べてみて下さい) • NODE は固定で OK NODES = [ 'localhost:8000’, 'localhost:8001’, 'localhost:8002’, ] • and のリクエストを受け取ると、各 term 毎に Posting List を各サーバーに http で要求し、全ての結果をマージ(AND or OR)する • mmap_server.py の変更点: • _and と _or はこれまでの and と or • /and と /or を新たに追加 • mmap_server.py の変更点: • 新たに分散検索を行う search と同じ機能(候補の Posting List のリスト)を実装
  122. Practice③: 分散検索を実装してみよう © Recruit Co., Ltd., 2021. 122 課題のレベル •

    Level0: dist_server.py を実行して中身をみて、「課題が何なのか?」だけでも知る • Level1: 疲れたので、dist_server.py で遊ぶ • Level2: ログが分かりにくいので、分かりやすくする • Level3: dist_server.py を作る • Level4: dist_serarch.py を作る • Level5: 1台サーバーを落としても、動作するように変更する • Level6: 各サーバーへのリクエストを非同期で投げる • Level∞: サーバー単位でインデックスを分割してみよう これであなたのサーバーも Elasticsearch!! # サーバーを複数立ち上げ $ ./dist_server.py 8000 & $ ./dist_server.py 8001 & $ ./dist_server.py 8002 & # あるサーバーから search を実行して、 # 各サーバーがリクエストを受け取り、 # これまでと結果が変わらないことを確認
  123. ちゃんと 話していないこと① © Recruit Co., Ltd., 2021. 123

  124. 「Python の辞書を使ったら反則では?」 © Recruit Co., Ltd., 2021. 124 すみません… 反則です…

    折角なので、耳寄りな情報を
  125. 「もっているか?否か?」の効率的な判定 © Recruit Co., Ltd., 2021. 00000 00001 00002 00003

    FFFFF 00001 Python の辞書ファイル Posting List のファイル(index) 00024 00001 00001 00099 00032 00033 00055 00025 125 • 結構サイズが大きい • 必要ない機能も色々ある • 嘘でもいいから、もっと速く小 さく!
  126. Bloom フィルター © Recruit Co., Ltd., 2021. 126 ブルームフィルターに問い合わせて… •

    「結果が有る」と言ったら、嘘かもしれない • 「結果が無い」と言ったら、本当に無い サイズはとても小さい!! Oracle で利用可能
  127. Bloom フィルターの動作原理:作成 © Recruit Co., Ltd., 2021. 127 x x

    x x x x x x x x 「ア」登録 x x x x x x x x x x
  128. Bloom フィルターの動作原理:作成 © Recruit Co., Ltd., 2021. 128 x x

    x x x x x 「イ」登録 x x x x x x x x x x x x x x
  129. Bloom フィルターの動作原理:問い合わせ © Recruit Co., Ltd., 2021. 129 x x

    x x x 「I」は有る? x x x x x x x x x x x x x x 有る!(嘘)
  130. Bloom フィルターの動作原理:問い合わせ © Recruit Co., Ltd., 2021. 130 x x

    x x x 「ー」は有る? 無い!(本当) x x x x x x x x x x x x x x
  131. ちゃんと 話していないこと② © Recruit Co., Ltd., 2021. 131

  132. Term (転置インデックスのキー) © Recruit Co., Ltd., 2021. 132

  133. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 133
  134. © Recruit Co., Ltd., 2021. 134 転置インデックス 50,241件 10,320件 30,483件

    UNIX BSD mmap kernel Linux 520件 1 1 1 2 3 3 4 5 5 6 6 7 500,020件
  135. TokenStream = Term(= 文字列 + フィールド)の stream + アトリビュー ト

    • https://github.com/apache/lucene/blob/main/lucene/core/src/java/org/apache/lucene/index/Term.java • https://github.com/apache/lucene/blob/main/lucene/core/src/java/org/apache/lucene/analysis/TokenStream.java これはどう作るの?! Lucene の世界では Tokenizer が分割をしてくれる! © Recruit Co., Ltd., 2021. 135 Lucene の世界の Term と Token
  136. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 136 Lucene の Tokenizer
  137. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 137 Lucene の Tokenizer
  138. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 138 Lucene の Tokenizer
  139. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 139 Lucene の Tokenizer
  140. 英語の Tokenize は超簡単 “Elasticsearch is a distributed, RESTful search and

    analytics engine capable of solving a growing number of use cases.” WhitespaceTokenizer “Elasticsearch is a distributed, RESTful search and analytics engine capable of solving a growing number of use cases.” © Recruit Co., Ltd., 2021. 140
  141. 日本語の Tokenize は… “Elasticsearchは、様々なユースケースを解決する、分散型RESTful 検索/分析エンジンです。” ? “Elasticsearchは、様々なユースケースを解決する、分散型RESTful 検索/分析エンジンです。” 単純には分割できない ?

    ? © Recruit Co., Ltd., 2021. 141
  142. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 142 Lucene の Tokenizer
  143. Ngram Tokenizer 一定の長さの文字列単位で分割「敵に塩を送る」 • Unigram: 1文字単位 ⇒ 「敵」「に」「塩」「を」「送」「る」 • Bigram:

    2文字単位 ⇒「敵に」「に塩」「塩を」「を送」「送る」 • Trigram: 3文字単位 ⇒「敵に塩」「に塩を」「塩を送」「を送る」 Q: Bigram で「塩」を検索可能?! A: No… 検索できない ⇒ N-gram ならば 2-1gram © Recruit Co., Ltd., 2021. 143
  144. Ngram Tokenizer: 比較 Unigram vs Trigram 「敵に塩を」 • 長さ3以上の term

    ならできることに変わりはなし(「塩」は検索できない) • どんどん大きくなると、完全一致のようになり、検索とは何か? という問題になる(6-gramでは「敵に塩を送」さえ検索できない) • 速度には差がでる(Unigram より Trigram の方が速い) 4個タームのマージ vs 2個のタームのマージ 「敵」「に」「塩」「を」vs 「敵に塩」「に塩を」 ※「に」「を」のPosting List などは非常に大きい(はず) © Recruit Co., Ltd., 2021. 144
  145. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 145 Lucene の Tokenizer
  146. Japanese Tokenizer (Kuromoji) • 形態素解析エンジン • 辞書ベースで分割 • 「敵に塩を送った」 Surface

    form Part-of-Speech Base form Reading Pronunciati on 敵 名詞,一般,*,* 敵 テキ テキ に 助詞,格助詞,一般,* に 二 二 塩 名詞,一般,*,* 塩 シオ シオ を 助詞,格助詞,一般,* を ヲ ヲ 送っ 動詞,自立,*,* 送る オクッ オクッ た 助動詞,*,*,* た タ タ © Recruit Co., Ltd., 2021. 146
  147. Ngram vs 形態素解析 それぞれ、良いところと悪いところがある 解決策:両方をもつハイブリッド index 効果\手法 Ngram 形態素解析 取りこぼし:

    「目黒」で「中目黒」は hit? Good! = hit Bad… = No hit レレバンシー: 「京都」で「東京都」が hit? Bad… = hit Good! = No hit Index サイズ Bad… = 大 Good! = 小 © Recruit Co., Ltd., 2021. 147
  148. Sudachi(形態素解析機) 最近は「sudachi」が人気 © Recruit Co., Ltd., 2021. 148 https://github.com/WorksApplications/Sudachi •

    A: 医薬/品/安全/管理/責任/者 • B:医薬品/安全/管理/責任者 • C:医薬品安全管理責任者
  149. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 149 Lucene の Tokenizer
  150. Unicode のノーマライズ これは、検索に限らずどこでも使う!! (一般的なプログラミング言語全てで提供。ICU、ありがとう!) • ABC ⇒ ABC • トウキョウ

    ⇒ トウキョウ • ㌀ ⇒ アパート © Recruit Co., Ltd., 2021. 150
  151. • ClassicTokenizerFactory • EdgeNGramTokenizerFactory • HMMChineseTokenizerFactory • ICUTokenizerFactory • JapaneseTokenizerFactory

    • KeywordTokenizerFactory • LetterTokenizerFactory • LowerCaseTokenizerFactory • NGramTokenizerFactory • PathHierarchyTokenizerFactoryPatternTokenizerFactory • StandardTokenizerFactory • ThaiTokenizerFactory • UAX29URLEmailTokenizerFactory • UIMAAnnotationsTokenizerFactory • UIMATypeAwareAnnotationsTokenizerFactory • WhitespaceTokenizerFactory • WikipediaTokenizerFactory © Recruit Co., Ltd., 2021. 151 Lucene の Tokenizer 「京都」で「東京都」
  152. © Recruit Co., Ltd., 2021. 152 Lucene の Tokenizer 「京都」

    で 「東京都」
  153. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 153
  154. Precision and Recall © Recruit Co., Ltd., 2021. 154 適合率と再現率

    理想と現実
  155. 適合率と再現率 Precision and Recall 検索結果が 適合性:現実における理想の割合 再現性:理想における現実の割合 © Recruit Co.,

    Ltd., 2021. 155
  156. 理想の検索結果 C 実際の検索結果 B A 再現率= C A 適合率= B

    A © Recruit Co., Ltd., 2021. 156 適合率と再現率
  157. 意味:どれほど正確か?=正確性=ノイズを含まない比率 実際の検索結果(B)に理想の結果(A)が含まれている割合 理想の検索結果 C 実際の検索結果 B A © Recruit Co.,

    Ltd., 2021. 157 再現率= C A 適合率= B A 適合率
  158. 意味:どれほど網羅しているか?網羅性=取りこぼしが少ない比率 理想の検索結果(C)の内、実際の検索結果として取得できた(A)割合 理想の検索結果 C 実際の検索結果 B A © Recruit Co.,

    Ltd., 2021. 158 再現率= C A 適合率= B A 再現率
  159. • 適合率:正確性=ノイズを含まない比率 • 再現率:網羅性=取りこぼしが少ない比率 理想の検索結果 C 実際の検索結果 B A 再現率=

    C A 適合率= B A 適合率と再現率
  160. =1 なんでも正しい1件しか返却しない! ⇒ 最高 • 適合率を上げれば、再現率は下がり、、 • 再現率を上げれば、適合率が下がる。 理想の検索結果 C

    実際の検索結果 B A © Recruit Co., Ltd., 2021. 160 再現率= C 1 適合率= B A 極端な適合率
  161. =1 • 適合率を上げれば、再現率は下がり、 • 再現率を上げれば、適合率が下がる。 なんでも全件返却する! ⇒ 最高 理想の検索結果 C

    A B 実際の検索結果 © Recruit Co., Ltd., 2021. 161 再現率= C A 適合率= B A 極端な再現率
  162. 適合率(正確性)と再現率(網羅性)のバランスが重要 理想の検索結果 C 実際の検索結果 B A © Recruit Co., Ltd.,

    2021. 162 再現率= C A 適合率= B A 適合率と再現率
  163. F-measure の値が大きければ、バランスのとれた良い結果 F-measure = 適合率 ( 1 + 再現率 1

    ) 2 © Recruit Co., Ltd., 2021. 163 F-measure:適合率と再現率のバランス
  164. ところで… © Recruit Co., Ltd., 2021. 164

  165. 理想の検索結果 C 実際の検索結果 B A © Recruit Co., Ltd., 2021.

    165 実際の結果と理想の結果を全部?
  166. • そもそも「理想の検索結果」とは? • 機械的に作ることが可能ならば、それを検索結果してしまえば良い • 実際に10万件の結果がある場合、評価可能?! • メジャーなクエリー1万件ある場合、評価が必要な件数は10億件 • 検索にヒットしなかった結果も評価しないといけない…

    • 全部で100万件あり、10万件ヒットしたとしても、 残りの90万件も「理想の検索結果」か否かを評価… © Recruit Co., Ltd., 2021. 166 適合率と再現率の検索での非現実性
  167. そもそも、 検索結果を全件見る?! © Recruit Co., Ltd., 2021. 167

  168. 愚直に適合率と再現率を上げるのではなく、 必要とされる 順序 で検索結果を返すことが重要 © Recruit Co., Ltd., 2021. 168

  169. ランキング © Recruit Co., Ltd., 2021. 169

  170. • クエリー「目黒」で、検索結果に「中目黒」を含めるべきか否か?! • なかなか分からない • クエリー「京都」で、検索結果に「東京都」を含めるべきか?! • 含めるべきではない(だろう) • 答えはあるのか?

    • 多分、一般的な解はない • どうすればいいのか? © Recruit Co., Ltd., 2021. 170 検索結果の一般的な評価?
  171. なるべく多く検索結果に含めて、 結局ランキング © Recruit Co., Ltd., 2021. 171

  172. { "_score" : 656.68774, "_source" : { "nikki_kuromoji" : "雪の目黒",

    "nikki_ngram" : "雪の目黒“ } }, { "_score" : 23.361103, "_source" : { "nikki_kuromoji" : "雨の中目黒", "nikki_ngram" : "雨の中目黒“ } } © Recruit Co., Ltd., 2021. 172 「Elasticsearch が何か出しているよ?」
  173. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 173
  174. Okapi BM25: 1980年代から90年代に、ロンドン大学シティ校 で作られた Okapi 検索システムで実装されたから © Recruit Co., Ltd.,

    2021. 174
  175. TF-IDF and Okapi BM25b • 何なの? – アルゴリズム • 入力は?

    – 文章の集合 • 出力は? – 各文章の各単語にスコアを付与 • スコアは何を表すの? – 各文章の各単語の重要度 © Recruit Co., Ltd., 2021. 175
  176. TF-IDF and Okapi BM25b • 何なの? – アルゴリズム • 入力は?

    – 文章の集合 • 出力は? – 各文章の各単語にスコアを付与 • スコアは何を表すの? – 各文章の各単語の重要度 Linux: 0.3 Windows:0.1 ぶり: 4.2 Linux: 1.3 Windows:2.3 まぐろ: 3.8 Linux: 5.4 FreeBSD:10.3 大根: 2.1 © Recruit Co., Ltd., 2021. 176
  177. 困ってる人:「文章が沢山あるのだけど、それぞれ の文章に特徴的なタグを付けられないかな。」 私達:「OK!TF-IDF か Okapi BM25bを使えばタグ付け完了」 © Recruit Co., Ltd.,

    2021. 177
  178. 2つの文章での「Linux」 Linux Linux(リナックス、 他の読みは後述)は、 UnixライクなOSカー ネルである)。 OS オペレーティングシステム(英語: Operating System、

    OS、オーエス)と は、コンピュータのオペレーション (操作・運用・運転)のために、ソ フトウェアの中でも基本的、中核的 位置づけのシステムソフトウェアで ある。通常、OSメーカーが組み上げ たコンピュータプログラムの集合と して、作成され提供されている。 … フリーなOSは、Linux、FreeBSD… … どちらの文章が「Linux」に関して重要度が高いか?! = 価値が高いか?! < 直感的 ? 定量的 © Recruit Co., Ltd., 2021. 178
  179. TF-IDF © Recruit Co., Ltd., 2021. 179

  180. TF-IDF • TF=Term Frequency=Termの頻度 あるドキュメントの中で、どれだけその Term が出現したか? ⇒ いっぱい出てくる単語は重要だ •

    IDF:IDF=Inverse Document Frequency=逆文章頻度 ある Term が全体の中でどれほどレアか? ⇒ レアな単語は重要だ • TF-IDF = TF×IDF あるドキュメント D の中の、Term T がどれほど重要か?は、 (TF: D の中での T の頻出度)×(IDF: T の全体でのレア度) © Recruit Co., Ltd., 2021. 180
  181. TF-IDF:TF=Term Frequency=Termの頻度 Linux Linux(リナックス、 他の読みは後述)は、 UnixライクなOSカー ネルである)。 Linux: 2 リナックス:

    1 読み: 1 Unix: 1 一つの文章に現れる Term の出現回数 沢山出現すれば それだけ重要 © Recruit Co., Ltd., 2021. 181
  182. TF-IDF:IDF=Inverse Document Frequency=逆文章頻度 • Linux • である IDF = log

    Term T が現れる文章数 総文章数 • 野菜 • である • 野菜 • がある • Linux • がある • 肉 • である IDF(Linux) = log 2 5 = 0.39 IDF(である) = log 3 5 = 0.22 > 定量的 Linux である © Recruit Co., Ltd., 2021. 182
  183. TF-IDF:IDF=Inverse Document Frequency=逆文章頻度 • 逆である意味は?! – 現れるドキュメントが、多ければ多いほど、重要度を下げたい (逆比例:「である」等は小、「しめ鯖」等は大) • log

    を取る意味は?! – 非常に大きな総文章数の場合のためのノーマライズ (ノーマラナイズしないとTFの意味がなくなる) © Recruit Co., Ltd., 2021. 183 IDF = log Term T が現れる文章数 総文章数
  184. TF-IDF あるドキュメント D の中の、 Term T がどれほど重要か?は、 (TF: D の中での

    T の頻出度) × (IDF: 文章全体での T のレア度) © Recruit Co., Ltd., 2021. 184
  185. TF-IDFの注意(良いところ) あるドキュメント D に対して Term が異なれば、TF-IDFも異なる しめ鯖 ⇒ 0.8492 Linux

    ⇒ 0.0234 月刊 Linux 2018/04/24 号 今月の月刊 Linux では、 カーネルの特集を… …ところでしめ鯖は美味 しいですね。僕も… © Recruit Co., Ltd., 2021. 185
  186. Okapi BM25b © Recruit Co., Ltd., 2021. 186

  187. BM25: TF-IDFが不都合な場合 Linux Linux(リナックス、 他の読みは後述)は、 UnixライクなOS カーネルである)。 Linux Linux Linux

    Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux … TF(Linux) = 14,352 TF(Linux) =2 > これは不都合 注)IDFはどちらも一緒 © Recruit Co., Ltd., 2021. 187
  188. BM25: TF-IDFが不都合な場合 Linux Linux(リナックス、 他の読みは後述)は、 UnixライクなOS カーネルである)。 Linux Linux Linux

    Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux Linux … TF(Linux) = 14,352 TF(Linux) =2 > これは不都合 注)IDFはどちらも一緒 © Recruit Co., Ltd., 2021. 188 単語数! 14,352 > 23
  189. BM25の定義 ・TF = 単語(Linux)の出現数 ・IDF = 単語レア度(Linuxのレア度) ・DL = ドキュメントの単語数(23)

    ・avgDL = 全てのドキュメントの単語数の平均 (=320) ・2つのパラメータk1, b k1 は 2 が最も最適と言われている b は 0.75 が最も最適と言われている BM25(Linux) = TF × IDF × TF+k1 ×(1-b+b× ) k1 + 1 avgDL DL © Recruit Co., Ltd., 2021. 189 Linux Linux(リナックス、 他の読みは後述)は、 UnixライクなOS カーネルである)。
  190. BM25の意味 BM25(Linux) = TF × IDF × TF+k1 ×(1-b+b× )

    k1 + 1 avgDL DL 単に単語を沢山もつ場合は 減点↓ 単語を沢山もつ場合は 一つの単語の価値を減点↓ 単語を沢山もつ場合は減点だが それが平均に対して小さければ 加点↑ ・TF = 単語の出現数 ・IDF = 単語レア度 ・DL = ドキュメントの単語数 ・avgDL = 全てのドキュメントの単語数の平均 © Recruit Co., Ltd., 2021. 190
  191. BM25 and TF-IDF Linux はフリー のOSカーネル であり、… FreeBSDは Unix系のオー プンソースの…

    今年のじゃがい もはとても不作 だった。 日本ではこの時 期のブリを特に 「寒ブリ」と • Linux: 23 • OS: 11 • カーネル: 17 • は: 0.331 • あり: 3.65 • の: 0.003 • です: 0.0001 • は: 0.000053 • の: 0.023 • FreeBSD: 65 • OS: 9 • カーネル: 5 • じゃがいも: 42 • 不作: 58 • 今年: 2 • だった:0.003 • は: 0.00428 • の: 0.00084 • 寒ブリ: 90 • 日本: 3 • 時期: 1.8 • 特に: 0.2 • の: 0.00189 レアではないワードはスコア小 特徴的 Term はスコア大 © Recruit Co., Ltd., 2021. 191
  192. そもそもTF-IDF を何故計算していたのか? © Recruit Co., Ltd., 2021. 192

  193. • クエリー「目黒」で、検索結果に「中目黒」を含めるべきか否か?! • なかなか分からない • クエリー「京都」で、検索結果に「東京都」を含めるべきか?! • 含めるべきではない(だろう) • 答えはあるのか?

    • 多分、一般的な解はない • どうすればいいのか? © Recruit Co., Ltd., 2021. 193 検索結果の一般的な評価?
  194. 結局、ランキングでした © Recruit Co., Ltd., 2021. 194

  195. { "_score" : 656.68774, "_source" : { "nikki_kuromoji" : "雪の目黒",

    "nikki_ngram" : "雪の目黒“ } }, { "_score" : 23.361103, "_source" : { "nikki_kuromoji" : "雨の中目黒", "nikki_ngram" : "雨の中目黒“ } } © Recruit Co., Ltd., 2021. 195 「Elasticsearch が何か出しているよ?」⇒ Okapi BM25b
  196. めでたし、めでたし… © Recruit Co., Ltd., 2021. 196 本当に?!

  197. © Recruit Co., Ltd., 2021. 197 User First は何処へ?

  198. © Recruit Co., Ltd., 2021. 198 $ ¥ CVR や売上は何処へ?

  199. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 199
  200. そんなあなたへ nDCG • nDCG (= normalized Discounted Cumulative Gain) •

    直訳すると「正規化された効果減少の累積報酬」 • ランキングの精度評価指標 • ランキングを行うシステムの評価に利用できるので、 特に、検索だけがターゲットではない。 例)レコメンドシステム、広告システム • nDCG も理想のランキングとの乖離具合を数値化 © Recruit Co., Ltd., 2021. 200
  201. nDCG の仲間達 • nDCG • Precision@k • mAP (Mean Average

    Precision) • MMR (Maximal Marginal Relevance) © Recruit Co., Ltd., 2021. 201
  202. レコメンド © Recruit Co., Ltd., 2021. 202

  203. 広告 © Recruit Co., Ltd., 2021. 203

  204. nDCG:実際の検索結果 クエリー「からし明太子」 ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上

    辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 © Recruit Co., Ltd., 2021. 204
  205. nDCG:実際のカスタマーの行動 クエリー「からし明太子」 ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上

    辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 © Recruit Co., Ltd., 2021. 205
  206. ちょっと脱線 「クリック」と「購入」って? © Recruit Co., Ltd., 2021. 206

  207. 表示された クリックされた 購入された CTR と CVR © Recruit Co., Ltd.,

    2021. 207
  208. 表示された CTR と CVR PV (Page View): 表示された回数 © Recruit

    Co., Ltd., 2021. 208
  209. 表示された クリックされた CTR と CVR PV (Page View): 表示された回数 CTR

    = 表示された回数 クリックされた回数 (Click Through Rate) © Recruit Co., Ltd., 2021. 209
  210. 表示された クリックされた 購入された CTR と CVR PV (Page View): 表示された回数

    CTR = 表示された回数 クリックされた回数 (Click Through Rate) CVR = 表示された回数 購入された回数 (Conversion Rate) ※何を Conversion と考えるか?はサービス次第 © Recruit Co., Ltd., 2021. 210
  211. nDCG:実際のカスタマーの行動 クエリー「からし明太子」 ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上

    辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 © Recruit Co., Ltd., 2021. 211
  212. © Recruit Co., Ltd., 2021. 212 仮定: ランキング上位の方が conversion しやすい

  213. nDCG:実際のカスタマーの行動 クエリー「からし明太子」 ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上

    辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 2位なのに 頑張っている 4位なのに断トツ?! 1位なのに普通かな ③と④は上下反転?! © Recruit Co., Ltd., 2021. 213
  214. nDCG:理想の結果 クエリー「からし明太子」 ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上

    辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 © Recruit Co., Ltd., 2021. 214
  215. nDCG:理想の結果 クエリー「からし明太子」 ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上

    辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 元々1位だったアド バンテージを考慮 していない © Recruit Co., Ltd., 2021. 215
  216. nDCG は 順位のアドバンテージ を考慮した評価 © Recruit Co., Ltd., 2021. 216

  217. nDCG:スコア ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上 辛子明太子

    1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 S1=150 S2=110 S3=45 S5=60 S4=250 1. 各順位の結果はスコアをもっている (例: クリック数+購入数×100) © Recruit Co., Ltd., 2021. 217
  218. nDCG:Top 5 のスコア ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック

    ④【送料無料】極上 辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 S1=150 S2=110 S3=45 S5=60 S4=250 2. 各順位に応じて、ペナルティ を与え、全体のスコアを計算 DCG5= S1 + + + … log2 S2 log3 S3 © Recruit Co., Ltd., 2021. 218
  219. nDCG:理想の結果のDCG=iDCG (ideal DCG) ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック

    ④【送料無料】極上 辛子明太子 1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 3. スコア順の DCG を求める = iDCG ⇒ DCG が MAX DCG5= S4 + + + … log2 S1 log3 S2 S4=250 S1=150 S2=110 S3=45 S5=60 © Recruit Co., Ltd., 2021. 219
  220. nDCG = iDCG(理想のDCG) DCG(現実のDCG) © Recruit Co., Ltd., 2021. 220

  221. nDCG = 518.78 439.23 = 0.84 理想の結果の84% © Recruit Co.,

    Ltd., 2021. 221
  222. nDCG:ちょっと改善してみる ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上 辛子明太子

    1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 © Recruit Co., Ltd., 2021. 222
  223. nDCG:ちょっと改善してみる ① 辛子明太子 ゴールデンサイズ ② 明太子!【送料無料】てんこ盛り ③ からし明太子高菜80g×2パック ④【送料無料】極上 辛子明太子

    1kg ⑤ パスタソース 逸品 からし明太子 クリック 購入 クリック 購入 クリック 購入 クリック 購入 クリック 購入 © Recruit Co., Ltd., 2021. 223
  224. nDCG = 518.78 489.23 = 0.94 理想の結果の94% © Recruit Co.,

    Ltd., 2021. 224
  225. ランキングの良さを 定量的に評価 できるようになりました。 © Recruit Co., Ltd., 2021. 225

  226. 定量的に評価 できると何が良いのか?! 1. 客観性 2. 再現性 3. 実証性 4. 機械学習の対象にできる

    © Recruit Co., Ltd., 2021. 226
  227. 「あれ?…何かおかしいぞ… スコアが出せるならば、 そのスコア順でいいのでは?」 © Recruit Co., Ltd., 2021. 227

  228. あなたは 100%MAXパーフェクト に正しい!! © Recruit Co., Ltd., 2021. 228

  229. 実際の改善では? • 「ドキュメントは新しい方が良さそうだ」 ⇒ 登録日時を考慮 • 「このクエリーのときにはこういう価格帯が良さそうだ」 ⇒ 価格帯を考慮 •

    「あまり見られていなドキュメントにも可能性があるのでは?」 ⇒ 公平性を考慮 • 「ユーザーの評価も含めるべきではないか?」 ⇒ ユーザー評価を考慮 © Recruit Co., Ltd., 2021. 229
  230. ∞ の可能性 © Recruit Co., Ltd., 2021. 230

  231. アジェンダ • 検索とは何か? • 転置インデックスとは何か? • 転置インデックスを実装するには? • 分散検索とは何か? •

    Term とは何か? • 良い検索結果とは何か? • 検索結果のスコアとは何か? • 良いランキングとは何か? • 良いランキングを作るとは何か? © Recruit Co., Ltd., 2021. 231
  232. ∞ の可能性!! © Recruit Co., Ltd., 2021. 232

  233. Fin お疲れ様でした。 © Recruit Co., Ltd., 2021. 233