# ギブリー研修(演習)
【演習:RAG精度改善ワーク】
- 目的:高精度なRAGシステムを作ろう
- データ:任意のPDFファイル
- やること
1. 質問と回答のテストデータの作成(3ケース)
2. 3ケースのテストデータに対して、RAGの処理を実行して、精度結果(Scoring Evaluatorを使用)を確認
[Scoring Evaluator | 🦜️🔗 Langchain で、数値化](https://python.langchain.com/docs/guides/productionization/evaluation/string/scoring_eval_chain/)
3. すべてのテストデータでScore = 9~10であれば、難易度の高いテストデータを再作成
4. 精度改善を実施(モデル選定、Embeddingの手法選定、データ分割の手法、メタ情報の付与、検索手法の選定、プロンプトデザイン、データの前処理など)
5. 精度改善結果の評価
- テキストでまとめて共有して欲しいこと(Slackのこのスレッドにて、投稿していただけますと幸いです)
1. どんな精度改善をしたか?
2. 何をしたら、精度が上がったか?
## 素材
「人を対象とする生命科学・医学系研究に関する倫理指針 ガイダンス」のPDF
https://www.lifescience.mext.go.jp/files/pdf/n2376_01.pdf
- 厚労省などから出されている文書。人に対する研究などを行う際に大学や企業で倫理的に問題ないか審査する必要があり、その仕組みを解説する文書。
## 方法
- LangChainにてRAGを構成。
- プレテストで同じ質問でも生成される回答によってScoreに差がでるため、同じ質問で5回繰り返してScoreのブレも見る
- モデルの変更などを実施
- Evaluatorに使用するモデルは一旦gpt-3.5-turboで固定。
## 質問と模範解答
```
input_1 = "多機関共同研究を実施する場合、必ず一括審査を実施しなくてはいけませんか?"
input_2 = "倫理審査委員会を構成する委員の男女比率に規定はありますか? "
input_3 = "インフォームド・コンセント(IC)を受ける手続きに「口頭IC(記録作成含む。)とあるが、記録とはどのようなものか。"
reference_1 = """
生命・医学系指針の第6の2⑸の規定にもあるように、同指針の第6の2⑵の規定によらず、
各研究機関の状況等を踏まえ、共同研究機関と一括した倫理審査委員会の審査を受けずに、
各共同研究機関の研究責任者において個別の倫理審査委員会の意見を聴くことを妨げてはいません。
また、第6の2の規定に係るガイダンスの8に記載されているとおり、
多機関共同研究として倫理審査委員会に審査を求める場合、
研究代表者が受ける「一の倫理審査委員会による一括審査」と各共同研究機関の研究責任者が
個別に倫理審査委員会の意見を聴くことが混在することは問題ありません。
ただし、一括審査を他機関に依頼した上で、改めて自機関の委員会で審査を受けること(二重審査)は不要です。
"""
reference_2 = """
倫理審査委員会の男女比率については、生命・医学系指針の 第 17 の2(1)⑤ に記載されているとおり、
「男女両性で構成されていること。」 が満たされている必要がありますが、男女の具体の比率については規定されておりません。
ただし、構成要件と成立要件は同様の要件となりますのでご留意ください。
すなわち、女性1名の構成であった場合、その者が欠席すると倫理審査委員会が成立しなくなりますので、ご注意ください。
"""
reference_3 = """
同意の意思は、電話や郵送での返信による場合も含め、個々の研究対象 者ごとに確認する必要がある。
「同意の内容に関する記録」としては、同意の日時、説明方法、説明者、同意事項等について記載する必要がある。
また、口頭での手続による場合であっても、研究対象者等が受けた説明や与えた同意の内容を記憶にとどめられるよう、
当該説明及び同意の内容に関する資料を渡すなどの配慮を行うことが望ましい。
"""
```
## 1回目(4/12)
- embedding:text-embedding-3-large
- gpt:gpt-3.5-turbo
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 3 | 7 | 8 | 8 | 7 | 6.6 | 1.85 |
| input_2 | 4 | 4 | 7 | 6 | 8 | 5.8 | 1.60 |
| input_3 | 7 | 7 | 9 | 8 | 7 | 7.6 | 0.80 |
## 2回目(4/12)
- **embedding:text-embedding-3-small(一旦低くする)**
- gpt:gpt-3.5-turbo
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 6 | 6 | 6 | 6 | 8 | 6.6 | 0.80 |
| input_2 | 7 | 8 | 7 | 3 | 9 | 6.8 | 2.04 |
| input_3 | 7 | 7 | 8 | 9 | 7 | 7.6 | 0.80 |
- あんまり変わらない・・・?
## 3回目(4/12)
- embedding:text-embedding-3-small
- **gpt:gpt-4(変更)**
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 8 | 7 | 7 | 9 | 7 | 7.6 | 0.80 |
| input_2 | 8 | 4 | 8 | 7 | 7 | 6.8 | 1.47 |
| input_3 | 9 | 9 | 7 | 7 | 9 | 8.2 | 0.98 |
- 先ほどよりGPT-4にすると少し良くなった印象
## 4回目(4/12)
- **embedding:text-embedding-3-large(変更)**
- gpt:gpt-4
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 6 | 9 | 7 | 9 | 9 | 8.0 | 1.26 |
| input_2 | 6 | 9 | 8 | 8 | 7 | 7.6 | 1.02 |
| input_3 | 7 | 8 | 8 | 9 | 8 | 8.0 | 0.63 |
- input_2は3回目より良くなった感じはあるが他は誤差範囲。
- 今までの結果から、modelはgpt-4の方が良さげだが、embeddingはどちらも変わらない(なら早いsmallの方がよい?)
## 5回目(4/12)
- Sematic Chunkingを試そうとしたが、エラーが出て断念。
(データが重すぎてGoogle Colaboratoryでは無理?)
>
It seems like the error message you received, "IOPub data rate exceeded," occurs when the amount of data being sent from a Jupyter Notebook server to a client exceeds the predefined limit. This could happen if a large amount of data, such as a complex output or many large files, is being processed and sent.
In a typical setting, to resolve this, you might adjust the iopub_data_rate_limit configuration of the Jupyter server to allow a higher data rate. This would let more data to be sent without interruption. However, this change needs to be made in the server configuration and usually involves restarting the Jupyter server with an increased data rate limit. If you're managing the server or have access to its configurations, you can adjust this setting; otherwise, you might need to contact the administrator of the server.
## 6回目(4/14)
### chunk設定を試す
- text-embedding-3-large,gpt-4で固定
- chunk_size=1000, chunk_overlap=200
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 8 | 8 | 7 | 7 | 8 | 7.6 | 0.49 |
| input_2 | 3 | 7 | 7 | 9 | 4 | 6.0 | 2.19 |
| input_3 | 9 | 8 | 9 | 9 | 8 | 8.6 | 0.49 |
- input_1と3は回答が安定しているが、2については点数も低く、安定していない
## 7回目(4/14)
### chunk設定を試す
- text-embedding-3-large,gpt-4で固定
- chunk_size=2000, chunk_overlap=400 -> 6回目の2倍に
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 7 | 7 | 7 | 7 | 9 | 7.4 | 0.80 |
| input_2 | 6 | 4 | 3 | 4 | 7 | 4.8 | 1.47 |
| input_3 | 9 | 8 | 7 | 9 | 9 | 8.4 | 0.80 |
- 明確にinput_2の精度が落ちた
## 8回目(4/14)
### chunk設定を試す
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 6回目の半分に
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 7 | 8 | 9 | 9 | 8 | 8.2 | 0.75 |
| input_2 | 4 | 7 | 7 | 7 | 6 | 6.2 | 1.17 |
| input_3 | 8 | 9 | 8 | 9 | 9 | 8.6 | 0.49 |
- input_1と3については最高得点、2については7回目よりは良いが、ページ単位のチャンクと比べると低い。
## 9回目(4/14)
### 検索方法の見直し
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 8回目のまま
- as_retrieverのパラメータを以下のようにし、サーチタイプは変更せず(similarity)、取得されるドキュメント数を10件に(デフォルトは4件)
``` python=
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={'k': 10}
)
```
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 9 | 9 | 8 | 9 | 8 | 8.6 | 0.49 |
| input_2 | 7 | 7 | 7 | 9 | 6 | 7.2 | 0.98 |
| input_3 | 9 | 8 | 9 | 9 | 9 | 8.8 | 0.40 |
- 全inputに対して精度向上が見られ、回答のばらつきも少なくなった
## 10回目(4/14)
### 検索方法の見直し
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 8回目のまま
- as_retrieverのパラメータを以下のようにし、サーチタイプはMMRに変更し(λはデフォルトの0.5)、取得されるドキュメント数は10件のままに。
``` python=
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={'k': 10, 'lambda_mult': 0.5}
)
```
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 8 | 7 | 7 | 7 | 8 | 7.4 | 0.49 |
| input_2 | 6 | 8 | 4 | 7 | 7 | 6.4 | 1.35 |
| input_3 | 8 | 9 | 8 | 9 | 9 | 8.6 | 0.49 |
- input_1と2は精度低下が見られた。
## 11回目(4/14)
### 検索方法の見直し
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 8回目のまま
- 10回目の設定からMMRのλを0.8に変更
``` python=
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={'k': 10, 'lambda_mult': 0.8}
)
```
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 7 | 9 | 7 | 9 | 8 | 8.0 | 0.89 |
| input_2 | 8 | 6 | 7 | 8 | 7 | 7.2 | 0.74 |
| input_3 | 9 | 9 | 9 | 9 | 9 | 9.0 | 0.0 |
- input_3が初の9点台となった。
## 12回目(4/14)
### 検索方法の見直し
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 8回目のまま
- MMRのλを0.8のまま、取得する文書を5に削減
``` python=
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={'k': 5, 'lambda_mult': 0.8}
)
```
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 8 | 9 | 8 | 9 | 8 | 8.4 | 0.48 |
| input_2 | 4 | 6 | 6 | 8 | 7 | 6.2 | 1.32 |
| input_3 | 9 | 9 | 9 | 6 | 9 | 8.4 | 1.2 |
- input_1は向上したが、input_2と3は1つ得点が低いものが入って低下。
## 13回目(4/14)
### 検索方法の見直し
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 8回目のまま
- MMRのλを1.0に変更
``` python=
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={'k': 5, 'lambda_mult': 1.0}
)
```
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 9 | 8 | 8 | 8 | 8 | 8.2 | 0.39 |
| input_2 | 7 | 4 | 3 | 7 | 7 | 5.6 | 1.74 |
| input_3 | 9 | 8 | 9 | 9 | 9 | 8.8 | 0.40 |
- input_1と3は安定した回答ができている。2は平均もばらつきも大きくなった。
## 14回目(4/14)
### 検索方法の見直し
- text-embedding-3-large,gpt-4で固定
- chunk_size=500, chunk_overlap=100 -> 8回目のまま
- MMRのλを1.0のままで、取得する文章を10に増やす
``` python=
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={'k': 10, 'lambda_mult': 1.0}
)
```
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 8 | 7 | 8 | 8 | 7 | 7.6 | 0.48 |
| input_2 | 7 | 7 | 7 | 7 | 7 | 7.0 | 0.0 |
| input_3 | 9 | 9 | 8 | 7 | 7 | 8.0 | 0.89 |
- input_2は上がったが、1と3は低下。
## 15回目(4/15)
### modelの変更(gpt-4-turbo-previewへ変更)
- 今までの検証でよかった構成をベースに、gpt-4-turbo-previewで実施。
- embedding : text-embedding-3-large
- chunk : chunk_size=500, chunk_overlap=100
- search : similarity, k=10
| 質問 | S1 | S2 | S3 | S4 | S5 | 平均 | 標準偏差 |
| ------- | - | - | - | - | - | --- | --- |
| input_1 | 9 | 9 | 9 | 9 | 10 | 9.2 | 0.40 |
| input_2 | 9 | 8 | 8 | 8 | 8 | 8.2 | 0.40 |
| input_3 | 9 | 9 | 10 | 9 | 9 | 9.2 | 0.40 |
- **結局、gpt-4-turboは最強だったという話。**
---
## 最終の回答結果
```
input_1 = "多機関共同研究を実施する場合、必ず一括審査を実施しなくてはいけませんか?"
reference_1 = """
生命・医学系指針の第6の2⑸の規定にもあるように、同指針の第6の2⑵の規定によらず、
各研究機関の状況等を踏まえ、共同研究機関と一括した倫理審査委員会の審査を受けずに、
各共同研究機関の研究責任者において個別の倫理審査委員会の意見を聴くことを妨げてはいません。
また、第6の2の規定に係るガイダンスの8に記載されているとおり、
多機関共同研究として倫理審査委員会に審査を求める場合、
研究代表者が受ける「一の倫理審査委員会による一括審査」と各共同研究機関の研究責任者が
個別に倫理審査委員会の意見を聴くことが混在することは問題ありません。
ただし、一括審査を他機関に依頼した上で、改めて自機関の委員会で審査を受けること(二重審査)は不要です。
"""
prediction_1(S1) = '多機関共同研究を実施する場合、必ずしも一括審査を実施しなければいけないわけではありません。各研究機関の状況等を踏まえ、共同研究機関と一括した倫理審査委員会の審査を受ける代わりに、個別の倫理審査委員会の意見を聴くことも可能です。研究責任者及び研究代表者は、各研究機関の体制、研究内容等を踏まえて、十分に協議し審査方法(一括審査又は個別審査)を決める必要があります。また、「一の倫理審査委員会による場合」、「個別の倫理審査委員会による場合」が混在することも許容されています。'
prediction_1(S2) = '多機関共同研究を実施する場合、一括審査を必ず実施しなければいけないわけではありません。各研究機関の状況等を踏まえて、研究責任者と研究代表者間で十分に協議し、審査方法(一括審査または個別審査)を決定する必要があります。また、共同研究機関と一括した倫理審査委員会の審査を受けず、個別の倫理審査委員会の意見を聴くことも可能です。'
prediction_1(S3) = '多機関共同研究を実施する場合、必ずしも一括審査を行う必要はありません。研究責任者及び研究代表者間で十分に協議し、各研究機関の体制や研究内容等を踏まえて、一括審査か個別審査かを決定します。また、個別の倫理審査委員会の意見を聴くことを妨げるものではありません。これらの選択肢は、研究の内容やそれまでの審査過程、そして各研究機関の状況等を考慮に入れて選ばれるべきです。ただし、複数の倫理審査委員会の意見を聴く場合でも、全体としての審査過程や審査結果を共有し、整合性を保つことが重要です。'
prediction_1(S4) = '多機関共同研究を実施する場合、一括審査を必ず行う必要はありません。研究責任者や研究代表者は各研究機関の体制、研究内容等を踏まえ、十分に協議し審査方法(一括審査または個別審査)を決める必要があります。また、共同研究機関と一括した倫理審査委員会の審査を受けず、個別の倫理審査委員会の意見を聴くことを妨げるものではないとされています。したがって、具体的な研究の内容や各研究機関の状況に応じて対応を決めることが可能です。'
prediction_1(S5) = '多機関共同研究を実施する場合、必ずしも一括審査を実施しなければならないわけではありません。各研究機関の状況等を踏まえ、研究責任者及び研究代表者間で十分に協議した上で、一括審査または個別審査を選ぶことが可能です。一括審査を受けずに、個別の倫理審査委員会の意見を聴くことを妨げるものではありません。また、「一の倫理審査委員会による場合」、「個別の倫理審査委員会による場合」が混在することも許容されています。'
```
```
input_2 = "倫理審査委員会を構成する委員の男女比率に規定はありますか? "
reference_2 = """
倫理審査委員会の男女比率については、生命・医学系指針の 第 17 の2(1)⑤ に記載されているとおり、
「男女両性で構成されていること。」 が満たされている必要がありますが、男女の具体の比率については規定されておりません。
ただし、構成要件と成立要件は同様の要件となりますのでご留意ください。
すなわち、女性1名の構成であった場合、その者が欠席すると倫理審査委員会が成立しなくなりますので、ご注意ください。
"""
prediction_2(S1) = '倫理審査委員会は男女両性で構成されていることが求められています。ただし、具体的な男女比率については規定されていません。これは、審査結果が公正かつバランスのとれたものとなることが期待されているからです。なお、委員の専門性だけでなく、異なる立場の委員による十分な議論の上で合意を形成することも重要とされています。'
prediction_2(S2) = '倫理審査委員会の構成については男女比率に関する規定があります。具体的には、倫理審査委員会は男女両性で構成されていることが求められます。これは、性別による視点の多様性を確保し、公正かつバランスのとれた審議結果を得るためです。'
prediction_2(S3) = '倫理審査委員会の構成に関しては、男女両性で構成されていることが規定されています。ただし、具体的な男女比率についての規定は明記されていません。その他、5名以上で構成されることや、医学・医療の専門家等、自然科学の有識者、倫理学・法律学の専門家等、人文・社会科学の有識者、研究対象者の観点も含めて一般の立場から意見を述べることのできる者、倫理審査委員会の設置者の所属機関に所属しない者が含まれていることなどが求められます。'
prediction_2(S4) = 'はい、倫理審査委員会の構成には男女両性で構成されていることが規定されています。具体的には、倫理審査委員会の構成は、研究計画書の審査等の業務を適切に実施できるように、特定の要件を全て満たさなければならず、その中に男女両性で構成されていることが含まれています。男女両性の視点を盛り込むことにより、より公正かつバランスのとれた審査結果となることが期待されます。'
prediction_2(S5) = '倫理審査委員会の構成については、委員が男女両性で構成されていることが求められています。具体的な男女比率については定められていませんが、多様な視点を持った委員による公正かつバランスのとれた審議が期待されています。'
```
```
input_3 = "インフォームド・コンセント(IC)を受ける手続きに「口頭IC(記録作成含む。)とあるが、記録とはどのようなものか。"
reference_3 = """
同意の意思は、電話や郵送での返信による場合も含め、個々の研究対象 者ごとに確認する必要がある。
「同意の内容に関する記録」としては、同意の日時、説明方法、説明者、同意事項等について記載する必要がある。
また、口頭での手続による場合であっても、研究対象者等が受けた説明や与えた同意の内容を記憶にとどめられるよう、
当該説明及び同意の内容に関する資料を渡すなどの配慮を行うことが望ましい。
"""
prediction_3(S1) = '口頭によるインフォームド・コンセント(IC)の記録とは、研究者が研究参加者に対して口頭で説明を行い、同意を得た際の内容を記録したものを指します。具体的には、同意の日時、説明方法、説明者、同意事項等について記載されるべきです。また、研究参加者が受けた説明や与えた同意の内容を記憶にとどめられるよう、当該説明及び同意の内容に関する資料を渡すなどの配慮が望ましいとされています。この記録は、研究の透明性を保つため、また後日何か問題が起きたときに証拠となるために重要です。'
prediction_3(S2) = '「口頭IC(記録作成含む。)」の記録とは、研究者が参加者に対して行った説明や参加者が与えた同意の内容を記録したものを指します。これは参加者が受けた説明や与えた同意の内容を記憶にとどめられるようにするためのものであり、特に参加者が記録を求める場合には提供することが望ましいとされています。\n\n具体的には、「同意の内容に関する記録」には、同意の日時、説明方法、説明者、同意事項等について記載する必要があります。これにより、研究の透明性が保たれ、参加者の権利が守られます。\n\nなお、適切な同意を受けて共同研究機関へ取得した試料・情報を提供する場合、同意の内容に関する記録を作成することが求められています。'
prediction_3(S3) = '「口頭IC(記録作成含む。)」とは、インフォームド・コンセント(IC)について口頭で説明し、口頭での同意を受けることを指します。この際に作成される「記録」は、行われた説明や受けられた同意の内容を記録したものです。具体的には、同意の日時、説明方法、説明者、同意内容等を記載します。これにより、研究対象者が受けた説明や与えた同意の内容を記憶にとどめられるようにすることが求められます。\n\n口頭での手続による場合でも、特に研究対象者が求める場合には、当該説明及び同意の内容に関する資料を渡す等の配慮を行うことが望ましいとされています。これらの記録は、後日何か問題が生じた場合や、研究結果を公表する際などに、研究対象者の同意の有無や同意内容を確認するための重要な証拠となります。'
prediction_3(S4) = '口頭によるインフォームド・コンセント(IC)での記録は、「同意の内容に関する記録」として、同意の日時、説明方法、説明者、同意事項等について記載する必要があります。これは、研究参加者が受けた説明や与えた同意の内容を明確に記録し、後から確認できるようにするためのものです。口頭での手続きの場合でも、研究対象者が受けた説明や与えた同意の内容を記憶にとどめられるよう、当該説明及び同意の内容に関する資料を渡すなどの配慮を行うことが望ましいとされています。'
prediction_3(S5) = '「口頭によるインフォームド・コンセント(IC)」における記録とは、口頭での説明や同意の内容を文書や電子データ等で残すことを指します。具体的には、説明や同意が行われた日時、説明の方法、説明を行った者の名前、同意の内容等を記録として残す必要があります。\n\nまた、研究対象者が受けた説明や与えた同意の内容を記憶にとどめられるよう、当該説明及び同意の内容に関する資料を渡すなどの配慮を行うことが望ましいとされています。\n\nこれは、後から研究の過程や結果が問題視された際などに、説明や同意のプロセスを明確に示すことができるようにするための措置です。また、研究対象者自身が自分が何に同意したのかを確認するための記録ともなります。'
```