From b6f9b386ef1b7dc2794f7e975dd3cd0504419d06 Mon Sep 17 00:00:00 2001 From: acano Date: Thu, 19 Mar 2026 16:27:25 +0100 Subject: [PATCH] Add BEIR analysis notebooks for different datasets and models - Created `n00 Beir Analysis.ipynb` for analyzing BEIR dataset with Ollama embeddings. - Added `n00 Beir Analysis_cosqa.ipynb` for evaluating the CosQA dataset using similar methods. - Introduced `n00 first Analysis.ipynb` for initial analysis with Ragas embeddings and semantic similarity evaluation. - Implemented data loading, processing, and evaluation metrics for each notebook. - Included functionality to save results to JSON files for further analysis. --- .../embeddings/Embedding model selection.pdf | Bin 0 -> 105074 bytes .../beir_CodeXGlue_results.json | 54 +++ .../beir_Scifact_results.json | 62 ++++ .../beir_cosqa_results.json | 62 ++++ .../n00 Beir Analysis CodeXGlue.ipynb | 333 +++++++++++++++++ research/embeddings/n00 Beir Analysis.ipynb | 323 +++++++++++++++++ .../embeddings/n00 Beir Analysis_cosqa.ipynb | 335 ++++++++++++++++++ research/embeddings/n00 first Analysis.ipynb | 289 +++++++++++++++ 8 files changed, 1458 insertions(+) create mode 100644 research/embeddings/Embedding model selection.pdf create mode 100644 research/embeddings/embedding_eval_results/beir_CodeXGlue_results.json create mode 100644 research/embeddings/embedding_eval_results/beir_Scifact_results.json create mode 100644 research/embeddings/embedding_eval_results/beir_cosqa_results.json create mode 100644 research/embeddings/n00 Beir Analysis CodeXGlue.ipynb create mode 100644 research/embeddings/n00 Beir Analysis.ipynb create mode 100644 research/embeddings/n00 Beir Analysis_cosqa.ipynb create mode 100644 research/embeddings/n00 first Analysis.ipynb diff --git a/research/embeddings/Embedding model selection.pdf b/research/embeddings/Embedding model selection.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d295567fe19db0b854468ad63948412fd9157034 GIT binary patch literal 105074 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�-E= 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

j2$QFBbT*@5eWDQHh`beT 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

NXGE8$2rcoU{CwP=?P$50!0{ZMpihC>=9X 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 aW~d=i|B9aT?^;7gQw4<}ua!Tl{eJ-_ literal 0 HcmV?d00001 diff --git a/research/embeddings/embedding_eval_results/beir_CodeXGlue_results.json b/research/embeddings/embedding_eval_results/beir_CodeXGlue_results.json new file mode 100644 index 0000000..2763405 --- /dev/null +++ b/research/embeddings/embedding_eval_results/beir_CodeXGlue_results.json @@ -0,0 +1,54 @@ +{ + "qwen3-0.6B-emb:latest": { + "NDCG": { + "NDCG@1": 0.94971, + "NDCG@3": 0.96956, + "NDCG@5": 0.97166, + "NDCG@10": 0.97342 + }, + "MAP": { + "MAP@1": 0.94971, + "MAP@3": 0.96504, + "MAP@5": 0.9662, + "MAP@10": 0.96694 + }, + "Recall": { + "Recall@1": 0.94971, + "Recall@3": 0.98251, + "Recall@5": 0.98761, + "Recall@10": 0.99297 + }, + "Precision": { + "P@1": 0.94971, + "P@3": 0.3275, + "P@5": 0.19752, + "P@10": 0.0993 + } + }, + "qwen2.5:1.5b": { + "NDCG": { + "NDCG@1": 0.00031, + "NDCG@3": 0.00061, + "NDCG@5": 0.00086, + "NDCG@10": 0.00118 + }, + "MAP": { + "MAP@1": 0.00031, + "MAP@3": 0.00051, + "MAP@5": 0.00065, + "MAP@10": 0.00078 + }, + "Recall": { + "Recall@1": 0.00031, + "Recall@3": 0.00088, + "Recall@5": 0.00151, + "Recall@10": 0.0025 + }, + "Precision": { + "P@1": 0.00031, + "P@3": 0.00029, + "P@5": 0.0003, + "P@10": 0.00025 + } + } +} \ No newline at end of file diff --git a/research/embeddings/embedding_eval_results/beir_Scifact_results.json b/research/embeddings/embedding_eval_results/beir_Scifact_results.json new file mode 100644 index 0000000..9518098 --- /dev/null +++ b/research/embeddings/embedding_eval_results/beir_Scifact_results.json @@ -0,0 +1,62 @@ +{ + "qwen3-0.6B-emb:latest": { + "NDCG": { + "NDCG@1": 0.56333, + "NDCG@3": 0.64367, + "NDCG@5": 0.66577, + "NDCG@10": 0.68551, + "NDCG@100": 0.71285 + }, + "MAP": { + "MAP@1": 0.52994, + "MAP@3": 0.6117, + "MAP@5": 0.62815, + "MAP@10": 0.6383, + "MAP@100": 0.64466 + }, + "Recall": { + "Recall@1": 0.52994, + "Recall@3": 0.7035, + "Recall@5": 0.75967, + "Recall@10": 0.81611, + "Recall@100": 0.94 + }, + "Precision": { + "P@1": 0.56333, + "P@3": 0.25889, + "P@5": 0.17067, + "P@10": 0.093, + "P@100": 0.0107 + } + }, + "qwen2.5:1.5b": { + "NDCG": { + "NDCG@1": 0.02333, + "NDCG@3": 0.03498, + "NDCG@5": 0.0404, + "NDCG@10": 0.04619, + "NDCG@100": 0.07768 + }, + "MAP": { + "MAP@1": 0.02083, + "MAP@3": 0.03083, + "MAP@5": 0.03375, + "MAP@10": 0.03632, + "MAP@100": 0.04123 + }, + "Recall": { + "Recall@1": 0.02083, + "Recall@3": 0.04417, + "Recall@5": 0.0575, + "Recall@10": 0.07417, + "Recall@100": 0.23144 + }, + "Precision": { + "P@1": 0.02333, + "P@3": 0.01556, + "P@5": 0.01267, + "P@10": 0.00833, + "P@100": 0.00277 + } + } +} \ No newline at end of file diff --git a/research/embeddings/embedding_eval_results/beir_cosqa_results.json b/research/embeddings/embedding_eval_results/beir_cosqa_results.json new file mode 100644 index 0000000..d44b968 --- /dev/null +++ b/research/embeddings/embedding_eval_results/beir_cosqa_results.json @@ -0,0 +1,62 @@ +{ + "qwen3-0.6B-emb:latest": { + "NDCG": { + "NDCG@1": 0.174, + "NDCG@3": 0.27374, + "NDCG@5": 0.33509, + "NDCG@10": 0.39086, + "NDCG@100": 0.45099 + }, + "MAP": { + "MAP@1": 0.174, + "MAP@3": 0.247, + "MAP@5": 0.2808, + "MAP@10": 0.30466, + "MAP@100": 0.31702 + }, + "Recall": { + "Recall@1": 0.174, + "Recall@3": 0.352, + "Recall@5": 0.502, + "Recall@10": 0.67, + "Recall@100": 0.952 + }, + "Precision": { + "P@1": 0.174, + "P@3": 0.11733, + "P@5": 0.1004, + "P@10": 0.067, + "P@100": 0.00952 + } + }, + "qwen2.5:1.5b": { + "NDCG": { + "NDCG@1": 0.0, + "NDCG@3": 0.0, + "NDCG@5": 0.0, + "NDCG@10": 0.0, + "NDCG@100": 0.0021 + }, + "MAP": { + "MAP@1": 0.0, + "MAP@3": 0.0, + "MAP@5": 0.0, + "MAP@10": 0.0, + "MAP@100": 0.00043 + }, + "Recall": { + "Recall@1": 0.0, + "Recall@3": 0.0, + "Recall@5": 0.0, + "Recall@10": 0.0, + "Recall@100": 0.01 + }, + "Precision": { + "P@1": 0.0, + "P@3": 0.0, + "P@5": 0.0, + "P@10": 0.0, + "P@100": 0.0001 + } + } +} \ No newline at end of file diff --git a/research/embeddings/n00 Beir Analysis CodeXGlue.ipynb b/research/embeddings/n00 Beir Analysis CodeXGlue.ipynb new file mode 100644 index 0000000..a4bc78f --- /dev/null +++ b/research/embeddings/n00 Beir Analysis CodeXGlue.ipynb @@ -0,0 +1,333 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "66cbbaf8", + "metadata": {}, + "source": [ + "# Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c01c19dc", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Dict, List, Union\n", + "import numpy as np\n", + "from langchain_ollama import OllamaEmbeddings\n", + "from beir.datasets.data_loader import GenericDataLoader\n", + "from beir.retrieval.search.dense import DenseRetrievalExactSearch\n", + "from beir.retrieval.evaluation import EvaluateRetrieval\n", + "from beir import util\n", + "import json\n", + "from datasets import load_dataset" + ] + }, + { + "cell_type": "markdown", + "id": "ac011c1c", + "metadata": {}, + "source": [ + "# Utils" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b83e7900", + "metadata": {}, + "outputs": [], + "source": [ + "class BEIROllamaEmbeddings:\n", + " \"\"\"\n", + " Adapter that makes LangChain's OllamaEmbeddings compatible with BEIR.\n", + " \"\"\"\n", + "\n", + " def __init__(\n", + " self,\n", + " base_url: str,\n", + " model: str,\n", + " batch_size: int = 64,\n", + " ) -> None:\n", + " self.batch_size = batch_size\n", + " self.embeddings = OllamaEmbeddings(\n", + " base_url=base_url,\n", + " model=model,\n", + " )\n", + "\n", + " def _batch_embed(self, texts: List[str]) -> np.ndarray:\n", + " vectors = []\n", + "\n", + " for i in range(0, len(texts), self.batch_size):\n", + " batch = texts[i : i + self.batch_size]\n", + " batch_vectors = self.embeddings.embed_documents(batch)\n", + " vectors.extend(batch_vectors)\n", + "\n", + " return np.asarray(vectors, dtype=np.float32)\n", + "\n", + " def encode_queries(self, queries: List[str], **kwargs) -> np.ndarray:\n", + " \"\"\"\n", + " BEIR query encoder\n", + " \"\"\"\n", + " return self._batch_embed(queries)\n", + "\n", + " def encode_corpus(\n", + " self,\n", + " corpus: Union[List[Dict[str, str]], Dict[str, Dict[str, str]]],\n", + " **kwargs,\n", + " ) -> np.ndarray:\n", + " \"\"\"\n", + " BEIR corpus encoder\n", + " \"\"\"\n", + " if isinstance(corpus, dict):\n", + " corpus = list(corpus.values())\n", + "\n", + " texts = []\n", + " for doc in corpus:\n", + " title = (doc.get(\"title\") or \"\").strip()\n", + " text = (doc.get(\"text\") or \"\").strip()\n", + "\n", + " if title:\n", + " texts.append(f\"{title}\\n{text}\")\n", + " else:\n", + " texts.append(text)\n", + "\n", + " return self._batch_embed(texts)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "af3eb66d", + "metadata": {}, + "outputs": [], + "source": [ + "def convert_hf_to_beir(hf_dataset):\n", + " corpus, queries, qrels = {}, {}, {}\n", + " \n", + " for i, data in enumerate(hf_dataset):\n", + " docid = f\"doc_{i}\"\n", + " queryid = f\"q_{i}\"\n", + " \n", + " # El código es el documento (lo que el agente debe recuperar)\n", + " corpus[docid] = {\"title\": data.get(\"func_name\", \"\"), \"text\": data['code']}\n", + " \n", + " # El docstring es la consulta (lo que el usuario pide)\n", + " queries[queryid] = data['docstring']\n", + " \n", + " # Relación 1 a 1: la query i busca el código i\n", + " qrels[queryid] = {docid: 1}\n", + " \n", + " return corpus, queries, qrels" + ] + }, + { + "cell_type": "markdown", + "id": "c9528fb6", + "metadata": {}, + "source": [ + "# Data" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "230aae25", + "metadata": {}, + "outputs": [], + "source": [ + "raw_dataset = load_dataset(\"google/code_x_glue_tc_nl_code_search_adv\", split=\"test\")\n", + "corpus, queries, qrels = convert_hf_to_beir(raw_dataset)" + ] + }, + { + "cell_type": "markdown", + "id": "13050d31", + "metadata": {}, + "source": [ + "# Test qwen3-0.6B-emb:latest" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "514540af", + "metadata": {}, + "outputs": [], + "source": [ + "model = BEIROllamaEmbeddings(\n", + " base_url=\"http://localhost:11434\",\n", + " model=\"qwen3-0.6B-emb:latest\",\n", + " batch_size=64,\n", + ")\n", + "\n", + "# Inicializar buscador y evaluador\n", + "retriever = DenseRetrievalExactSearch(model, batch_size=64)\n", + "evaluator = EvaluateRetrieval(retriever, score_function=\"cos_sim\")\n", + "\n", + "# Ejecutar recuperación\n", + "results = evaluator.retrieve(corpus, queries)\n", + "\n", + "# Evaluar métricas (NDCG, MAP, Recall, Precision)\n", + "ndcg, _map, recall, precision = evaluator.evaluate(\n", + " qrels, results, [1, 3, 5, 10]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5c0f9845", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Resultados para CodeXGLUE:\n", + "NDCG: {'NDCG@1': 0.94971, 'NDCG@3': 0.96956, 'NDCG@5': 0.97166, 'NDCG@10': 0.97342}\n", + "MAP: {'MAP@1': 0.94971, 'MAP@3': 0.96504, 'MAP@5': 0.9662, 'MAP@10': 0.96694}\n", + "Recall: {'Recall@1': 0.94971, 'Recall@3': 0.98251, 'Recall@5': 0.98761, 'Recall@10': 0.99297}\n", + "Precision: {'P@1': 0.94971, 'P@3': 0.3275, 'P@5': 0.19752, 'P@10': 0.0993}\n" + ] + } + ], + "source": [ + "print(f\"Resultados para CodeXGLUE:\")\n", + "print(\"NDCG:\", ndcg)\n", + "print(\"MAP:\", _map)\n", + "print(\"Recall:\", recall)\n", + "print(\"Precision:\", precision)" + ] + }, + { + "cell_type": "markdown", + "id": "c4e643ca", + "metadata": {}, + "source": [ + "# Test qwen2.5:1.5b" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5ced1c25", + "metadata": {}, + "outputs": [], + "source": [ + "model_q2 = BEIROllamaEmbeddings(\n", + " base_url=\"http://localhost:11434\",\n", + " model=\"qwen2.5:1.5b\",\n", + " batch_size=64,\n", + ")\n", + "\n", + "# Inicializar buscador y evaluador\n", + "retriever_q2 = DenseRetrievalExactSearch(model_q2, batch_size=64)\n", + "evaluator_q2 = EvaluateRetrieval(retriever_q2, score_function=\"cos_sim\")\n", + "\n", + "# Ejecutar recuperación\n", + "results_q2 = evaluator_q2.retrieve(corpus, queries)\n", + "\n", + "# Evaluar métricas (NDCG, MAP, Recall, Precision)\n", + "ndcg_qwen_2, _map_qwen_2, recall_qwen_2, precision_qwen_2 = evaluator_q2.evaluate(\n", + " qrels, results_q2, [1, 3, 5, 10]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "6a95189e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Resultados para CodeXGLUE:\n", + "NDCG: {'NDCG@1': 0.00031, 'NDCG@3': 0.00061, 'NDCG@5': 0.00086, 'NDCG@10': 0.00118}\n", + "MAP: {'MAP@1': 0.00031, 'MAP@3': 0.00051, 'MAP@5': 0.00065, 'MAP@10': 0.00078}\n", + "Recall: {'Recall@1': 0.00031, 'Recall@3': 0.00088, 'Recall@5': 0.00151, 'Recall@10': 0.0025}\n", + "Precision: {'P@1': 0.00031, 'P@3': 0.00029, 'P@5': 0.0003, 'P@10': 0.00025}\n" + ] + } + ], + "source": [ + "print(f\"Resultados para CodeXGLUE:\")\n", + "print(\"NDCG:\", ndcg_qwen_2)\n", + "print(\"MAP:\", _map_qwen_2)\n", + "print(\"Recall:\", recall_qwen_2)\n", + "print(\"Precision:\", precision_qwen_2)" + ] + }, + { + "cell_type": "markdown", + "id": "3dad9811", + "metadata": {}, + "source": [ + "# Save data" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "f875dd8d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Resultados guardados en /home/pseco/VsCodeProjects/assistance-engine/data/interim/beir_CodeXGlue_results.json\n" + ] + } + ], + "source": [ + "results_data = {\n", + " \"qwen3-0.6B-emb:latest\": {\n", + " \"NDCG\": ndcg,\n", + " \"MAP\": _map,\n", + " \"Recall\": recall,\n", + " \"Precision\": precision,\n", + " },\n", + " \"qwen2.5:1.5b\": {\n", + " \"NDCG\": ndcg_qwen_2,\n", + " \"MAP\": _map_qwen_2,\n", + " \"Recall\": recall_qwen_2,\n", + " \"Precision\": precision_qwen_2,\n", + " }\n", + "}\n", + "\n", + "output_file = \"/home/pseco/VsCodeProjects/assistance-engine/data/interim/beir_CodeXGlue_results.json\"\n", + "with open(output_file, \"w\") as f:\n", + " json.dump(results_data, f, indent=2)\n", + "\n", + "print(f\"Resultados guardados en {output_file}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "assistance-engine", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/research/embeddings/n00 Beir Analysis.ipynb b/research/embeddings/n00 Beir Analysis.ipynb new file mode 100644 index 0000000..fcd0587 --- /dev/null +++ b/research/embeddings/n00 Beir Analysis.ipynb @@ -0,0 +1,323 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "66cbbaf8", + "metadata": {}, + "source": [ + "# Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "c01c19dc", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Dict, List, Union\n", + "import numpy as np\n", + "from langchain_ollama import OllamaEmbeddings\n", + "from beir.datasets.data_loader import GenericDataLoader\n", + "from beir.retrieval.search.dense import DenseRetrievalExactSearch\n", + "from beir.retrieval.evaluation import EvaluateRetrieval\n", + "from beir import util\n", + "import json" + ] + }, + { + "cell_type": "markdown", + "id": "ac011c1c", + "metadata": {}, + "source": [ + "# Utils" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "b83e7900", + "metadata": {}, + "outputs": [], + "source": [ + "class BEIROllamaEmbeddings:\n", + " \"\"\"\n", + " Adapter that makes LangChain's OllamaEmbeddings compatible with BEIR.\n", + " \"\"\"\n", + "\n", + " def __init__(\n", + " self,\n", + " base_url: str,\n", + " model: str,\n", + " batch_size: int = 64,\n", + " ) -> None:\n", + " self.batch_size = batch_size\n", + " self.embeddings = OllamaEmbeddings(\n", + " base_url=base_url,\n", + " model=model,\n", + " )\n", + "\n", + " def _batch_embed(self, texts: List[str]) -> np.ndarray:\n", + " vectors = []\n", + "\n", + " for i in range(0, len(texts), self.batch_size):\n", + " batch = texts[i : i + self.batch_size]\n", + " batch_vectors = self.embeddings.embed_documents(batch)\n", + " vectors.extend(batch_vectors)\n", + "\n", + " return np.asarray(vectors, dtype=np.float32)\n", + "\n", + " def encode_queries(self, queries: List[str], **kwargs) -> np.ndarray:\n", + " \"\"\"\n", + " BEIR query encoder\n", + " \"\"\"\n", + " return self._batch_embed(queries)\n", + "\n", + " def encode_corpus(\n", + " self,\n", + " corpus: Union[List[Dict[str, str]], Dict[str, Dict[str, str]]],\n", + " **kwargs,\n", + " ) -> np.ndarray:\n", + " \"\"\"\n", + " BEIR corpus encoder\n", + " \"\"\"\n", + " if isinstance(corpus, dict):\n", + " corpus = list(corpus.values())\n", + "\n", + " texts = []\n", + " for doc in corpus:\n", + " title = (doc.get(\"title\") or \"\").strip()\n", + " text = (doc.get(\"text\") or \"\").strip()\n", + "\n", + " if title:\n", + " texts.append(f\"{title}\\n{text}\")\n", + " else:\n", + " texts.append(text)\n", + "\n", + " return self._batch_embed(texts)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af3eb66d", + "metadata": {}, + "outputs": [], + "source": [ + "def convert_codexglue_to_beir(input_file):\n", + " corpus, queries, qrels = {}, {}, {}\n", + " with open(input_file, 'r') as f:\n", + " for i, line in enumerate(f):\n", + " data = json.loads(line)\n", + " docid = f\"doc_{i}\"\n", + " queryid = f\"q_{i}\"\n", + " \n", + " # El código es nuestro documento (Corpus)\n", + " corpus[docid] = {\"title\": \"\", \"text\": data['code']}\n", + " # El docstring es nuestra consulta (Query)\n", + " queries[queryid] = data['docstring']\n", + " # En CodeXGLUE, la consulta i corresponde al código i\n", + " qrels[queryid] = {docid: 1}\n", + " \n", + " return corpus, queries, qrels\n", + "\n", + "# Carga tus datos (ejemplo con el set de test de AdvTest)\n", + "corpus, queries, qrels = convert_codexglue_to_beir(\"test.jsonl\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "c9528fb6", + "metadata": {}, + "source": [ + "# Data" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "230aae25", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1915c67ec20f4806b30b48eff9a132e2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/5183 [00:00 None:\n", + " self.batch_size = batch_size\n", + " self.embeddings = OllamaEmbeddings(\n", + " base_url=base_url,\n", + " model=model,\n", + " )\n", + "\n", + " def _batch_embed(self, texts: List[str]) -> np.ndarray:\n", + " vectors = []\n", + "\n", + " for i in range(0, len(texts), self.batch_size):\n", + " batch = texts[i : i + self.batch_size]\n", + " batch_vectors = self.embeddings.embed_documents(batch)\n", + " vectors.extend(batch_vectors)\n", + "\n", + " return np.asarray(vectors, dtype=np.float32)\n", + "\n", + " def encode_queries(self, queries: List[str], **kwargs) -> np.ndarray:\n", + " \"\"\"\n", + " BEIR query encoder\n", + " \"\"\"\n", + " return self._batch_embed(queries)\n", + "\n", + " def encode_corpus(\n", + " self,\n", + " corpus: Union[List[Dict[str, str]], Dict[str, Dict[str, str]]],\n", + " **kwargs,\n", + " ) -> np.ndarray:\n", + " \"\"\"\n", + " BEIR corpus encoder\n", + " \"\"\"\n", + " if isinstance(corpus, dict):\n", + " corpus = list(corpus.values())\n", + "\n", + " texts = []\n", + " for doc in corpus:\n", + " title = (doc.get(\"title\") or \"\").strip()\n", + " text = (doc.get(\"text\") or \"\").strip()\n", + "\n", + " if title:\n", + " texts.append(f\"{title}\\n{text}\")\n", + " else:\n", + " texts.append(text)\n", + "\n", + " return self._batch_embed(texts)" + ] + }, + { + "cell_type": "markdown", + "id": "c9528fb6", + "metadata": {}, + "source": [ + "# Data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "230aae25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Descargando datos de Hugging Face...\n", + "Cargando con BEIR GenericDataLoader...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0e67479e959248f598db3415efbb13ae", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/20604 [00:00>>>>>> 4b5352d93cf89b7562895b550fb5bd62160586c5 + } + ], + "metadata": { + "kernelspec": { + "display_name": "assistance-engine", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/research/embeddings/n00 first Analysis.ipynb b/research/embeddings/n00 first Analysis.ipynb new file mode 100644 index 0000000..fa0f304 --- /dev/null +++ b/research/embeddings/n00 first Analysis.ipynb @@ -0,0 +1,289 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "096e6224", + "metadata": {}, + "source": [ + "# Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "4b0853e9", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_2931729/1845255288.py:4: DeprecationWarning: Importing SemanticSimilarity from 'ragas.metrics' is deprecated and will be removed in v1.0. Please use 'ragas.metrics.collections' instead. Example: from ragas.metrics.collections import SemanticSimilarity\n", + " from ragas.metrics import SemanticSimilarity\n" + ] + } + ], + "source": [ + "# ...existing code...\n", + "from datasets import load_dataset\n", + "from ragas import EvaluationDataset, evaluate\n", + "from ragas.metrics import SemanticSimilarity\n", + "from langchain_community.embeddings import OllamaEmbeddings\n", + "import asyncio\n", + "from typing import Sequence\n", + "from ragas.embeddings.base import BaseRagasEmbedding\n", + "import os\n", + "from transformers import AutoConfig\n", + "import nltk\n", + "# ...existing code..." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6bfe1ca0", + "metadata": {}, + "outputs": [], + "source": [ + "nltk.download(\"punkt\", quiet=True)\n", + "\n", + "ES_URL = os.getenv(\"ELASTICSEARCH_LOCAL_URL\")\n", + "ES_INDEX_NAME = os.getenv(\"ELASTICSEARCH_INDEX\")\n", + "HF_EMBEDDING_MODEL_NAME = os.getenv(\"HF_EMBEDDING_MODEL_NAME\")\n", + "BASE_URL = os.getenv(\"LLM_BASE_LOCAL_URL\")\n", + "MODEL_NAME = os.getenv(\"OLLAMA_MODEL_NAME\")\n", + "\n", + "config = AutoConfig.from_pretrained(HF_EMBEDDING_MODEL_NAME)\n", + "embedding_dim = config.hidden_size" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ea41ce0f", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_2931729/256987240.py:1: LangChainDeprecationWarning: The class `OllamaEmbeddings` was deprecated in LangChain 0.3.1 and will be removed in 1.0.0. An updated version of the class exists in the `langchain-ollama package and should be used instead. To use it run `pip install -U `langchain-ollama` and import as `from `langchain_ollama import OllamaEmbeddings``.\n", + " embeddings = OllamaEmbeddings(base_url=BASE_URL, model=MODEL_NAME)\n" + ] + } + ], + "source": [ + "embeddings = OllamaEmbeddings(base_url=BASE_URL, model=MODEL_NAME)" + ] + }, + { + "cell_type": "markdown", + "id": "8eee9390", + "metadata": {}, + "source": [ + "# Similitud Aleatoria" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7b150e5", + "metadata": {}, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "from ragas import EvaluationDataset\n", + "\n", + "\n", + "def _normalize_answer(answer_value: object) -> str:\n", + " \"\"\"\n", + " Normalize answer values to a single string.\n", + " \"\"\"\n", + " if isinstance(answer_value, dict):\n", + " text_value = answer_value.get(\"text\")\n", + " if isinstance(text_value, list):\n", + " return str(text_value[0]) if text_value else \"\"\n", + " if text_value is not None:\n", + " return str(text_value)\n", + "\n", + " if isinstance(answer_value, list):\n", + " return str(answer_value[0]) if answer_value else \"\"\n", + "\n", + " return str(answer_value)\n", + "\n", + "\n", + "def _first_existing_key(candidates: list[str], keys: set[str]) -> str | None:\n", + " \"\"\"\n", + " Return the first key present in keys from candidates.\n", + " \"\"\"\n", + " for candidate in candidates:\n", + " if candidate in keys:\n", + " return candidate\n", + " return None\n", + "\n", + "\n", + "ds = load_dataset(\"sentence-transformers/natural-questions\")\n", + "train_ds = ds[\"train\"]\n", + "\n", + "max_questions = min(100, len(train_ds))\n", + "train_ds = train_ds.select(range(max_questions))\n", + "\n", + "available_keys = set(train_ds.column_names)\n", + "reference_key = _first_existing_key(\n", + " [\"question\", \"query\", \"text\", \"input\"], available_keys\n", + ")\n", + "response_key = _first_existing_key(\n", + " [\"answer\", \"answers\", \"response\", \"output\"], available_keys\n", + ")\n", + "\n", + "if reference_key is None or response_key is None:\n", + " raise KeyError(\n", + " f\"Expected question/answer-like columns not found. \"\n", + " f\"Available columns: {train_ds.column_names}\"\n", + " )\n", + "\n", + "rows = []\n", + "for row in train_ds:\n", + " rows.append(\n", + " {\n", + " \"reference\": str(row[reference_key]),\n", + " \"response\": _normalize_answer(row[response_key]),\n", + " }\n", + " )\n", + "\n", + "eval_ds = EvaluationDataset.from_list(rows)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "753aab30", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DatasetDict({\n", + " train: Dataset({\n", + " features: ['query', 'answer'],\n", + " num_rows: 100231\n", + " })\n", + "})\n", + "['query', 'answer']\n", + "{'query': 'when did richmond last play in a preliminary final', 'answer': \"Richmond Football Club Richmond began 2017 with 5 straight wins, a feat it had not achieved since 1995. A series of close losses hampered the Tigers throughout the middle of the season, including a 5-point loss to the Western Bulldogs, 2-point loss to Fremantle, and a 3-point loss to the Giants. Richmond ended the season strongly with convincing victories over Fremantle and St Kilda in the final two rounds, elevating the club to 3rd on the ladder. Richmond's first final of the season against the Cats at the MCG attracted a record qualifying final crowd of 95,028; the Tigers won by 51 points. Having advanced to the first preliminary finals for the first time since 2001, Richmond defeated Greater Western Sydney by 36 points in front of a crowd of 94,258 to progress to the Grand Final against Adelaide, their first Grand Final appearance since 1982. The attendance was 100,021, the largest crowd to a grand final since 1986. The Crows led at quarter time and led by as many as 13, but the Tigers took over the game as it progressed and scored seven straight goals at one point. They eventually would win by 48 points – 16.12 (108) to Adelaide's 8.12 (60) – to end their 37-year flag drought.[22] Dustin Martin also became the first player to win a Premiership medal, the Brownlow Medal and the Norm Smith Medal in the same season, while Damien Hardwick was named AFL Coaches Association Coach of the Year. Richmond's jump from 13th to premiers also marked the biggest jump from one AFL season to the next.\"}\n" + ] + } + ], + "source": [ + "print(ds)\n", + "print(ds[\"train\"].column_names)\n", + "print(ds[\"train\"][0])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6c3d4235", + "metadata": {}, + "outputs": [], + "source": [ + "# ...existing code...\n", + "class OllamaRagasEmbeddingAdapter(BaseRagasEmbedding):\n", + " \"\"\"Adaptador de LangChain Ollama a la API moderna de embeddings en Ragas.\"\"\"\n", + "\n", + " def __init__(self, base_url: str, model_name: str) -> None:\n", + " self._client = OllamaEmbeddings(base_url=base_url, model=model_name)\n", + "\n", + " def embed_text(self, text: str) -> list[float]:\n", + " return self._client.embed_query(text)\n", + "\n", + " async def aembed_text(self, text: str) -> list[float]:\n", + " return await asyncio.to_thread(self.embed_text, text)\n", + "\n", + " def embed_query(self, text: str) -> list[float]:\n", + " return self.embed_text(text)\n", + "\n", + " def embed_documents(self, texts: Sequence[str]) -> list[list[float]]:\n", + " return self._client.embed_documents(list(texts))\n", + "\n", + " async def aembed_query(self, text: str) -> list[float]:\n", + " return await self.aembed_text(text)\n", + "\n", + " async def aembed_documents(\n", + " self, texts: Sequence[str]\n", + " ) -> list[list[float]]:\n", + " return await asyncio.to_thread(self.embed_documents, texts)\n", + "\n", + "\n", + "if not BASE_URL or not MODEL_NAME:\n", + " raise ValueError(\n", + " \"Faltan variables de entorno: LLM_BASE_LOCAL_URL u OLLAMA_MODEL_NAME.\"\n", + " )\n", + "\n", + "embeddings = OllamaRagasEmbeddingAdapter(\n", + " base_url=BASE_URL,\n", + " model_name=MODEL_NAME,\n", + ")\n", + "\n", + "semantic_sim = SemanticSimilarity()\n", + "# ...existing code..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "54aacf01", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6a4b6e91c71d4849922f36d45f3e9f7f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Evaluating: 0%| | 0/100231 [00:00