RAGで使用する検索対象データのベクトル化についての検証メモ 

## 概要
- RAGにおいて、質問文に関連するデータをベクトルDBなどから検索する場合、元となるドキュメントを分割しただけの場合、何かしらの加工(要約、タイトル付けなど)をした場合で質問文とのコサイン類似度がどのように変わるか？を検証してみました。せっかくなのでメモとして残しておきます。![image.jpg]!
- RAGや生成AIを実務で使った経験はないため、知識・経験不足などによる誤りがあるかもしれません。何か不備がありましたらご指摘ください。

## 環境
- OS Ubuntu 22.04
- Python 3.10.12
- 元となるドキュメントとしてWikipediaの記事を使用。[unstructured](https://github.com/Unstructured-IO/unstructured)でテキスト抽出。
- OpenAIの[text-embedding-3-small](https://platform.openai.com/docs/models/embeddings)でベクトル作成
- テキストの要約、タイトル付けはOpenAIの[gpt-3.5 turbo](https://platform.openai.com/docs/models/gpt-3-5-turbo)を使用。
- ベクトル化対象のデータと質問文とのコサイン類似度の結果は[openpyxl](https://openpyxl.readthedocs.io/en/stable/)でExcelファイルとして保存。 

## 検証内容
- 適当なテキストデータを一定のサイズで分割したテキストデータを作成する。  　
  テキストデータとWikipediaのページでの説明対象についての質問文をOpenAIのtext-embedding-3-smallで
ベクトル化する。
- 分割したテキストデータのベクトルと質問文のベクトルのコサイン類似度を確認する。  
- 次の6つの検証を行う。
    - test1: テキストデータをただ分割しただけの未加工のテキストと質問文の類似度の確認
    - test2: GPT-3.5 turboで生成した要約と質問文の類似度の確認
    - test3: １つ前のテキストデータから生成した要約を文脈情報として与えて生成した要約と質問文の類似度の確認
    - test4: 「あらかじめ用意した文章の説明 + 未加工のテキスト」と質問文の類似度の確認
    - test5: 「あらかじめ用意した文章の説明 + 未加工のテキスト」から生成した要約文と質問文の類似度の確認
    - test6: 「あらかじめ用意した文章の説明 + １つ前のテキストデータから生成した要約 」を文脈情報として与えて生成した要約と質問文の類似度の確認


## 検証手順
- [Wikipediaの「のりたま」のページ](https://ja.wikipedia.org/wiki/%E3%81%AE%E3%82%8A%E3%81%9F%E3%81%BE)をunstructuredでテキスト化。
- テキスト化したデータを約500文字で分割。
- チャンク化したデータそのもの、または要約やタイトル化など加工したデータからベクトルを作成。
- データのベクトルと質問文(のりたまとは何ですか？)のベクトルのコサイン類似度を取得。　　
　これを分割したデータ分行うことをテストケースとする。
- 各データの内容と、質問文と各データのコサイン類似度をExcelファイルに保存する。
- 検証には自作のPythonスクリプト([embedding_test](https://github.com/knd3dayo/embedding_test))を使用。

## 結果
### 結果一覧
![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/eb18101f-0f1f-13ba-280f-21af92691afa.png)

### test1 テキストデータはただ分割しただけの未加工のテキストと質問文の類似度
- [test01.py](https://github.com/knd3dayo/embedding_test/test01.py)を実行しました。  
 「結果一覧」のtest1の列が結果です。
- コサイン類似度は0.140～0.480の範囲でした。
- コサイン類似度が0.140だったのはcase 15で、ベクトル化の元となった内容は次の通り。
    ```
    シールブーム[編集]1963年（昭和38年）に明治製菓がマーブルチョコレートに鉄腕アトムのシールを付けて以降ブームとなっていた[94]江崎グリコは鉄人28号、森永製菓は狼少年ケンのシールを、それぞれの社の製品に入れて追随した[95]丸美屋食品工業は「のりたま」にエイトマンのシールをおまけとして封入した[96][96]東京オリンピックにちなんで参加国のうち32か国の国旗とシークレットとして聖火を背景としたワッペン型のシール計33種類が[97][98][96][96][99][96][96][100][98][9][30][54][96]1965年（昭和40年）に「エイトマン」の放送が終了し「スーパージェッター」の放送が始まると、スーパージェッターのカードが封入されるようになった[98]1960年（昭和35年）から1965年（昭和40年）まで、ふりかけ市場における丸美屋食品工業のシェアは50％近くを占めたが、エッセイストの町田忍は、これらの「ヒーローものカードの果たした役割が大きい」としている[98][96]永谷園が、1964年（昭和39年）発売の「カレンダーふりかけ」に「忍者の素」という忍者道具の小物を、1965年（昭和40年）発売の「ビタフリ」には「ベースボールスタンプカード」を、それぞれおまけとしてつけている
    ```  
    シールブームとか食玩メインのチャンクだったので「のりたま」とは関連度が低いと判断されたんでしょうか。

### test2 GPT-3.5 turboで生成した要約と質問文の類似度
- [test02.py](https://github.com/knd3dayo/embedding_test/test02.py)を実行した結果です。  
 「結果一覧」のtest2の列が結果です。
- コサイン類似度は0.095～0.562の範囲でした。
- コサイン類似度が0.095だったのはcase 15で、test1と同様に「のりたま」とは全く関係ない要約でした。

### test3 1つ前のテキストデータから生成した要約を文脈情報として与えて生成した要約と質問文の類似度
- [test04.py](https://github.com/knd3dayo/embedding_test/test04.py)を実行した結果です。  
「結果一覧」のtest3の列が結果です。
- コサイン類似度は0.364～0.620の範囲でした。
- コサイン類似度が0.364だったのはcase 12で、ベクトルの元となった内容は次の通り。
    ```
    マルミヤ食品工業は1960年に「のりたま」を発売し、斬新なデザインで成功を収め、女性向けにも商品展開。その後、リニューアルを重ねて9代目まで進化。また、復刻版パッケージ商品も発売。CMでは俳優の桂小金治や木村佳乃を起用し、家族の絆をテーマにしたストーリーが展開された。
    ```
### test4 文章の説明と未加工のテキストを結合したテキストと質問文の類似度
- [test04.py](https://github.com/knd3dayo/embedding_test/test04.py)を実行した結果です。  
「結果一覧」のtest4の列が結果です。
- test3のcase1で生成された次の要約文を文章の説明として使用しました。
    ```
    丸美屋食品工業が1960年から販売しているふりかけ「のりたま」は、玉子味の顆粒ときざみ海苔の組み合わせが特徴であり、高級食材の玉子と海苔を主原料とする画期的な商品として登録商標として販売されている。
    ```
- コサイン類似度は0.297～0.554の範囲でした。
- コサイン類似度が0.297だったのはtest1、test2と同様にcase 15でした。

### test5 文章の説明と未加工のテキストを結合したテキストから生成した要約文と質問文の類似度
- [test05.py](https://github.com/knd3dayo/embedding_test/test05.py)を実行した結果です。  
「結果一覧」のtest5の列が結果です。
- test4と同じく、test3のcase1で生成された要約文を文章の説明として使用しました。

- コサイン類似度は0.383～0.592の範囲でした。
- コサイン類似度が0.383だったのはcase 8で、ベクトルの元となった内容は次の通り。
    ```
    マーケティング調査結果を受け、丸美屋食品工業が若い女性向けに「手のりたま」を2007年に発売。人気が高まり、価格改定や内容量変更を実施。製品のリニューアルも行われ、塩分を25％カットした1981年の経緯もある。
    ```
- test4では0.297となっていたcase 15のコサイン類似度は0.540となっていました。  
    ベクトルの元となった内容は次の通り
    ```
    
    丸美屋食品工業が1960年から販売しているふりかけ「のりたま」は、玉子味の顆粒ときざみ海苔の組み合わせが特徴であり、画期的な商品である。登録商標でもあり、主原料に高級食材の玉子と海苔を使用している。
    ```  
    「シールブーム」云々の話は全く消えてしまったようです。

### test6 文章の説明と１つ前のテキストデータから生成した要約を文脈情報として与えて生成した要約と質問文の類似度
- [test06.py](https://github.com/knd3dayo/embedding_test/test06.py)を実行した結果です。  
「結果一覧」のtest6の列が結果です。
- test4と同じく、test3のcase1で生成された次の要約文を文章の説明として使用しました。
- コサイン類似度は0.447～0.577 の範囲でした。
- test5 では0.383となっていたcase 8のベクトルの元になったデータは次の通り
    ```
    2007年に若い女性をターゲットにした「手のりたま」が発売され、コンビニエンスストアで人気となる。価格改定や内容量変更を繰り返し、2011年からの平均売価は「のりたま ニューパック」95円、「のりたま 大袋」185円。1981年には塩分を25％カットしたリニューアルも行われた。
    ```
    test5と比べて「のりたま」が文言が増えたのでコサイン類似度があがったのでしょうか。

### まとめ
- test1 テキスト分割しただけの未加工のテキストの場合、テキストによっては「のりたま」とは全く関係のないデータをもとにしてベクトル化が行われることで、質問文とのコサイン類似度が下がることがありました。
- test2 未加工のテキストから要約を生成した場合、テキストによっては質問文とのコサイン類似度が上がったり、下がったり、
  元の未加工テキストと「のりたま」との関係が強調されるような結果になりました。
- test3 １つ前のテキストデータから生成した要約を文脈情報として与えて要約を生成した場合、文脈情報が優先されて元データの情報がなくなることがありました。
- test4 文章の概要として「のりたま」と関連が高いテキストを文章の説明として与えた場合、質問文とのコサイン類似度が高くなる傾向になりました。
- test5 文章の説明と未加工テキストから要約を生成した結果と質問文のコサイン類似度を比較した場合、多くの場合は
test4と同等かコサイン類似度が高くなりましたが、一部では逆に下がる結果になりました。
- test6 文章の説明と１つ前のテキストデータから生成した要約と未加工テキストから要約を生成した結果、test5よりもコサイン類似度が下がる傾向にありましたが、一部ではtest5よりも高くなる結果になりました。

## 今後の課題
今後は次の事も調べたいと思います。
- 今回使用した質問文は「のりたまとは何ですか？」でしたが、より具体的な質問文の場合はどうでしょうか？全く関係のない質問の場合、文章と質問文のコサイン類似度はどうなるでしょうか？
- さらに具体的な質問文があった場合は、その質問文をそのまま使用するか、それをGPTなどで抽象的な質問文に変換した場合、どのような結果になるのでしょうか？
- そもそもチャンクサイズを500文字としていましたが、サイズ変更を行った場合はどうなるのでしょうか？
- ベクトル化するデータは未加工のテキストデータであるべきでしょうか？要約のほうがよいでしょうか？  
  たとえば、「のりたまの歴史を教えてください」という質問文があったとき、「のりたまの歴史は～」といった要約文があることで、目的のデータを検索しやすくなるのではないでしょうか？（それとも要約はあまり意味がないものなのでしょうか？）