From ec117366063d0c7c65187b6fa88cd73f265f1f66 Mon Sep 17 00:00:00 2001 From: Antonino Lorenzo <94693967+antoninoLorenzo@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:41:15 +0200 Subject: [PATCH] Integrated Gemini + removed tmp.ipynb --- test/benchmarks/rag/tmp.ipynb | 855 ---------------------------------- 1 file changed, 855 deletions(-) delete mode 100644 test/benchmarks/rag/tmp.ipynb diff --git a/test/benchmarks/rag/tmp.ipynb b/test/benchmarks/rag/tmp.ipynb deleted file mode 100644 index 6b01e28..0000000 --- a/test/benchmarks/rag/tmp.ipynb +++ /dev/null @@ -1,855 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "initial_id", - "metadata": { - "collapsed": true, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:30.161918Z", - "start_time": "2024-06-19T08:55:24.236921Z" - } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "import pandas as pd\n", - "from test.benchmarks.rag.evaluation import init_knowledge_base\n", - "from src.agent.knowledge import Store, Topic" - ] - }, - { - "cell_type": "code", - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Uploading owasp.json: 100%|██████████| 10/10 [00:09<00:00, 1.11it/s]\n" - ] - } - ], - "source": [ - "knowledge_base: Store = init_knowledge_base({\n", - " '../../../data/json/owasp.json': [Topic.WebPenetrationTesting]\n", - "})" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:41.829245Z", - "start_time": "2024-06-19T08:55:30.162921Z" - } - }, - "id": "b1441efd86811dd8", - "execution_count": 2 - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "collapsed": false - }, - "id": "84a65f908228afc9" - }, - { - "cell_type": "markdown", - "source": [ - "### Load Synthetic Dataset" - ], - "metadata": { - "collapsed": false - }, - "id": "ac205fbdbf95bc52" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "synthetic_qa_paths = [\n", - " '../../../data/rag_eval/owasp_100.json',\n", - " # '../../../data/rag_eval/owasp_100-200.json'\n", - "] " - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:41.836743Z", - "start_time": "2024-06-19T08:55:41.832744Z" - } - }, - "id": "ba2c82d6c78358f4", - "execution_count": 3 - }, - { - "cell_type": "code", - "outputs": [ - { - "data": { - "text/plain": " question \\\n0 How can a security professional choose appropr... \n1 Is any data transmitted in clear text, and are... \n2 What is the SQL injection vulnerability in the... \n3 What security measures are implemented to prev... \n4 What are the key security requirements to be c... \n.. ... \n95 What is the vulnerability category that is not... \n96 How can an attacker gain access to a user's au... \n97 What was the position of security logging and ... \n98 What are some prohibited attack scenarios rela... \n99 What are some example exploitable component vu... \n\n ground_truth \n0 Choose a CSPRNG-based initialization vector fo... \n1 The context does not provide any information a... \n2 The SQL injection vulnerability in the given s... \n3 The context does not provide sufficient inform... \n4 Secure design is a crucial phase in applicatio... \n.. ... \n95 The vulnerability category that is not include... \n96 The attacker can gain access to the user's aut... \n97 The position of security logging and monitorin... \n98 Scenario #1: A credential recovery workflow mi... \n99 CVE-2017-5638, Heartbleed vulnerability, Strut... \n\n[100 rows x 2 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
questionground_truth
0How can a security professional choose appropr...Choose a CSPRNG-based initialization vector fo...
1Is any data transmitted in clear text, and are...The context does not provide any information a...
2What is the SQL injection vulnerability in the...The SQL injection vulnerability in the given s...
3What security measures are implemented to prev...The context does not provide sufficient inform...
4What are the key security requirements to be c...Secure design is a crucial phase in applicatio...
.........
95What is the vulnerability category that is not...The vulnerability category that is not include...
96How can an attacker gain access to a user's au...The attacker can gain access to the user's aut...
97What was the position of security logging and ...The position of security logging and monitorin...
98What are some prohibited attack scenarios rela...Scenario #1: A credential recovery workflow mi...
99What are some example exploitable component vu...CVE-2017-5638, Heartbleed vulnerability, Strut...
\n

100 rows × 2 columns

\n
" - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df = pd.concat(\n", - " [pd.read_json(path) for path in synthetic_qa_paths],\n", - " ignore_index=True\n", - ")\n", - "df" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:41.868776Z", - "start_time": "2024-06-19T08:55:41.838744Z" - } - }, - "id": "87c213b188fbb94c", - "execution_count": 4 - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "collapsed": false - }, - "id": "a629ba80b9f6f7b7" - }, - { - "cell_type": "markdown", - "source": [ - "### Retrieve context and generate responses" - ], - "metadata": { - "collapsed": false - }, - "id": "554640690cff08aa" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "import textwrap\n", - "from datasets import Dataset\n", - "from tqdm import tqdm\n", - "from src.agent.llm import LLM" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:42.978746Z", - "start_time": "2024-06-19T08:55:41.870245Z" - } - }, - "id": "ff8adbd82ec644f8", - "execution_count": 5 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "sys_prompt = textwrap.dedent(\"\"\"\n", - "You are a Cybersecurity professional assistant, your job is to provide an answer to context specific questions.\n", - "You will be provided with additional Context information to provide an answer.\n", - "\"\"\")\n", - "\n", - "usr_prompt = textwrap.dedent(\"\"\"\n", - "Question: {query}\n", - "Context:\n", - "{context}\n", - "\"\"\")" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:42.990244Z", - "start_time": "2024-06-19T08:55:42.981745Z" - } - }, - "id": "96c8c76ec10f9101", - "execution_count": 6 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "llm = LLM(model='gemma:2b')\n", - "\n", - "def gen_context_answer(question: str):\n", - " points = knowledge_base.retrieve(question, 'owasp')\n", - " context_list = [f'{p.payload[\"title\"]}: {p.payload[\"text\"]}' for p in points]\n", - " context = '\\n'.join(context_list)\n", - " answer = llm.query(\n", - " messages=[\n", - " {'role': 'system', 'content': sys_prompt},\n", - " {'role': 'user', 'content': usr_prompt.format(query=question, context=context)}\n", - " ],\n", - " stream=False\n", - " )['message']['content']\n", - " \n", - " return context_list, answer" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T08:55:43.002744Z", - "start_time": "2024-06-19T08:55:42.993246Z" - } - }, - "id": "fcb81d39510e7c0f", - "execution_count": 7 - }, - { - "cell_type": "code", - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Retrieving context and generating answers.: 99%|█████████▉| 100/101 [1:07:39<00:40, 40.59s/it]\n" - ] - } - ], - "source": [ - "limit = 101\n", - "eval_data = []\n", - "for i, items in tqdm(df.iterrows(), total=limit, desc='Retrieving context and generating answers.'):\n", - " if i >= limit:\n", - " break\n", - " ctx, ans = gen_context_answer(items.question)\n", - " eval_data.append({\n", - " 'contexts': ctx,\n", - " 'question': items.question,\n", - " 'answer': ans,\n", - " 'ground_truth': items.ground_truth\n", - " })" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.228949Z", - "start_time": "2024-06-19T08:55:43.005746Z" - } - }, - "id": "cad1a2e72a2cce65", - "execution_count": 8 - }, - { - "cell_type": "code", - "outputs": [ - { - "data": { - "text/plain": " contexts \\\n0 [Cryptographic Failures: * Store passwords usi... \n1 [Cryptographic Failures: For all such data:\\n*... \n2 [Vulnerable and Outdated Components: Such flaw... \n3 [Vulnerable and Outdated Components: * Continu... \n4 [Insecure Design: How to Prevent\\n* Establish ... \n.. ... \n95 [Vulnerable and Outdated Components: It was #2... \n96 [Identification and Authentication Failures: A... \n97 [Security Logging and Monitoring Failures: Sec... \n98 [Insecure Design: Limit resource consumption b... \n99 [Vulnerable and Outdated Components: Such flaw... \n\n question \\\n0 How can a security professional choose appropr... \n1 Is any data transmitted in clear text, and are... \n2 What is the SQL injection vulnerability in the... \n3 What security measures are implemented to prev... \n4 What are the key security requirements to be c... \n.. ... \n95 What is the vulnerability category that is not... \n96 How can an attacker gain access to a user's au... \n97 What was the position of security logging and ... \n98 What are some prohibited attack scenarios rela... \n99 What are some example exploitable component vu... \n\n answer \\\n0 **How can a security professional choose appro... \n1 I am unable to provide a specific answer to th... \n2 Sure, here's an answer to the context question... \n3 **Security measures to prevent unauthorized ac... \n4 Sure, here are the key security requirements t... \n.. ... \n95 The vulnerability category that is not include... \n96 Sure, here is how an attacker can gain access ... \n97 Sure, here's the answer to your question:\\n\\nI... \n98 Sure, here are some prohibited attack scenario... \n99 Sure, here are some examples of exploitable co... \n\n ground_truth \n0 Choose a CSPRNG-based initialization vector fo... \n1 The context does not provide any information a... \n2 The SQL injection vulnerability in the given s... \n3 The context does not provide sufficient inform... \n4 Secure design is a crucial phase in applicatio... \n.. ... \n95 The vulnerability category that is not include... \n96 The attacker can gain access to the user's aut... \n97 The position of security logging and monitorin... \n98 Scenario #1: A credential recovery workflow mi... \n99 CVE-2017-5638, Heartbleed vulnerability, Strut... \n\n[100 rows x 4 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
contextsquestionanswerground_truth
0[Cryptographic Failures: * Store passwords usi...How can a security professional choose appropr...**How can a security professional choose appro...Choose a CSPRNG-based initialization vector fo...
1[Cryptographic Failures: For all such data:\\n*...Is any data transmitted in clear text, and are...I am unable to provide a specific answer to th...The context does not provide any information a...
2[Vulnerable and Outdated Components: Such flaw...What is the SQL injection vulnerability in the...Sure, here's an answer to the context question...The SQL injection vulnerability in the given s...
3[Vulnerable and Outdated Components: * Continu...What security measures are implemented to prev...**Security measures to prevent unauthorized ac...The context does not provide sufficient inform...
4[Insecure Design: How to Prevent\\n* Establish ...What are the key security requirements to be c...Sure, here are the key security requirements t...Secure design is a crucial phase in applicatio...
...............
95[Vulnerable and Outdated Components: It was #2...What is the vulnerability category that is not...The vulnerability category that is not include...The vulnerability category that is not include...
96[Identification and Authentication Failures: A...How can an attacker gain access to a user's au...Sure, here is how an attacker can gain access ...The attacker can gain access to the user's aut...
97[Security Logging and Monitoring Failures: Sec...What was the position of security logging and ...Sure, here's the answer to your question:\\n\\nI...The position of security logging and monitorin...
98[Insecure Design: Limit resource consumption b...What are some prohibited attack scenarios rela...Sure, here are some prohibited attack scenario...Scenario #1: A credential recovery workflow mi...
99[Vulnerable and Outdated Components: Such flaw...What are some example exploitable component vu...Sure, here are some examples of exploitable co...CVE-2017-5638, Heartbleed vulnerability, Strut...
\n

100 rows × 4 columns

\n
" - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eval_dataset = pd.DataFrame(eval_data)\n", - "eval_dataset" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.424948Z", - "start_time": "2024-06-19T10:03:22.255947Z" - } - }, - "id": "9ef8a49e35990408", - "execution_count": 9 - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "collapsed": false - }, - "id": "a77551bf33d25a5d" - }, - { - "cell_type": "markdown", - "source": [ - "### Evaluate with LLM as a judge" - ], - "metadata": { - "collapsed": false - }, - "id": "85c9e2d9ed6fd3c4" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "import re\n", - "import os\n", - "import json\n", - "from json import JSONDecodeError\n", - "from dataclasses import dataclass\n", - "from abc import ABC, abstractmethod\n", - "\n", - "import requests\n", - "import numpy as np\n", - "from dotenv import load_dotenv\n", - "load_dotenv()\n", - "\n", - "hf_api_key = os.environ.get('HF_API_KEY')\n", - "API_URL = \"https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.3\"\n", - "json_pattern = r'{\"result\": \\[[^\\]]*\\]}'" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.442449Z", - "start_time": "2024-06-19T10:03:22.428945Z" - } - }, - "id": "5580a76d77c3a1dd", - "execution_count": 10 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "@dataclass\n", - "class HuggingFaceLLM:\n", - " \"\"\"Represents HuggingFace Inference Endpoint\"\"\"\n", - " url: str\n", - " key: str\n", - " \n", - " def __post_init__(self):\n", - " self.headers = {\"Authorization\": f\"Bearer {self.key}\", \"Content-Type\": \"application/json\"}\n", - "\n", - " def __query(self, payload):\n", - " response = requests.post(self.url, headers=self.headers, json={'inputs': payload})\n", - " response.raise_for_status()\n", - " return response.json()\n", - " \n", - " def query(self, messages: list):\n", - " prompt = '\\n'.join([msg['content'] for msg in messages])\n", - " return self.__query(prompt)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.459947Z", - "start_time": "2024-06-19T10:03:22.445947Z" - } - }, - "id": "c15f7e7e8fb88cce", - "execution_count": 11 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "@dataclass\n", - "class Metric(ABC):\n", - " \"\"\"Represents a RAG evaluation metric using LLM-as-a-judge paradigm\"\"\"\n", - " system_prompt: str\n", - " user_prompt: str\n", - " llm_provider: HuggingFaceLLM\n", - " \n", - " @abstractmethod\n", - " def compute(self, *args, **kwargs) -> float:\n", - " \"\"\"Needs to be implemented to evaluate a metric\"\"\"\n", - " pass\n", - " \n", - " \n", - "class ContextRecall(Metric):\n", - " \"\"\"Assesses how much the answer is based on the context\"\"\"\n", - " \n", - " def compute(self, answer: str, context: str):\n", - " \"\"\"Computes context recall given answer and context\"\"\"\n", - " messages = [\n", - " {'role': 'system', 'content': self.system_prompt},\n", - " {'role': 'user', 'content': self.user_prompt.format(answer=answer, context=context)}\n", - " ]\n", - " \n", - " result = self.llm_provider.query(messages)\n", - " result = result[0]['generated_text'].split('\\n')[-1]\n", - " \n", - " try:\n", - " return np.mean(json.loads(result)['result'])\n", - " except JSONDecodeError:\n", - " match = re.search(json_pattern, result)\n", - " if match:\n", - " return np.mean(json.loads(match.group())['result'])\n", - " else:\n", - " return result\n", - " \n", - " \n", - "class ContextPrecision(Metric):\n", - " \"\"\"Assesses how much the context was useful in generating the answer\"\"\"\n", - " \n", - " def compute(self, question: str, answer: str, context: str):\n", - " \"\"\"Uses question, answer and context\"\"\"\n", - " messages = [\n", - " {'role': 'system', 'content': self.system_prompt},\n", - " {'role': 'user', 'content': self.user_prompt.format(question=question, answer=answer, context=context)}\n", - " ]\n", - " \n", - " result = self.llm_provider.query(messages)\n", - " result = result[0]['generated_text'].split('\\n')[-1]\n", - " \n", - " try:\n", - " return np.mean(json.loads(result)['result'])\n", - " except JSONDecodeError:\n", - " match = re.search(json_pattern, result)\n", - " if match:\n", - " return np.mean(json.loads(match.group())['result'])\n", - " else:\n", - " return result" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.502947Z", - "start_time": "2024-06-19T10:03:22.480446Z" - } - }, - "id": "93059f0f04e3a35b", - "execution_count": 12 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "mistral_context_recall_sys = textwrap.dedent(\"\"\"\n", - "Given a context, and an answer, analyze each sentence in the answer and classify if the sentence can be attributed to the given context or not. Use only \"Yes\" (1) or \"No\" (0) as a binary classification. \n", - "\n", - "Your output should contain a list of 0 or 1 for each sentence, also it should be a JSON string as follows:\n", - "{{\"result\": [1, 0, ...]}}\n", - "\n", - "IMPORTANT:\n", - "- Only provide the JSON string in the specified format. Do not include any additional text.\n", - "- If the answer mentions that available information wasn't sufficient, your response should be the following: {{\"result\": [0]}}\n", - "\"\"\")\n", - "\n", - "mistral_context_recall_usr = textwrap.dedent(\"\"\"\n", - "Answer:\n", - "{answer}\n", - "\n", - "Context:\n", - "{context}\n", - "\n", - "Your output should contain a list of 0 or 1 for each sentence, also it should be a JSON string as follows:\n", - "{{\"result\": [1, 0, ...]}}\n", - "\n", - "IMPORTANT:\n", - "- Only provide the JSON string in the specified format. Do not include any additional text.\n", - "- If the answer mentions that available information wasn't sufficient, your response should be the following: {{\"result\": [0]}}\n", - "\"\"\")\n", - "\n", - "mistral_context_precision_sys = textwrap.dedent(\"\"\"\n", - "Given question, answer and context verify if the context was useful in arriving at the given answer. \n", - "Use only \"Useful\" (1) or \"Not Useful\" (0) as a binary classification. \n", - "\n", - "Your output should contain a list of 0 or 1 for each sentence, also it should be a JSON string as follows:\n", - "{{\"result\": [1, 0, ...]}}\n", - "\n", - "IMPORTANT:\n", - "- Only provide the JSON string in the specified format. Do not include explanations or any additional text.\n", - "- If the answer do not provide a response to the question or mentions that available information wasn't sufficient, your response should be the following: {{\"result\": [0]}}\n", - "\"\"\")\n", - "\n", - "mistral_context_precision_usr = textwrap.dedent(\"\"\"\n", - "Question:\n", - "{question}\n", - "\n", - "Context:\n", - "{context}\n", - "\n", - "Answer:\n", - "{answer}\n", - "\n", - "Your output should contain a list of 0 or 1 for each sentence, also it should be a JSON string as follows:\n", - "{{\"result\": [1, 0, ...]}}\n", - "\n", - "IMPORTANT:\n", - "- Only provide the JSON string in the specified format. Do not include explanations or any additional text.\n", - "- If the answer do not provide a response to the question or mentions that available information wasn't sufficient, your response should be the following: {{\"result\": [0]}}\n", - "\"\"\")" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.515447Z", - "start_time": "2024-06-19T10:03:22.505947Z" - } - }, - "id": "a6d59f4490fc1fe2", - "execution_count": 13 - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "collapsed": false - }, - "id": "1a09019a25040f02" - }, - { - "cell_type": "markdown", - "source": [ - "## Run Evaluation" - ], - "metadata": { - "collapsed": false - }, - "id": "8e53f6a6dd302f45" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "hf_llm = HuggingFaceLLM(API_URL, hf_api_key)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:03:22.528945Z", - "start_time": "2024-06-19T10:03:22.517448Z" - } - }, - "id": "c682374384fe0ee5", - "execution_count": 14 - }, - { - "cell_type": "code", - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Measuring Context Recall: 100%|██████████| 100/100 [02:06<00:00, 1.26s/it]\n" - ] - } - ], - "source": [ - "ctx_recall = ContextRecall(mistral_context_recall_sys, mistral_context_recall_usr, hf_llm)\n", - "recall = []\n", - "for i, item in tqdm(eval_dataset.iterrows(), total=len(eval_dataset), desc='Measuring Context Recall'):\n", - " ctx = '\\n\\n'.join(item.contexts)\n", - " ans = item.answer\n", - " recall.append(ctx_recall.compute(ans, ctx))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:05:28.941230Z", - "start_time": "2024-06-19T10:03:22.530947Z" - } - }, - "id": "6190b68800bfa74e", - "execution_count": 15 - }, - { - "cell_type": "code", - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Measuring Context Recall: 100%|██████████| 100/100 [02:03<00:00, 1.24s/it]\n" - ] - } - ], - "source": [ - "ctx_precision = ContextPrecision(mistral_context_precision_sys, mistral_context_precision_usr, hf_llm)\n", - "precision = []\n", - "for i, item in tqdm(eval_dataset.iterrows(), total=len(eval_dataset), desc='Measuring Context Recall'):\n", - " qst = item.question\n", - " ctx = '\\n\\n'.join(item.contexts)\n", - " ans = item.answer\n", - " precision.append(ctx_precision.compute(qst, ans, ctx))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:07:32.809616Z", - "start_time": "2024-06-19T10:05:28.942231Z" - } - }, - "id": "1c96601b8555eea3", - "execution_count": 16 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "clean_recall = []\n", - "for r in recall:\n", - " try:\n", - " rec = float(r)\n", - " except ValueError:\n", - " rec = 0\n", - " clean_recall.append(rec)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:20.220081Z", - "start_time": "2024-06-19T10:10:20.216081Z" - } - }, - "id": "579449b7b229c53b", - "execution_count": 26 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "clean_precision = []\n", - "for p in precision:\n", - " try:\n", - " pr = float(p)\n", - " except ValueError:\n", - " pr = 0\n", - " clean_precision.append(pr)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:34.168549Z", - "start_time": "2024-06-19T10:10:34.164549Z" - } - }, - "id": "aefb6d3a76454398", - "execution_count": 28 - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "collapsed": false - }, - "id": "275c633e8efb004f" - }, - { - "cell_type": "markdown", - "source": [ - "## Output plots" - ], - "metadata": { - "collapsed": false - }, - "id": "6fe0391f00ed4786" - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import seaborn as sns" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:39.161021Z", - "start_time": "2024-06-19T10:10:39.157521Z" - } - }, - "id": "6415e330adf8a1dd", - "execution_count": 29 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "evaluation = {\n", - " 'context_recall': clean_recall,\n", - " 'context_precision': clean_precision\n", - "}\n", - "eval_results = pd.DataFrame(evaluation)\n", - "\n", - "with open('../../../data/rag_eval/results/results.json', 'r+', encoding='utf-8') as fp:\n", - " content: list = json.load(fp)\n", - " res = eval_results.mean()\n", - " content.append({'context_precision': res.context_precision, 'context_recall': res.context_recall})\n", - " fp.seek(0)\n", - " json.dump(content, fp, indent=4)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:50.744545Z", - "start_time": "2024-06-19T10:10:50.737545Z" - } - }, - "id": "7adfb65846e177fd", - "execution_count": 30 - }, - { - "cell_type": "code", - "outputs": [ - { - "data": { - "text/plain": " context_precision context_recall\n0 0.000000 0.000000\n1 0.661228 0.487287", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
context_precisioncontext_recall
00.0000000.000000
10.6612280.487287
\n
" - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eval_history = pd.DataFrame(content)\n", - "eval_history" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:51.590752Z", - "start_time": "2024-06-19T10:10:51.581253Z" - } - }, - "id": "96dae7b40c52e944", - "execution_count": 31 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "def plot_eval(df: pd.DataFrame, name: str):\n", - " sns.lineplot(data=df, x='x', y='y', zorder=0)\n", - " plt.scatter(\n", - " df.iloc[1:]['x'], \n", - " df.iloc[1:]['y'], \n", - " color='#000000', \n", - " s=15,\n", - " zorder=1\n", - " ) \n", - " \n", - " plt.ylim(0, 1) \n", - " plt.xticks(range(0, len(df)))\n", - " \n", - " plt.title(f'RAG Evaluation: {name}')\n", - " plt.ylabel(name)\n", - " plt.xlabel('')\n", - " return plt" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:55.325668Z", - "start_time": "2024-06-19T10:10:55.321687Z" - } - }, - "id": "e06d33ce8aabf3a5", - "execution_count": 32 - }, - { - "cell_type": "code", - "outputs": [], - "source": [ - "plots = {}\n", - "for col in eval_history.columns:\n", - " values = eval_history[col].to_list()\n", - " plots[col] = [{'x': i, 'y': val} for i, val in enumerate(values)]\n", - "\n", - "ctx_precision_df = pd.DataFrame(plots['context_precision'])\n", - "ctx_recall_df = pd.DataFrame(plots['context_recall'])" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:57.005979Z", - "start_time": "2024-06-19T10:10:57.001479Z" - } - }, - "id": "49190b77c14b8c7f", - "execution_count": 33 - }, - { - "cell_type": "code", - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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f39/Bg0aZA41ffr0ISoqiilTpnDu3DkyMjJ49dVXadKkCUOHDqVHjx48/vjjACxevJgePXpc82u/ltzcXE6cOFHktM6MGTMYPXo048aNIyIigu3bt9O/f39cXV3573//y6uvvsq2bdvo27cv2dnZAJw+fZonn3ySuLg4xo8fz9tvv01KSgr9+vUjLS2tyHvPnTuXzz//nOHDhzNv3jyeeuopPvroI/P37e9K6uchFZtOOUm5sn37dvO1BJfZ2dlxxx138L///Y8OHToU+tzy5cu54447aNSoEQDdu3dn6dKl/PTTTzz00EMAnD9/nvPnz1/1X/5/vxDYzs4OBweH68742muv8dprrxVZ7u7ubr5m4pFHHmHZsmXExMTQrFkzAH744Qdq165No0aNyM3N5eLFi4wdO9Ycopo3b05GRgaTJ08mJSWFatWqXXeOazlz5gwvvPBCoYuJXVxcGDlyJAcPHqRJkybmnWSDBg0ICgoqso3ly5dz6NAhvvjiCyIiIgBo27YtBoOBWbNm0bNnT6pUqQJA5cqVmTVrlvn7dvz4caZPn05qaipVq1a95mnEvzp16hTAVWe5mhkzZuDs7MzChQvN1/20b9+erl27MnXq1EJHku6++25zwGrVqhUbN27kt99+46WXXqJu3brm11+e8csvv+TAgQN8+eWXhIeHA6ZTnn369OGdd95h2bJl2NnZMWnSJB5++GHefvttHBwcSEtLY8GCBTg4OODv74+/v3+h7V7P5ZAMpt/JkydPMmvWLM6dO0fv3r0LrdurVy86d+5s/njatGmEhoYyZ84c888gPDycBx98kGXLltG7d2/mz59Pbm4uH3/8sfn36s477+Spp55i9+7d1KlTp9B7bNu2jbvuuovHHnsMMP1uurm54enpWao/D6nYFGikXAkLC2PChAmAacf83//+l7y8PP773/9Su3btQuueO3eOX3/9laFDh5Keng5AvXr1CAwMZPHixeZAU1BQcNX3io+P57777iu0LDAw8IZ3lowYMeKqRxv+GoSaN29OQEAAP/zwA82aNSMnJ4fVq1czePBgwHQNwkcffQSY/vUcGxtLXFwcv/76K0CRI0yWmDZtGmD6/hw7doz4+HiLt7tt2zYCAwPNYeayhx9+mKVLl7J7927zdR2NGjUq9LVf3pFnZWVRtWrVYr3f5ddfPspVnPk6dOhQ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pUuXMmzYMEaOHMnPP/9Mly5dWLFiBS+++OINZ3n//fd58sknr/rn7bffLrRu165dsbOzo0OHDoXuEAkJCWHatGmcPn2a5557jnHjxgHwySefYGdnx44dO6763pMnT+auu+5i7NixjBkzhrCwMPr162f+vKenJ7NmzcJoNPL888/z8ssvk5iYyKeffkqlSpXM223RogWtW7dm2rRpRZ6XA6ZTFZ988gkdOnTgf//7H8899xwxMTFMnDiRkSNH3vB79Fd//PEHTz75pDmsXUtAQACLFy/miSee4Pvvv2f48OGMHTuWxMREpk2bxvjx483r1qtXj88++wwfHx/GjBnD//3f/2E0Glm4cCGtW7e2aL7evXvj5OTEs88+y7p163B3d2fRokVERkby9ttv8+yzz7Jq1Speeukl8/N7JkyYQFZWlvkCdjA97ddoNJrvgLvvvvto1KgRr7zyivkC8NIQHR3NRx99RFJSEqNGjeLll1/GwcGBjz/+2HwBbo0aNfjss8+oXr06r7zyCmPGjKFGjRosWLDAfD3QXz3//PMMHTqUZcuWMWjQICZPnkx0dDTvvffeVWcoyZ+HVFx2Rl1NJSIiIjZOR2hERETE5inQiIiIiM0rE4EmNzeXrl27mq+ov5o///yTHj16EB4ezmOPPca+fftu44QiIiJSllk90OTk5PDiiy9y+PDha66TmZnJ4MGDadasGcuXLyciIoIhQ4aokExEREQAKweaI0eO8MQTT3D8+PHrrrdixQpcXFx4+eWXqVOnDq+99hqVKlVi5cqVt2lSERERKcusGmi2bdtGixYtWLx48XXX2717N5GRkeaHh9nZ2dG0adNrPstDREREKharPlivV69exVovOTm5yOPMfXx8rnuaSkRERCoOq19DUxxZWVlFHn3t7Ox8S43CIiIiUn7YRPWBi4tLkfCSm5uLq6urxds6d+4CJfkoQTs78Pb2LPHtioiI2IrS3Bde3vaN2ESg8fPzK9LEmpKSQvXq1S3eVkEBJR5oSmO7IiIitqI094V/K3O/Jps45RQeHs7OnTvNDcJGo5Hff/+d8PBwK08mIiIiZUGZDTTJyclkZ2cD0LlzZ9LT05k4cSJHjhxh4sSJZGVl8cADD1h5ShERESkLymygiY6OZsWKFQB4eHgwZ84cYmJi6N69O7t37+aDDz7A3d3dylOKiIhIWVDh2rZTUkr+omBfX88S366IiIitKM194eVt30iZPUIjIiIiUlwKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNk+BRkRERGyeAo2IiIjYPAUaERERsXkKNCIiImLzFGhERETE5inQiIiIiM1ToBERERGbp0AjIiIiNs+qgSYnJ4dXX32VZs2aER0dzbx586657s8//8wDDzxAREQETz31FH/88cdtnFRERETKMqsGmqlTp7Jv3z4WLFjA66+/zowZM1i5cmWR9Q4fPsxLL73EkCFD+Oabb2jQoAFDhgwhKyvLClOLiIhIWWO1QJOZmcmSJUt47bXXCAsL495772XQoEEsWrSoyLobN26kbt26dOvWjeDgYF588UWSk5M5cuSIFSYXERGRssZqgebAgQMYDAYiIiLMyyIjI9m9ezcFBQWF1q1SpQpHjhwhJiaGgoICli9fjoeHB8HBwbd7bBERESmDHK31xsnJyVStWhVnZ2fzMl9fX3JyckhLS8Pb29u8vEuXLqxZs4ZevXrh4OCAvb09c+bMwcvLy+L3tbMrkfGLbK+ktysiImIrSnNfWNxtWi3QZGVlFQozgPnj3NzcQstTU1NJTk5m3LhxhIeH8/nnnzNmzBi++uorfHx8LHpfHx/PWxv8Nm9XRETEVlhzX2i1QOPi4lIkuFz+2NXVtdDyd955hzvuuIPevXsD8MYbb/DAAw+wbNkyBg8ebNH7nj17AaPxFgb/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" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt_ctx_precision = plot_eval(ctx_precision_df, 'Context Precision')\n", - "plt_ctx_precision.savefig('../../../data/rag_eval/results/plots/context_precision.png')" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:57.664450Z", - "start_time": "2024-06-19T10:10:57.391951Z" - } - }, - "id": "1ccfce4deaebd47", - "execution_count": 34 - }, - { - "cell_type": "code", - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjQAAAGxCAYAAAB1Hiz1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABEu0lEQVR4nO3deVxWdd7/8TeCLAougAKamrkgsom7ZaXWrWYuQMtYM2phozWl85tqItMxLA0zW+4W78zyLsvpNhfU3DK1rLHUMhVxxX0DBQUX9uX8/kAuvQSVS4GLA6/n4+FjhsO5zvVh0evd+3zPuRwMwzAEAABgYrXsPQAAAMCtItAAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAqBTcw7NIRX0f+P6ipiPQoEYaNmyY/P39rf60a9dOHTt2VGRkpJYsWXLNxw4dOlT+/v767rvvrvscBw4c0Ouvv65+/fopNDRUnTp10tChQ/Xvf/9b+fn5133s8ePHS8x39Z+vv/76pr72axk2bJiGDRtWrseUpOTkZI0aNUonTpywbOvTp49efvnlcn8uW+Tk5Ojzzz/XQw89pE6dOqlr164aOnSoFi9eXGHhYO3atYqOji734yYmJuqxxx677j6bNm0q9fcoKChI99xzj1566SWlpKSU+2xlceXvQ/GcmzZtssssMC8new8A2Ev79u316quvWj4uKChQcnKyPv/8c7300ktq0KCB7r33XqvHHDx4UFu3blXbtm31f//3f+rXr1+px16xYoXGjRunVq1a6cknn1TLli2VnZ2t9evX64033tDPP/+sGTNmyMHB4bozPvPMM+rVq1epn2vWrJltX7Cd/PLLL1q/fr3Vtg8//FDu7u52mkhKTU3VU089paSkJA0bNkwhISEqLCzUDz/8oJdfflm///67Xn/99Rv+fGz1+eefl+vxiq1atUpbt24t074TJ05UYGCg5eOMjAxt2bJFn3zyiQ4dOqT58+dXyIxARSPQoMZyd3dXhw4dSmy/55571KNHDy1atKhEoFm0aJGaNm2q0aNH68UXX9SRI0fUokULq30OHDigcePG6e6779Z7770nJ6fLf83uvfdedevWTWPHjtXKlSs1YMCA687YvHnzUmc0u/bt29v1+aOjo5WcnKx58+bp9ttvt2zv1auXmjRponfeeUe9e/fWfffdZ78hK0jr1q1L/E7dddddys3N1axZs7R//361bt3aPsMBt4BTTsBVXFxc5OzsXOK/zgsKCrR48WL17t1b999/v+rUqaN58+aVePynn36qWrVqadKkSVZhpli/fv0UHh5eLrPm5OSoU6dOevPNN6225+fnq3v37po8ebIkKTs7W2+//bb69u2roKAgdezYUU8++aR2795d6nGLT3ktWrTIavvLL7+sPn36WD4uKCjQJ598ooEDByokJEQdOnTQ0KFDtXHjRklFAXDcuHGSpPvuu89yWuHqU04XLlxQbGys7r//fgUHB2vgwIFasGCB1XP36dNH77//vt58803deeedCgkJ0ciRI3X48GHLPsWnK66e+0q7d+/Wf/7zH40cOdIqzBR74okn9Oc//1l16tSxbDt8+LDGjh2ru+66Sx06dNCwYcO0ZcuWEt+vlStXauzYsQoLC1PXrl01YcIEZWZmSio6pbd582Zt3rzZ6pRKenq6Jk6cqDvvvFPBwcF69NFH9euvv1qOPWfOnBJf08aNG9WuXTt99NFH+uCDD/Thhx9Kkvz9/fXBBx9c82u/nnr16kmS1e/9vn37NHr0aHXs2FEdO3bUs88+q2PHjlk97vTp04qOjlaPHj0UFhamv/zlL1Zt0dmzZzVp0iT17t1bQUFB6tq1q5599lkdP378puYEroVAgxrLMAzl5+db/uTk5OjgwYMaN26cMjIyNGTIEKv9f/rpJ6WkpCg8PFyurq564IEHFBcXp9zcXKv91q5dq+7du8vLy+uaz/3mm2/esJ2RpMLCQqsZi/8UFBRIKgpf/fr108qVK63WfWzYsEFpaWmWr+Gll17SwoULNWrUKM2ePVvjxo1TYmKiXnjhhVtaLzJ9+nTNmDFDf/rTn/Tpp5/q9ddfV3p6uv7+978rKytLvXr10jPPPCOp6DTT3/72txLHyM7O1uOPP65vv/1WTz31lGbMmKFOnTpp/Pjx+vjjj632nTNnjg4ePKjY2FhNnjxZCQkJVmtSAgMDNW/evGueppOkn3/+WZKsgtmVXFxcNHHiRPXo0UOStH//fkVGRur48eOaMGGCpk+fLgcHB40YMUKbN2+2euyrr76qpk2basaMGRo5cqQWLFig//mf/7F8rn379mrfvr3mzZunwMBA5eTkaMSIEVq7dq3+8Y9/6MMPP5Svr6+eeuopS6gZNmyYunTpojfffFNnz57VxYsX9corr6hDhw56+umn9cgjj+jhhx+WJM2bN0+PPPLINb92qeTvVHp6ulavXq3PPvtMISEhatmypSTp0KFDGjp0qM6cOaM333xTU6ZM0bFjx/TYY4/pzJkzkopOVz322GPatGmT/vnPf+rDDz+Ui4uLoqKidPjwYRmGodGjR2vDhg168cUX9dlnn+m5557Tr7/+anW6FygPnHJCjfXbb79ZrSWQiv7rtG3btvrv//5v9e7d2+pzixYtUtu2bRUcHCxJioyM1IIFC/Tdd99p0KBBkqRz587p3Llzpf6X/9ULgR0cHOTo6HjdGcePH6/x48eX2F6nTh3LfwUPGTJECxcu1JYtW9S5c2dJ0vLly3XHHXcoODhYubm5ysjI0IQJEywhqmvXrrp48aKmTp2q1NRUNWrU6LpzXMvp06f1j3/8w2oxsYuLi8aMGaO9e/eqQ4cOat68uSQpICBAt912W4ljLFq0SPv27dP//d//KSwsTJJ09913Kz8/XzNmzNDQoUPVoEEDSUUtwowZMyzft6NHj+qDDz5QWlqaGjZseM3TiFdKSkqSpFJnKc2HH34oZ2dnzZkzx7Lup1evXho4cKCmTZtm1STde++9loDVo0cPbdiwQT/++KNeeOEFtW7d2vL44hm/+eYb7dmzR998841CQ0MlFZ3yHDZsmKZPn66FCxfKwcFBsbGxGjx4sN566y05OjoqPT1dX3zxhRwdHeXr6ytfX1+r417PE088UWJb/fr1dd999+mf//ynatWqZfm63dzc9Pnnn1vm7tGjh+6//359+umnio6OVlxcnE6cOKG4uDgFBARIkjp27Kjw8HD99ttvcnNzk5ubm6Kjoy2/m926ddPRo0dLbTeBW0GgQY0VGBioSZMmSSp6YX7vvfeUl5en9957T3fccYfVvmfPntUPP/ygp59+WufPn5cktWnTRk2bNtW8efMsgaawsLDU5zpy5Ij69u1rta1p06Zat27ddWd87rnnSm0brgxCXbt2VZMmTbR8+XJ17txZOTk5WrNmjUaNGiVJcnZ21meffSZJOnXqlA4dOqTDhw/rhx9+kKQSDZMt3n77bUlF35+DBw/qyJEjNh938+bNatq0qSXMFBs8eLAWLFig7du3W9YyBQcHW33txS/kWVlZatiwYZmer/jxxS1XWebr3bu31SJmJycnPfjgg/roo4+UkZFh2X51oPD19bW6uutqv/76qxo1aqTAwECrwNu7d29NmzZN586dU/369dWsWTO9+OKLev3112UYhmJjY296UfikSZMUGBiowsJCrV27Vp9++qmGDRumMWPGWO23ceNGde3aVa6urpbZ3N3d1blzZ/3yyy+SpC1btui2226zhBlJcnNzs7oCcM6cOTIMQ8ePH9eRI0d08OBB/fHHH7f0eweUhkCDGqtu3bqWtkWSQkNDNXjwYEVFRWnRokXy9PS0fG7p0qXKy8vTBx98UGKNwokTJ3TgwAG1atVKDRs2VJ06dUq8iPn5+Vn9l/xHH32kffv23XDGpk2bWs1YGgcHBw0aNEjz58/XhAkT9MMPPygzM9MSsqSi0yxvvPGGDh48qLp166pdu3aWNSK3csppx44dmjRpknbs2CE3Nze1bt1aTZo0sem4586dK7Uh8vb2liRLgJSKXiyvVNwmXCtIlqZp06aSpJMnT15z8eupU6fUuHFjOTg46Ny5c5ZZrp7PMAxdvHjxuvNd7/uQnp6ulJSUEk1hsZSUFNWvX1+SNGDAAE2dOlVS0SLem9WyZUvL71RoaKhq165tOVVUHIKLZ1uxYoVWrFhR4hjFfzfS09Ove2pVKvq788477ygpKUkNGjRQQECAXF1db3p+4FoINMAl3t7emjhxov7+979rypQplvZBkhYuXKiwsDD94x//sHpMZmam/va3v+nrr7/WhAkTJBWtzfjhhx908eJFy3/VOzs7WwWT4lMo5WXIkCGaOXOmNm3apBUrVqhLly6WF+6jR4/q2Wef1f3336+ZM2eqWbNmcnBw0Ny5cy3rSa5WvDD06hajeIGrJF28eFFPPfWU/P39Lae4atWqpfXr19/wHj1Xql+/vo4cOVJie/E9UcravJRVz549JUnr168vNdDk5+dryJAh6tixo2bMmKH69esrNTX1uvOdPn36pmbx8PDQ7bffrunTp5f6+StPi02ePFl169aVs7OzJk6cqJkzZ97Uc17tmWee0Zo1a/T++++rV69eatu2rWW2O++8U08++WSJxxQvdvfw8Ch1ce8ff/yh+vXrKy0tTdHR0Ro2bJhGjhwpHx8fSdK0adOsFlUD5YFFwcAV+vfvr7vvvlvLli2zLPjcsWOH9u3bp8jISHXr1s3qT+/evdW9e3ctWbJE2dnZkqRRo0YpPz9fEyZMKLVWz87OLnGlyK1q1aqVAgMDtXz5cq1fv16DBw+2fC4hIUE5OTkaNWqUmjdvbgkrxWGmtAahOIidOnXKsi0vL0/x8fGWjw8ePKj09HQNHz5crVu3trQlP/30k6TLrUnx9mvp0qWLTpw4UeI+KkuXLlXt2rUVEhJStm9CGbVp00b33HOPZs2aVerPYebMmUpLS7N8D7t06WIJqMUKCgq0fPlyBQcHy9nZuczPffX3omvXrkpKSpKXl5eCg4MtfzZs2KBPP/3Ucnps9erVWrZsmcaNG6eJEyfqxx9/1MKFC695XFs4OTkpJiZG+fn5lqviimfbv3+/AgICLHMFBQXp888/1/fffy9J6ty5s44dO6bExETL43JycjRmzBgtWLBAW7duVWFhocaMGWMJMwUFBZZTVrY0a8CN0NAAV3nllVc0ePBgTZ48WXFxcVq4cKFq165dYg1MsSFDhuiXX37RihUrFBkZKX9/f7311lsaN26cIiMj9fDDD8vf31/5+fnaunWrFixYYLmx240cPXpU27ZtK/Vz9evXt1yRUjzHm2++KScnJ/Xv39+yPTAwUE5OTnrrrbcUFRWl3NxcLVq0SD/++KMk69blymOHhYXpyy+/VIsWLVS/fn3NmTNH2dnZllNVLVu2lLu7uz7++GM5OTnJyclJ3333neXUWlZWlqTLlwN///33uueee9SqVSur54qMjNS///1vPfvssxo7dqxuu+02rVu3TgsXLtRzzz1neXxZXLx4Ufv371fz5s2tThlebdKkSRoxYoQeffRRDR8+XKGhocrIyNCqVau0fPlyDR061PI9fO655/TTTz9p+PDhGjVqlGrXrq2vvvpKx44d06efflrm2Yq/F1u3btWvv/6q9u3bKzIyUl999ZWefPJJPf300/Lz89Mvv/yiWbNm6S9/+Ytq166ts2fPKiYmRj179rRctXb//fcrNjZWd911l3x9fS3fo2XLlik0NNTm9TVhYWEaPHiwlixZopUrV+qBBx7Q3/72Nw0dOlSjR4/WY489JhcXF82bN8/S5khFP7svv/xSzzzzjMaOHauGDRtqzpw5ysvL0+OPP66TJ09Kkl577TU99NBDOnfunObOnas9e/ZIKvrds+cNFlHNGEAN9Je//MX4y1/+cs3PT5061Wjbtq3x5ZdfGp07dzZGjRp1zX0zMjKMDh06GI888ojV9uPHjxtvvfWW8eCDDxodOnQwQkNDjYEDBxqxsbHGoUOHrjvfsWPHjLZt2173zzPPPGP1mNTUVKN9+/bG2LFjSxxv5cqVxoMPPmgEBwcbPXv2NJ577jlj8+bNhr+/v/HVV1+V+j05dOiQERUVZYSEhBh33nmn8c477xgzZswwevfubdln48aNRmRkpBESEmL06NHDiIqKMn7//XcjLCzMePPNNw3DMIyLFy8aTzzxhBEYGGj89a9/NQzDMHr37m1ER0dbjnPmzBnjlVdeMbp3724EBQUZgwcPNubPn2/1NVz9GMMwjIULFxpt27Y1jh07Zpmnbdu2xsKFC6/7/S1+znfeeccYMGCA0aFDB6Nr167G0KFDjWXLlhmFhYVW++7atct46qmnjA4dOhhhYWHGiBEjjN9++83y+eKf19XPGx0dbfX9+vXXX41evXoZgYGBxtKlSw3DKPq5jRs3zujRo4cRFBRk9OvXz5g1a5ZRUFBgGIZhjB071ujQoYPlazQMw0hOTjY6duxoREVFWT5+6KGHjMDAQOPVV18t9est/t5s3Lix1M+fOnXKCAsLM3r16mVkZmYahmEYCQkJxsiRI42wsDCjQ4cOxqOPPmqsWbPG6nHJycnG888/b3Tu3Nky0+7duy2f/+qrr4z77rvPCAoKMnr16mVER0cb33//vdG2bVvjxx9/NAzD+md7ozmBa3EwDN7RDAAAmBtraAAAgOkRaAAAgOlViUCTm5urgQMHXvft4nft2qVHHnlEoaGheuihh5SQkFCJEwIAgKrM7oEmJydHzz//vNVlf1fLzMzUqFGj1LlzZy1atEhhYWEaPXp0qVdnAACAmseugWb//v169NFHdfTo0evut2LFCrm4uOill15Sq1atNH78eNWtW1erVq2qpEkBAEBVZtdAs3nzZnXr1u2Gb1K2fft2derUyXJDMAcHB3Xs2PGa9+cAAAA1i11vrPf444+Xab+UlJQStyj38vK67mkqAABQc9h9DU1ZZGVllbi9uLOzM+/WCgAAJJnkrQ9cXFxKhJfc3NybesfWs2cvqDxvJejgIHl6epT7cQEAMIuKfC0sPvaNmCLQ+Pj4lHi329TUVDVu3NjmYxUWqtwDTUUcFwAAs6jI18LiY9+IKU45hYaGauvWrZZ3BTYMQ3/88YdCQ0PtPBkAAKgKqmygSUlJUXZ2tiSpf//+On/+vKZMmaL9+/drypQpysrK0gMPPGDnKQEAQFVQZQNNz549tWLFCkmSu7u7Zs6cqS1btigyMlLbt2/XJ598ojp16th5SgAAUBXUuHfbTk0t/0XB3t4e5X5cAADMoiJfC4uPfSNVtqEBAAAoKwINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPQINAAAwPbsGmpycHL3yyivq3LmzevbsqdmzZ19z3++//14PPPCAwsLC9Nhjj2nnzp2VOCkAAKjK7Bpopk2bpoSEBH3xxRd69dVX9eGHH2rVqlUl9ktMTNQLL7yg0aNHa8mSJQoICNDo0aOVlZVlh6kBAEBVY7dAk5mZqfnz52v8+PEKDAzUf/3Xf+mpp57S3LlzS+y7YcMGtW7dWuHh4WrevLmef/55paSkaP/+/XaYHAAAVDV2CzR79uxRfn6+wsLCLNs6deqk7du3q7Cw0GrfBg0aaP/+/dqyZYsKCwu1aNEiubu7q3nz5pU9NgAAqIKc7PXEKSkpatiwoZydnS3bvL29lZOTo/T0dHl6elq2DxgwQOvWrdPjjz8uR0dH1apVSzNnzlT9+vVtfl4Hh3IZv8Txyvu4AACYRUW+Fpb1mHYLNFlZWVZhRpLl49zcXKvtaWlpSklJ0cSJExUaGqqvv/5a48aNU1xcnLy8vGx6Xi8vj1sbvJKPCwCAWdjztdBugcbFxaVEcCn+2NXV1Wr79OnT1bZtW/35z3+WJL3++ut64IEHtHDhQo0aNcqm5z1z5oIM4xYGv4qDQ9EPsLyPCwCAWVTka2HxsW/EboHGx8dHaWlpys/Pl5NT0RgpKSlydXVVvXr1rPbduXOnhg0bZvm4Vq1aateunU6ePGnz8xqGKiR4VNRxAQAwC3u+FtptUXBAQICcnJy0bds2y7YtW7YoODhYtWpZj9W4cWMdOHDAatuhQ4d02223VcaoAACgirNboHFzc1N4eLhiYmIUHx+vNWvWaPbs2Ro+fLikorYmOztbkvToo4/qm2++0eLFi3XkyBFNnz5dJ0+eVEREhL3GBwAAVYjdTjlJ0rhx4xQTE6MRI0bI3d1dY8aMUd++fSVJPXv2VGxsrCIjIzVgwABlZGRo5syZSk5OVkBAgL744gubFwQDAIDqycEwatbKj9TU8l8U7O3tUe7HBQDALCrytbD42DfCm1MCAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTI9AAAADTcyrLTsOGDZODg0OZDjhnzpxbGggAAMBWZQo03bp1q5Anz8nJ0aRJk7R69Wq5uroqKipKUVFRpe67d+9excTEaOfOnWrRooXGjx+v7t27V8hcAADAXMoUaJ577rkKefJp06YpISFBX3zxhU6ePKno6Gg1adJE/fv3t9rvwoULioqKUp8+fTR16lQtWbJEzz33nL777jt5eXlVyGwAAMA8yhRoxo0bV+YDxsbGlmm/zMxMzZ8/X7NmzVJgYKACAwOVmJiouXPnlgg0cXFx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" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt_ctx_recall = plot_eval(ctx_recall_df, 'Context Recall')\n", - "plt_ctx_recall.savefig('../../../data/rag_eval/results/plots/context_recall.png')" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-06-19T10:10:58.001951Z", - "start_time": "2024-06-19T10:10:57.808463Z" - } - }, - "id": "b21e26fc3583d54", - "execution_count": 35 - }, - { - "cell_type": "code", - "outputs": [], - "source": [], - "metadata": { - "collapsed": false - }, - "id": "aa6a04bb810ae817" - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}