リランキングのありがたみが分かるCohereの解説ノートブックをやってみた

CohereのRerank 3モデルのリリースブログの一番最後に、「Searching Over Tables」という章があり、解説ノートブックのリンクがありました。

https://cohere.com/blog/rerank-3

リランキングについて理解が深まるかと思い、やってみました。

## 環境準備

:::note
埋め込みにはBedrockのTitan Text Embeddings V2を使用するように改変しています。
:::

Pythonライブラリーをインストールします。

```shell
pip install -q pandas numpy fastparquet cohere boto3
```

Pythonスクリプトを作成します。

まずは、ライブラリーをインポートします。

```python
import json

import boto3
import cohere
import numpy as np
import pandas as pd
```

Cohereアクセス用のクライアントを生成します。
トライアル用のAPIキーが無料で取得できます。

```python
cohere_key = "<<YOUR_COHERE_API_KEY>>"
co = cohere.Client(cohere_key)
```

Bedrockアクセス用のクライアントを生成します。

```python
client = boto3.client("bedrock-runtime")
```

検証に使用するデータセットを取得します。

```python
df = pd.read_parquet("https://huggingface.co/datasets/Cohere/movies/resolve/main/movies.parquet")
```

以下のようなデータが、4803行含まれています。

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>title</th>
      <th>overview</th>
      <th>genres</th>
      <th>producer</th>
      <th>cast</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Avatar</td>
      <td>In the 22nd century, a paraplegic Marine is di...</td>
      <td>Action, Adventure, Fantasy, Science Fiction</td>
      <td>Ingenious Film Partners, Twentieth Century Fox...</td>
      <td>Sam Worthington as Jake Sully, Zoe Saldana as ...</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Titanic</td>
      <td>84 years later, a 101-year-old woman named Ros...</td>
      <td>Drama, Romance, Thriller</td>
      <td>Paramount Pictures, Twentieth Century Fox Film...</td>
      <td>Kate Winslet as Rose DeWitt Bukater, Leonardo ...</td>
    </tr>
    <tr>
      <th>2</th>
      <td>The Avengers</td>
      <td>When an unexpected enemy emerges and threatens...</td>
      <td>Science Fiction, Action, Adventure</td>
      <td>Paramount Pictures, Marvel Studios</td>
      <td>Robert Downey Jr. as Tony Stark / Iron Man, Ch...</td>
    </tr>
    <tr>
      <th>3</th>
      <td>Jurassic World</td>
      <td>Twenty-two years after the events of Jurassic ...</td>
      <td>Action, Adventure, Science Fiction, Thriller</td>
      <td>Universal Studios, Amblin Entertainment, Legen...</td>
      <td>Chris Pratt as Owen Grady, Bryce Dallas Howard...</td>
    </tr>
    <tr>
      <th>4</th>
      <td>Furious 7</td>
      <td>Deckard Shaw seeks revenge against Dominic Tor...</td>
      <td>Action</td>
      <td>Universal Pictures, Original Film, Fuji Televi...</td>
      <td>Vin Diesel as Dominic Toretto, Paul Walker as ...</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>4798</th>
      <td>Midnight Cabaret</td>
      <td>A Broadway producer puts on a play with a Devi...</td>
      <td>Horror</td>
      <td></td>
      <td>Lisa Hart Carroll as Dawn, Michael Des Barres ...</td>
    </tr>
    <tr>
      <th>4799</th>
      <td>Growing Up Smith</td>
      <td>In 1979, an Indian family moves to America wit...</td>
      <td>Comedy, Family, Drama</td>
      <td></td>
      <td>Roni Akurati as Smith Bhatnagar, Brighton Shar...</td>
    </tr>
    <tr>
      <th>4800</th>
      <td>8 Days</td>
      <td>After sneaking to a party with her friends, 16...</td>
      <td>Thriller, Drama</td>
      <td>After Eden Pictures</td>
      <td>Nicole Smolen as Amber, Kim Baldwin as BB, Ari...</td>
    </tr>
    <tr>
      <th>4801</th>
      <td>Running Forever</td>
      <td>After being estranged since her mother's death...</td>
      <td>Family</td>
      <td>New Kingdom Pictures</td>
      <td></td>
    </tr>
    <tr>
      <th>4802</th>
      <td>To Be Frank, Sinatra at 100</td>
      <td>None</td>
      <td>Documentary</td>
      <td>Eyeline Entertainment</td>
      <td>Tony Oppedisano as Narrator</td>
    </tr>
  </tbody>
</table>
<p>4803 rows × 5 columns</p>
</div>


### テストデータをベクトル化する

このデータを、Titan Text Embeddings V2でベクトル化します。

一括で埋め込みを行う関数を作成します。

```python
def embed(
    texts: list[str],
    model_id: str = "amazon.titan-embed-text-v2:0",
):
    embeddings = []

    for text in texts:
        body = {"inputText": text}
        response = client.invoke_model(modelId=model_id, body=json.dumps(body))
        embeddings.append(json.loads(response["body"].read().decode())["embedding"])

    return embeddings
```

テストデータを、文字列型に変換します。

```python
docs_txt = [str(doc) for doc in df.to_dict("records")]
```

```text:docs_txt[0]
{'title': 'Avatar', 'overview': 'In the 22nd century, a paraplegic Marine is dispatched to the moon Pandora on a unique mission, but becomes torn between following orders and protecting an alien civilization.', 'genres': 'Action, Adventure, Fantasy, Science Fiction', 'producer': 'Ingenious Film Partners, Twentieth Century Fox Film Corporation, Dune Entertainment, Lightstorm Entertainment', 'cast': "Sam Worthington as Jake Sully, Zoe Saldana as Neytiri, Sigourney Weaver as Dr. Grace Augustine, Stephen Lang as Col. Quaritch, Michelle Rodriguez as Trudy Chacon, Giovanni Ribisi as Selfridge, Joel David Moore as Norm Spellman, CCH Pounder as Moat, Wes Studi as Eytukan, Laz Alonso as Tsu'Tey, Dileep Rao as Dr. Max Patel, Matt Gerald as Lyle Wainfleet, Sean Anthony Moran as Private Fike, Jason Whyte as Cryo Vault Med Tech, Scott Lawrence as Venture Star Crew Chief, Kelly Kilgour as Lock Up Trooper, James Patrick Pitt as Shuttle Pilot, Sean Patrick Murphy as Shuttle Co-Pilot, Peter Dillon as Shuttle Crew Chief, Kevin Dorman as Tractor Operator / Troupe, Kelson Henderson as Dragon Gunship Pilot, David Van Horn as Dragon Gunship Gunner, Jacob Tomuri as Dragon Gunship Navigator, Michael Blain-Rozgay as Suit #1, Jon Curry as Suit #2, Luke Hawker as Ambient Room Tech, Woody Schultz as Ambient Room Tech / Troupe, Peter Mensah as Horse Clan Leader, Sonia Yee as Link Room Tech, Jahnel Curfman as Basketball Avatar / Troupe, Ilram Choi as Basketball Avatar, Kyla Warren as Na'vi Child, Lisa Roumain as Troupe, Debra Wilson as Troupe, Chris Mala as Troupe, Taylor Kibby as Troupe, Jodie Landau as Troupe, Julie Lamm as Troupe, Cullen B. Madden as Troupe, Joseph Brady Madden as Troupe, Frankie Torres as Troupe, Austin Wilson as Troupe, Sara Wilson as Troupe, Tamica Washington-Miller as Troupe, Lucy Briant as Op Center Staff, Nathan Meister as Op Center Staff, Gerry Blair as Op Center Staff, Matthew Chamberlain as Op Center Staff, Paul Yates as Op Center Staff, Wray Wilson as Op Center Duty Officer, James Gaylyn as Op Center Staff, Melvin Leno Clark III as Dancer, Carvon Futrell as Dancer, Brandon Jelkes as Dancer, Micah Moch as Dancer, Hanniyah Muhammad as Dancer, Christopher Nolen as Dancer, Christa Oliver as Dancer, April Marie Thomas as Dancer, Bravita A. Threatt as Dancer, Colin Bleasdale as Mining Chief (uncredited), Mike Bodnar as Veteran Miner (uncredited), Matt Clayton as Richard (uncredited), Nicole Dionne as Nav'i (uncredited), Jamie Harrison as Trooper (uncredited), Allan Henry as Trooper (uncredited), Anthony Ingruber as Ground Technician (uncredited), Ashley Jeffery as Flight Crew Mechanic (uncredited), Dean Knowsley as Samson Pilot, Joseph Mika-Hunt as Trooper (uncredited), Terry Notary as Banshee (uncredited), Kai Pantano as Soldier (uncredited), Logan Pithyou as Blast Technician (uncredited), Stuart Pollock as Vindum Raah (uncredited), Raja as Hero (uncredited), Gareth Ruck as Ops Centreworker (uncredited), Rhian Sheehan as Engineer (uncredited), T. J. Storm as Col. Quaritch's Mech Suit (uncredited), Jodie Taylor as Female Marine (uncredited), Alicia Vela-Bailey as Ikran Clan Leader (uncredited), Richard Whiteside as Geologist (uncredited), Nikie Zambo as Na'vi (uncredited), Julene Renee as Ambient Room Tech / Troupe"}
```

埋め込みを行います。

```python
doc_emb = np.asarray(embed(texts=docs_txt))
```

### ベクトルデータを使って検索する

「Action movies with Christian Bale」という検索クエリで検索します。
検索クエリをベクトル化します。

```python
query = "Action movies with Christian Bale"
query_emb = np.asarray(embed(texts=[query]))
```

検索クエリのベクトルと、すべてのドキュメントのベクトルのコサイン類似度/ドット積を計算します。

```python
dot_scores = np.matmul(query_emb, doc_emb.transpose())[0]
```

上位100件を取得します。

```python
top_100_hits = np.argsort(-dot_scores).tolist()[0:100]

emb_results = df.iloc[top_100_hits].copy()
emb_results.insert(loc=0, column='rank', value=(np.arange(len(emb_results))+1))
emb_results
```

上位100は、このようになりました。

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>rank</th>
      <th>title</th>
      <th>overview</th>
      <th>genres</th>
      <th>producer</th>
      <th>cast</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>867</th>
      <td>1</td>
      <td>Babel</td>
      <td>Tragedy strikes a married couple on vacation i...</td>
      <td>Drama</td>
      <td>Paramount Vantage, Media Rights Capital, Anony...</td>
      <td>Brad Pitt as Richard, Cate Blanchett as Susan,...</td>
    </tr>
    <tr>
      <th>1615</th>
      <td>2</td>
      <td>Cellular</td>
      <td>A young man receives an emergency phone call o...</td>
      <td>Action, Adventure, Crime, Thriller</td>
      <td>New Line Cinema</td>
      <td>Chris Evans as Ryan Hewitt, Kim Basinger as Je...</td>
    </tr>
    <tr>
      <th>885</th>
      <td>3</td>
      <td>Blade</td>
      <td>When Blade's mother was bitten by a vampire du...</td>
      <td>Horror, Action</td>
      <td>New Line Cinema, Amen Ra Films, Imaginary Forc...</td>
      <td>Wesley Snipes as Blade, Stephen Dorff as Deaco...</td>
    </tr>
    <tr>
      <th>2361</th>
      <td>4</td>
      <td>Action Jackson</td>
      <td>Vengence drives a tough Detroit cop to stay on...</td>
      <td>Action, Adventure, Comedy, Crime, Drama</td>
      <td>Silver Pictures, Lorimar Motion Pictures</td>
      <td>Carl Weathers as Sgt. Jericho 'Action' Jackson...</td>
    </tr>
    <tr>
      <th>4072</th>
      <td>5</td>
      <td>Malone</td>
      <td>Erstwhile C.I.A. assassin Richard Malone hopes...</td>
      <td>Action, Thriller</td>
      <td>Orion Pictures</td>
      <td>Burt Reynolds as Richard Malone, Cliff Roberts...</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>2223</th>
      <td>96</td>
      <td>Desperado</td>
      <td>A gunslinger is embroiled in a war with a loca...</td>
      <td>Thriller, Action, Crime</td>
      <td>Columbia Pictures, Los Hooligans Productions</td>
      <td>Antonio Banderas as El Mariachi, Salma Hayek a...</td>
    </tr>
    <tr>
      <th>56</th>
      <td>97</td>
      <td>Spider-Man 2</td>
      <td>Peter Parker is going through a major identity...</td>
      <td>Action, Adventure, Fantasy</td>
      <td>Columbia Pictures, Laura Ziskin Productions, M...</td>
      <td>Tobey Maguire as Peter Parker / Spider-Man, Ki...</td>
    </tr>
    <tr>
      <th>1386</th>
      <td>98</td>
      <td>The Core</td>
      <td>Geophysicist Dr. Josh Keyes discovers that an ...</td>
      <td>Action, Thriller, Adventure, Science Fiction</td>
      <td>Paramount Pictures, David Foster Productions, ...</td>
      <td>Aaron Eckhart as Dr. Josh Keyes, Hilary Swank ...</td>
    </tr>
    <tr>
      <th>547</th>
      <td>99</td>
      <td>White House Down</td>
      <td>Capitol Policeman John Cale has just been deni...</td>
      <td>Action, Drama, Thriller</td>
      <td>Columbia Pictures, Centropolis Entertainment, ...</td>
      <td>Channing Tatum as Cale, Jamie Foxx as Presiden...</td>
    </tr>
    <tr>
      <th>3711</th>
      <td>100</td>
      <td>The Pink Panther</td>
      <td>When the coach of the France soccer team is ki...</td>
      <td>Action, Comedy, Crime, Mystery, Family</td>
      <td>Columbia Pictures, International Production Co...</td>
      <td>Steve Martin as Inspector Jacques Clouseau, Ke...</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 6 columns</p>
</div>

### リランキングして検索結果を改善させる

上位100件のデータをJSONオブジェクトに変換します。

```python
docs = emb_results.to_dict('records')
```

Rerank3では、JSONオブジェクトのリランク対象のキーを指定できます。今回は、すべてのキーを対象とします。

```python
rank_fields = list(docs[0].keys())
```

Rerank3モデルでリランキングします。

パラメーターは以下のように指定します。

* query: 検索クエリ（"Action movies with Christian Bale"）
* documents: 上位100件のデータ（1件ごとにJSONオブジェクトになっている）
* top_n: 結果として取得する件数
* model: CohereのモデルID
* rank_fields: リランク対象のフィールド。今回は、JSONの全部のキーを指定

```python
results = co.rerank(query=query, documents=docs, top_n=10, model='rerank-english-v3.0', rank_fields=rank_fields)
```

埋め込みで検索した上位100件のデータから、リランク処理で上位10件となったデータを抽出します。

```python
top_ids = [hit.index for hit in results.results]

rerank_results = emb_results.iloc[top_ids].copy()
rerank_results['rank'] = (np.arange(len(rerank_results))+1)
```

結果はこのとおりです。

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>rank</th>
      <th>title</th>
      <th>overview</th>
      <th>genres</th>
      <th>producer</th>
      <th>cast</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>2911</th>
      <td>1</td>
      <td>Harsh Times</td>
      <td>Jim Davis is an ex-Army Ranger who finds himse...</td>
      <td>Crime, Drama, Thriller, Action</td>
      <td>The Weinstein Company</td>
      <td>Christian Bale as Jim Luther Davis, Freddy Rod...</td>
    </tr>
    <tr>
      <th>1818</th>
      <td>2</td>
      <td>Reign of Fire</td>
      <td>In post-apocalyptic England, an American volun...</td>
      <td>Adventure, Action, Fantasy</td>
      <td>The Zanuck Company, Spyglass Entertainment, Wo...</td>
      <td>Christian Bale as Quinn Abercromby, Matthew Mc...</td>
    </tr>
    <tr>
      <th>2942</th>
      <td>3</td>
      <td>Equilibrium</td>
      <td>In a dystopian future, a totalitarian regime m...</td>
      <td>Action, Science Fiction, Thriller</td>
      <td>Dimension Films, Blue Tulip Productions</td>
      <td>Christian Bale as John Preston, Taye Diggs as ...</td>
    </tr>
    <tr>
      <th>2849</th>
      <td>4</td>
      <td>Rescue Dawn</td>
      <td>A US Fighter pilot's epic struggle of survival...</td>
      <td>Adventure, Drama, War</td>
      <td>Metro-Goldwyn-Mayer (MGM)</td>
      <td>Christian Bale as Dieter Dengler, Steve Zahn a...</td>
    </tr>
    <tr>
      <th>2528</th>
      <td>5</td>
      <td>Out of the Furnace</td>
      <td>Two brothers live in the economically-depresse...</td>
      <td>Thriller, Drama, Crime</td>
      <td>Appian Way, Scott Free Productions, Relativity...</td>
      <td>Christian Bale as Russell Baze, Zoe Saldana as...</td>
    </tr>
    <tr>
      <th>1062</th>
      <td>6</td>
      <td>Shaft</td>
      <td>New York police detective John Shaft arrests W...</td>
      <td>Action, Adventure, Crime, Thriller</td>
      <td>Paramount Pictures, Scott Rudin Productions</td>
      <td>Samuel L. Jackson as John Shaft, Jeffrey Wrigh...</td>
    </tr>
    <tr>
      <th>37</th>
      <td>7</td>
      <td>Spectre</td>
      <td>A cryptic message from Bond’s past sends him o...</td>
      <td>Action, Adventure, Crime</td>
      <td>Columbia Pictures, Danjaq, B24</td>
      <td>Daniel Craig as James Bond, Christoph Waltz as...</td>
    </tr>
    <tr>
      <th>2012</th>
      <td>8</td>
      <td>American Psycho</td>
      <td>A wealthy New York investment banking executiv...</td>
      <td>Thriller, Drama, Crime</td>
      <td>Lions Gate Films, Edward R. Pressman Film, Mus...</td>
      <td>Christian Bale as Patrick Bateman, Willem Dafo...</td>
    </tr>
    <tr>
      <th>2805</th>
      <td>9</td>
      <td>The Machinist</td>
      <td>The Machinist is the story of Trevor Reznik, a...</td>
      <td>Thriller, Drama</td>
      <td>Filmax Entertainment, Castelao Producciones, C...</td>
      <td>Christian Bale as Trevor Reznik, Jennifer Jaso...</td>
    </tr>
    <tr>
      <th>3427</th>
      <td>10</td>
      <td>Batman</td>
      <td>The Dynamic Duo faces four super-villains who ...</td>
      <td>Family, Adventure, Comedy, Science Fiction, Crime</td>
      <td>Twentieth Century Fox Film Corporation, DC Com...</td>
      <td>Adam West as Batman / Bruce Wayne, Burt Ward a...</td>
    </tr>
  </tbody>
</table>
</div>

---

ベクトル検索のみで取得した上位5件と、その後リランキングした上位5件を比較してみます。

まず、ベクトル検索のみの結果ですが、castに「Christian Bale」がいません。なので、全部検索結果としてはイケてないです。
対して、リランキングした結果は、すべてのcastに「Christian Bale」が含まれています。

また、「genres」についても、ベクトル検索のみ一位は「Drama」で、Actionではありませんでした。なぜこの結果が一位だったのかは気になりますね。
対して、リランキングした結果は、一位から三位までは「Action」が含まれていました。ただ、四位と五位は違うジャンルでした。ただ、AdventureやThrillerなどが含まれているので広く見てActionと捉えてもいいかもしれない？ように思いました。

上手に関連性の高いものが上位になっているように見えます。

ベクトル検索は、「意味が近いもの」を取ってくるようで、細かく見ると「近そうなもの」が取れているだけなのjかもしれません？リランキングすると、その「近そうなもの」を「近い順」にしてくれるイメージかな、と理解しました。

---



以上、リランキングの検証でした。