diff --git a/argilla_labeller_with_setfit.ipynb b/argilla_labeller_with_setfit.ipynb
new file mode 100644
index 0000000..ff53dd5
--- /dev/null
+++ b/argilla_labeller_with_setfit.ipynb
@@ -0,0 +1,1105 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Train Zero Shot Text Classification with SetFit on Argilla Labeler"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "- **Goal**: Show a standard workflow for a text classification task, including zero-shot suggestions and model fine-tuning.\n",
+ "- **Dataset**: [IMDB](https://huggingface.co/datasets/stanfordnlp/imdb), a dataset of movie reviews that need to be classified as positive or negative.\n",
+ "- **Libraries**: [datasets](https://github.com/huggingface/datasets), [transformers](https://github.com/huggingface/transformers), [setfit](https://github.com/huggingface/setfit)\n",
+ "- **Components**: [TextField](https://docs.argilla.io/latest/reference/argilla/settings/fields/#src.argilla.settings._field.TextField), [LabelQuestion](https://docs.argilla.io/latest/reference/argilla/settings/questions/#src.argilla.settings._question.LabelQuestion), [Suggestion](https://docs.argilla.io/latest/reference/argilla/records/suggestions/), [Query](https://docs.argilla.io/dev/reference/argilla/search/#rgquery_1), [Filter](https://docs.argilla.io/dev/reference/argilla/search/#rgfilter)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Getting started"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Deploy the Argilla server"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "If you already have deployed Argilla, you can skip this step. Otherwise, you can quickly deploy Argilla following [this guide](../getting_started/quickstart.md)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Set up the environment"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To complete this tutorial, you need to install the Argilla SDK and a few third-party libraries via `pip`."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Argilla Labeler "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Collecting ipywidgets\n",
+ " Using cached ipywidgets-8.1.5-py3-none-any.whl.metadata (2.3 kB)\n",
+ "Requirement already satisfied: comm>=0.1.3 in ./.venv/lib/python3.11/site-packages (from ipywidgets) (0.2.2)\n",
+ "Requirement already satisfied: ipython>=6.1.0 in ./.venv/lib/python3.11/site-packages (from ipywidgets) (8.28.0)\n",
+ "Requirement already satisfied: traitlets>=4.3.1 in ./.venv/lib/python3.11/site-packages (from ipywidgets) (5.14.3)\n",
+ "Collecting widgetsnbextension~=4.0.12 (from ipywidgets)\n",
+ " Using cached widgetsnbextension-4.0.13-py3-none-any.whl.metadata (1.6 kB)\n",
+ "Collecting jupyterlab-widgets~=3.0.12 (from ipywidgets)\n",
+ " Using cached jupyterlab_widgets-3.0.13-py3-none-any.whl.metadata (4.1 kB)\n",
+ "Requirement already satisfied: decorator in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (5.1.1)\n",
+ "Requirement already satisfied: jedi>=0.16 in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (0.19.1)\n",
+ "Requirement already satisfied: matplotlib-inline in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (0.1.7)\n",
+ "Requirement already satisfied: prompt-toolkit<3.1.0,>=3.0.41 in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (3.0.48)\n",
+ "Requirement already satisfied: pygments>=2.4.0 in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (2.18.0)\n",
+ "Requirement already satisfied: stack-data in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (0.6.3)\n",
+ "Requirement already satisfied: typing-extensions>=4.6 in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (4.12.2)\n",
+ "Requirement already satisfied: pexpect>4.3 in ./.venv/lib/python3.11/site-packages (from ipython>=6.1.0->ipywidgets) (4.9.0)\n",
+ "Requirement already satisfied: parso<0.9.0,>=0.8.3 in ./.venv/lib/python3.11/site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets) (0.8.4)\n",
+ "Requirement already satisfied: ptyprocess>=0.5 in ./.venv/lib/python3.11/site-packages (from pexpect>4.3->ipython>=6.1.0->ipywidgets) (0.7.0)\n",
+ "Requirement already satisfied: wcwidth in ./.venv/lib/python3.11/site-packages (from prompt-toolkit<3.1.0,>=3.0.41->ipython>=6.1.0->ipywidgets) (0.2.13)\n",
+ "Requirement already satisfied: executing>=1.2.0 in ./.venv/lib/python3.11/site-packages (from stack-data->ipython>=6.1.0->ipywidgets) (2.1.0)\n",
+ "Requirement already satisfied: asttokens>=2.1.0 in ./.venv/lib/python3.11/site-packages (from stack-data->ipython>=6.1.0->ipywidgets) (2.4.1)\n",
+ "Requirement already satisfied: pure-eval in ./.venv/lib/python3.11/site-packages (from stack-data->ipython>=6.1.0->ipywidgets) (0.2.3)\n",
+ "Requirement already satisfied: six>=1.12.0 in ./.venv/lib/python3.11/site-packages (from asttokens>=2.1.0->stack-data->ipython>=6.1.0->ipywidgets) (1.16.0)\n",
+ "Using cached ipywidgets-8.1.5-py3-none-any.whl (139 kB)\n",
+ "Using cached jupyterlab_widgets-3.0.13-py3-none-any.whl (214 kB)\n",
+ "Using cached widgetsnbextension-4.0.13-py3-none-any.whl (2.3 MB)\n",
+ "Installing collected packages: widgetsnbextension, jupyterlab-widgets, ipywidgets\n",
+ "Successfully installed ipywidgets-8.1.5 jupyterlab-widgets-3.0.13 widgetsnbextension-4.0.13\n",
+ "\n",
+ "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.1.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.2\u001b[0m\n",
+ "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip install ipywidgets\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\u001b[33mDEPRECATION: git+https://github.com/argilla-io/distilabel.git@fix/simplified-prompt-template-argilla-labeller#egg=distilabel[llama_cpp] contains an egg fragment with a non-PEP 508 name pip 25.0 will enforce this behaviour change. A possible replacement is to use the req @ url syntax, and remove the egg fragment. Discussion can be found at https://github.com/pypa/pip/issues/11617\u001b[0m\u001b[33m\n",
+ "\u001b[0mCollecting distilabel (from distilabel[llama_cpp])\n",
+ " Cloning https://github.com/argilla-io/distilabel.git (to revision fix/simplified-prompt-template-argilla-labeller) to /private/var/folders/8z/jnnncfnj7_lfxym0262z4p180000gn/T/pip-install-z047oxvm/distilabel_ef385863b5484cea8f5bd96bddb41a8e\n",
+ " Running command git clone --filter=blob:none --quiet https://github.com/argilla-io/distilabel.git /private/var/folders/8z/jnnncfnj7_lfxym0262z4p180000gn/T/pip-install-z047oxvm/distilabel_ef385863b5484cea8f5bd96bddb41a8e\n",
+ " Running command git checkout -b fix/simplified-prompt-template-argilla-labeller --track origin/fix/simplified-prompt-template-argilla-labeller\n",
+ " Switched to a new branch 'fix/simplified-prompt-template-argilla-labeller'\n",
+ " branch 'fix/simplified-prompt-template-argilla-labeller' set up to track 'origin/fix/simplified-prompt-template-argilla-labeller'.\n",
+ " Resolved https://github.com/argilla-io/distilabel.git to commit f5e05029c96962c803937dec7447b81e867ec96e\n",
+ " Installing build dependencies ... \u001b[?25ldone\n",
+ "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n",
+ "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n",
+ "\u001b[?25hRequirement already satisfied: datasets>=2.16.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (3.0.1)\n",
+ "Requirement already satisfied: httpx>=0.25.2 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (0.27.2)\n",
+ "Requirement already satisfied: jinja2>=3.1.2 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (3.1.4)\n",
+ "Requirement already satisfied: multiprocess>=0.70 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (0.70.16)\n",
+ "Requirement already satisfied: nest-asyncio>=1.6.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (1.6.0)\n",
+ "Requirement already satisfied: networkx>=3.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (3.3)\n",
+ "Requirement already satisfied: orjson>=3.10.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (3.10.7)\n",
+ "Requirement already satisfied: portalocker>=2.8.2 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (2.10.1)\n",
+ "Requirement already satisfied: pydantic>=2.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (2.9.2)\n",
+ "Requirement already satisfied: rich>=13.5.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (13.9.2)\n",
+ "Requirement already satisfied: scipy>=1.10.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (1.14.1)\n",
+ "Requirement already satisfied: tblib>=3.0.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (3.0.0)\n",
+ "Requirement already satisfied: typer>=0.9.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (0.12.5)\n",
+ "Requirement already satisfied: universal-pathlib>=0.2.2 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (0.2.5)\n",
+ "Requirement already satisfied: llama-cpp-python>=0.2.0 in ./.venv/lib/python3.11/site-packages (from distilabel->distilabel[llama_cpp]) (0.2.85)\n",
+ "Requirement already satisfied: filelock in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (3.16.1)\n",
+ "Requirement already satisfied: numpy>=1.17 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (1.26.4)\n",
+ "Requirement already satisfied: pyarrow>=15.0.0 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (17.0.0)\n",
+ "Requirement already satisfied: dill<0.3.9,>=0.3.0 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (0.3.8)\n",
+ "Requirement already satisfied: pandas in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2.2.3)\n",
+ "Requirement already satisfied: requests>=2.32.2 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2.32.3)\n",
+ "Requirement already satisfied: tqdm>=4.66.3 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (4.66.5)\n",
+ "Requirement already satisfied: xxhash in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (3.5.0)\n",
+ "Requirement already satisfied: fsspec<=2024.6.1,>=2023.1.0 in ./.venv/lib/python3.11/site-packages (from fsspec[http]<=2024.6.1,>=2023.1.0->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2024.6.1)\n",
+ "Requirement already satisfied: aiohttp in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (3.10.9)\n",
+ "Requirement already satisfied: huggingface-hub>=0.22.0 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (0.25.2)\n",
+ "Requirement already satisfied: packaging in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (24.1)\n",
+ "Requirement already satisfied: pyyaml>=5.1 in ./.venv/lib/python3.11/site-packages (from datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (6.0.2)\n",
+ "Requirement already satisfied: anyio in ./.venv/lib/python3.11/site-packages (from httpx>=0.25.2->distilabel->distilabel[llama_cpp]) (4.6.0)\n",
+ "Requirement already satisfied: certifi in ./.venv/lib/python3.11/site-packages (from httpx>=0.25.2->distilabel->distilabel[llama_cpp]) (2024.8.30)\n",
+ "Requirement already satisfied: httpcore==1.* in ./.venv/lib/python3.11/site-packages (from httpx>=0.25.2->distilabel->distilabel[llama_cpp]) (1.0.6)\n",
+ "Requirement already satisfied: idna in ./.venv/lib/python3.11/site-packages (from httpx>=0.25.2->distilabel->distilabel[llama_cpp]) (3.10)\n",
+ "Requirement already satisfied: sniffio in ./.venv/lib/python3.11/site-packages (from httpx>=0.25.2->distilabel->distilabel[llama_cpp]) (1.3.1)\n",
+ "Requirement already satisfied: h11<0.15,>=0.13 in ./.venv/lib/python3.11/site-packages (from httpcore==1.*->httpx>=0.25.2->distilabel->distilabel[llama_cpp]) (0.14.0)\n",
+ "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.11/site-packages (from jinja2>=3.1.2->distilabel->distilabel[llama_cpp]) (3.0.1)\n",
+ "Requirement already satisfied: typing-extensions>=4.5.0 in ./.venv/lib/python3.11/site-packages (from llama-cpp-python>=0.2.0->distilabel->distilabel[llama_cpp]) (4.12.2)\n",
+ "Requirement already satisfied: diskcache>=5.6.1 in ./.venv/lib/python3.11/site-packages (from llama-cpp-python>=0.2.0->distilabel->distilabel[llama_cpp]) (5.6.3)\n",
+ "Requirement already satisfied: annotated-types>=0.6.0 in ./.venv/lib/python3.11/site-packages (from pydantic>=2.0->distilabel->distilabel[llama_cpp]) (0.7.0)\n",
+ "Requirement already satisfied: pydantic-core==2.23.4 in ./.venv/lib/python3.11/site-packages (from pydantic>=2.0->distilabel->distilabel[llama_cpp]) (2.23.4)\n",
+ "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.11/site-packages (from rich>=13.5.0->distilabel->distilabel[llama_cpp]) (3.0.0)\n",
+ "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.11/site-packages (from rich>=13.5.0->distilabel->distilabel[llama_cpp]) (2.18.0)\n",
+ "Requirement already satisfied: click>=8.0.0 in ./.venv/lib/python3.11/site-packages (from typer>=0.9.0->distilabel->distilabel[llama_cpp]) (8.1.7)\n",
+ "Requirement already satisfied: shellingham>=1.3.0 in ./.venv/lib/python3.11/site-packages (from typer>=0.9.0->distilabel->distilabel[llama_cpp]) (1.5.4)\n",
+ "Requirement already satisfied: aiohappyeyeballs>=2.3.0 in ./.venv/lib/python3.11/site-packages (from aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2.4.3)\n",
+ "Requirement already satisfied: aiosignal>=1.1.2 in ./.venv/lib/python3.11/site-packages (from aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (1.3.1)\n",
+ "Requirement already satisfied: attrs>=17.3.0 in ./.venv/lib/python3.11/site-packages (from aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (24.2.0)\n",
+ "Requirement already satisfied: frozenlist>=1.1.1 in ./.venv/lib/python3.11/site-packages (from aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (1.4.1)\n",
+ "Requirement already satisfied: multidict<7.0,>=4.5 in ./.venv/lib/python3.11/site-packages (from aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (6.1.0)\n",
+ "Requirement already satisfied: yarl<2.0,>=1.12.0 in ./.venv/lib/python3.11/site-packages (from aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (1.14.0)\n",
+ "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.11/site-packages (from markdown-it-py>=2.2.0->rich>=13.5.0->distilabel->distilabel[llama_cpp]) (0.1.2)\n",
+ "Requirement already satisfied: charset-normalizer<4,>=2 in ./.venv/lib/python3.11/site-packages (from requests>=2.32.2->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (3.4.0)\n",
+ "Requirement already satisfied: urllib3<3,>=1.21.1 in ./.venv/lib/python3.11/site-packages (from requests>=2.32.2->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2.2.3)\n",
+ "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.11/site-packages (from pandas->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2.9.0.post0)\n",
+ "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.11/site-packages (from pandas->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2024.2)\n",
+ "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.11/site-packages (from pandas->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (2024.2)\n",
+ "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (1.16.0)\n",
+ "Requirement already satisfied: propcache>=0.2.0 in ./.venv/lib/python3.11/site-packages (from yarl<2.0,>=1.12.0->aiohttp->datasets>=2.16.0->distilabel->distilabel[llama_cpp]) (0.2.0)\n",
+ "\n",
+ "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.1.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.2\u001b[0m\n",
+ "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip install -U \"git+https://github.com/argilla-io/distilabel.git@fix/simplified-prompt-template-argilla-labeller#egg=distilabel[llama_cpp]\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/ben/code/argilla-cookbook/.venv/lib/python3.11/site-packages/argilla/datasets/_resource.py:264: UserWarning: Workspace not provided. Using default workspace: argilla id: 108b045c-a82e-4c75-a61b-0cddfb22c4c8\n",
+ " warnings.warn(f\"Workspace not provided. Using default workspace: {workspace.name} id: {workspace.id}\")\n",
+ "/Users/ben/code/argilla-cookbook/.venv/lib/python3.11/site-packages/argilla/records/_mapping/_mapper.py:89: UserWarning: Keys ['instruction', 'gender', 'age_group', 'nationality', 'expertise', 'language', 'distilabel_metadata', 'model_name', 'labels'] in data are not present in the mapping and will be ignored.\n",
+ " warnings.warn(f\"Keys {unknown_keys} in data are not present in the mapping and will be ignored.\")\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "
DatasetRecords: The provided batch size 256 was normalized. Using value 20.\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "DatasetRecords: The provided batch size \u001b[1;36m256\u001b[0m was normalized. Using value \u001b[1;36m20\u001b[0m.\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Sending records...: 100%|██████████| 1/1 [00:00<00:00, 3.50batch/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os\n",
+ "from uuid import uuid4\n",
+ "\n",
+ "import argilla as rg\n",
+ "\n",
+ "client = rg.Argilla()\n",
+ "\n",
+ "labels = [\"positive\", \"negative\", \"neutral\"]\n",
+ "\n",
+ "settings = rg.Settings(\n",
+ " guidelines=\"Label the sentiment of the text\",\n",
+ " fields=[\n",
+ " rg.TextField(\n",
+ " name=\"text\",\n",
+ " title=\"Text\",\n",
+ " description=\"A review of a pc component\",\n",
+ " )\n",
+ " ],\n",
+ " questions=[\n",
+ " rg.LabelQuestion(\n",
+ " name=\"sentiment\",\n",
+ " title=\"sentiment\",\n",
+ " description=\"Provide a single label for the sentiment of the text\",\n",
+ " labels=labels,\n",
+ " )\n",
+ " ],\n",
+ " # mapping={\"sentiment\": \"label\"},\n",
+ ")\n",
+ "\n",
+ "dataset_name = f\"pc-component-{uuid4()}\"\n",
+ "\n",
+ "dataset = rg.Dataset.from_hub(\n",
+ " repo_id=\"argilla/pc-components-reviews\",\n",
+ " name=dataset_name,\n",
+ " split=\"train[:20]\",\n",
+ " client=client,\n",
+ " with_records=True,\n",
+ " settings=settings,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 70,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "DatasetRecords: The provided batch size 256 was normalized. Using value 20.\n",
+ "
\n"
+ ],
+ "text/plain": [
+ "DatasetRecords: The provided batch size \u001b[1;36m256\u001b[0m was normalized. Using value \u001b[1;36m20\u001b[0m.\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Sending records...: 100%|██████████| 1/1 [00:00<00:00, 3.09batch/s]\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "DatasetRecords(Dataset(id=UUID('a27327ea-2ee4-4b44-afcb-ed19724a3866') inserted_at=datetime.datetime(2024, 10, 14, 9, 23, 11, 205431) updated_at=datetime.datetime(2024, 10, 14, 9, 23, 11, 818327) name='pc-component-1b5a4aff-9bc9-4b27-8cec-bc21b57b3e34' status='ready' guidelines='Label the sentiment of the text' allow_extra_metadata=False distribution=OverlapTaskDistributionModel(strategy='overlap', min_submitted=1) workspace_id=UUID('108b045c-a82e-4c75-a61b-0cddfb22c4c8') last_activity_at=datetime.datetime(2024, 10, 14, 9, 23, 11, 818327)))"
+ ]
+ },
+ "execution_count": 70,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "## ADD WITHOUT SUGGESTIONS\n",
+ "\n",
+ "# from datasets import load_dataset\n",
+ "\n",
+ "# updated_records = []\n",
+ "\n",
+ "# for sample in load_dataset(\"argilla/pc-components-reviews\", split=\"train[20:40]\"):\n",
+ "# _record = {\n",
+ "# \"text\": sample[\"text\"],\n",
+ "# }\n",
+ "# updated_records.append(_record)\n",
+ "\n",
+ "# dataset.records.log(updated_records)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Label the datasets\n",
+ "\n",
+ "We will now label the datasets. We will use the `ArgillaLabeller` class to label the datasets. This class will use will use a `LlamaCppLLM` LLM to label the datasets. These labels will then be converted into `rg.Suggestion` objects and added to the records. For the sake of the example, we will only label 5 records per time using a while loop that continuesly fetches pending records from Argilla for both datasets and labels them with the LLM. After the labelling, we will update the dataset with the new records."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from collections import Counter\n",
+ "from distilabel.llms.llamacpp import LlamaCppLLM\n",
+ "from distilabel.steps.tasks import ArgillaLabeller\n",
+ "\n",
+ "dataset = client.datasets(name=dataset_name, workspace=\"argilla\")\n",
+ "\n",
+ "example_records = []\n",
+ "\n",
+ "counter = Counter()\n",
+ "max_samples = 16\n",
+ "\n",
+ "\n",
+ "for record in dataset.records(with_responses=True, with_suggestions=True):\n",
+ " value = record.suggestions[\"sentiment\"].value\n",
+ " counter[value] += 1\n",
+ " if counter[value] > 12:\n",
+ " continue\n",
+ " record.responses.add(\n",
+ " rg.Response(question_name=\"sentiment\", value=value, user_id=client.me)\n",
+ " )\n",
+ " example_records.append(record)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "example_records = [record.to_dict() for record in example_records]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "20"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(example_records)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# randomly shuffle the records\n",
+ "\n",
+ "import random\n",
+ "\n",
+ "random.shuffle(example_records)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Distilabel can label your records\n",
+ "\n",
+ "We can use the `process` method of the `ArgillaLabeller` class to label the records. This method will label the records with the LLM and update the records with the new labels. We will use this method to label the records of the datasets."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from datasets import load_dataset\n",
+ "\n",
+ "train_dataset = load_dataset(\"argilla/pc-components-reviews\", split=\"train[:20]\")\n",
+ "\n",
+ "train_dataset = train_dataset.remove_columns(\n",
+ " [col for col in train_dataset.column_names if col not in [\"text\", \"sentiment\"]]\n",
+ ")\n",
+ "\n",
+ "test_dataset = load_dataset(\"argilla/pc-components-reviews\", split=\"train[20:100]\")\n",
+ "\n",
+ "test_dataset = test_dataset.remove_columns(\n",
+ " [col for col in test_dataset.column_names if col not in [\"text\", \"sentiment\"]]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " sentiment | \n",
+ " text | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " positive | \n",
+ " I finally got my hands on the Ryzen 9 7950X an... | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " positive | \n",
+ " I recently bought the Intel Core i5-10400F and... | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " positive | \n",
+ " I just upgraded to the Ryzen 9 5950X and it's ... | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " positive | \n",
+ " I just swapped out my old GPU for the RTX 4070... | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " negative | \n",
+ " I just upgraded to the new Intel Core i9-13900... | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " neutral | \n",
+ " Just got the new Intel Core i9-13900K, and I m... | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " negative | \n",
+ " I just got the new Ryzen 5 5600X and it’s not ... | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " positive | \n",
+ " Just built my new rig with the Ryzen 5 5600X a... | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " neutral | \n",
+ " I recently upgraded my PC with the AMD Ryzen 5... | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " positive | \n",
+ " I just built my first PC with an AMD Ryzen 5 3... | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " negative | \n",
+ " I just installed the new Ryzen 7 5800X and the... | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " neutral | \n",
+ " Hey, I just got the Ryzen 5 3600 and it’s actu... | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " negative | \n",
+ " I just got this new ASUS ROG Strix Z690-E Gami... | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " neutral | \n",
+ " I recently swapped out my old GPU for the NVID... | \n",
+ "
\n",
+ " \n",
+ " 14 | \n",
+ " neutral | \n",
+ " The Ryzen 9 5950X really shines in multi-threa... | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " positive | \n",
+ " I just built my new rig with the Ryzen 9 5900X... | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " negative | \n",
+ " I just built my rig with the Ryzen 5 3600 and ... | \n",
+ "
\n",
+ " \n",
+ " 17 | \n",
+ " positive | \n",
+ " I just built my new rig with the Ryzen 7 5800X... | \n",
+ "
\n",
+ " \n",
+ " 18 | \n",
+ " neutral | \n",
+ " I recently bought an Intel Core i5 for my new ... | \n",
+ "
\n",
+ " \n",
+ " 19 | \n",
+ " positive | \n",
+ " I just assembled a system with the Ryzen 9 595... | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " sentiment text\n",
+ "0 positive I finally got my hands on the Ryzen 9 7950X an...\n",
+ "1 positive I recently bought the Intel Core i5-10400F and...\n",
+ "2 positive I just upgraded to the Ryzen 9 5950X and it's ...\n",
+ "3 positive I just swapped out my old GPU for the RTX 4070...\n",
+ "4 negative I just upgraded to the new Intel Core i9-13900...\n",
+ "5 neutral Just got the new Intel Core i9-13900K, and I m...\n",
+ "6 negative I just got the new Ryzen 5 5600X and it’s not ...\n",
+ "7 positive Just built my new rig with the Ryzen 5 5600X a...\n",
+ "8 neutral I recently upgraded my PC with the AMD Ryzen 5...\n",
+ "9 positive I just built my first PC with an AMD Ryzen 5 3...\n",
+ "10 negative I just installed the new Ryzen 7 5800X and the...\n",
+ "11 neutral Hey, I just got the Ryzen 5 3600 and it’s actu...\n",
+ "12 negative I just got this new ASUS ROG Strix Z690-E Gami...\n",
+ "13 neutral I recently swapped out my old GPU for the NVID...\n",
+ "14 neutral The Ryzen 9 5950X really shines in multi-threa...\n",
+ "15 positive I just built my new rig with the Ryzen 9 5900X...\n",
+ "16 negative I just built my rig with the Ryzen 5 3600 and ...\n",
+ "17 positive I just built my new rig with the Ryzen 7 5800X...\n",
+ "18 neutral I recently bought an Intel Core i5 for my new ...\n",
+ "19 positive I just assembled a system with the Ryzen 9 595..."
+ ]
+ },
+ "execution_count": 28,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "train_dataset.to_pandas()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from distilabel.llms import InferenceEndpointsLLM\n",
+ "from huggingface_hub import notebook_login\n",
+ "\n",
+ "# notebook_login()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING:distilabel.step.None:Step 'None' hasn't received a pipeline, and it hasn't been created within a `Pipeline` context. Please, use `with Pipeline() as pipeline:` and create the step within the context.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.step.None:Step 'None' hasn't received a pipeline, and it hasn't been created within a `Pipeline` context. Please, use `with Pipeline() as pipeline:` and create the step within the context.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.step.None:Step 'None' hasn't received a pipeline, and it hasn't been created within a `Pipeline` context. Please, use `with Pipeline() as pipeline:` and create the step within the context.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.step.None:Step 'None' hasn't received a pipeline, and it hasn't been created within a `Pipeline` context. Please, use `with Pipeline() as pipeline:` and create the step within the context.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n",
+ "WARNING:distilabel.llm.meta-llama/Meta-Llama-3.1-8B-Instruct:Since the `base_url=https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3.1-8B-Instruct` is available and either one of `model_id` or `endpoint_name` is also provided, the `base_url` will either be ignored or overwritten with the one generated from either of those args, for serverless or dedicated inference endpoints, respectively.\n"
+ ]
+ }
+ ],
+ "source": [
+ "results_scores = {}\n",
+ "max_eval_records = 100\n",
+ "\n",
+ "for n_samples in [0, 4, 8, 16]:\n",
+ " # Initialize the labeller with the model and fields\n",
+ " labeller = ArgillaLabeller(\n",
+ " llm=InferenceEndpointsLLM(\n",
+ " model_id=\"meta-llama/Meta-Llama-3.1-8B-Instruct\",\n",
+ " tokenizer_id=\"meta-llama/Meta-Llama-3.1-8B-Instruct\",\n",
+ " generation_kwargs={\"max_new_tokens\": 1024 * 4},\n",
+ " ),\n",
+ " example_records=example_records[: n_samples + 1],\n",
+ " )\n",
+ " labeller.load()\n",
+ " predictions = []\n",
+ " true = []\n",
+ " results = labeller.process(\n",
+ " [\n",
+ " {\n",
+ " \"record\": rg.Record(fields={\"text\": sample[\"text\"]}),\n",
+ " \"fields\": dataset.fields,\n",
+ " \"question\": dataset.questions[0],\n",
+ " \"guidelines\": dataset.guidelines,\n",
+ " }\n",
+ " for sample in test_dataset\n",
+ " ]\n",
+ " )\n",
+ " for sample, result in zip(test_dataset, next(results)):\n",
+ " true.append(sample[\"sentiment\"])\n",
+ " if not result[\"suggestion\"]:\n",
+ " predictions.append(None)\n",
+ " continue\n",
+ "\n",
+ " suggestion = result[\"suggestion\"][\"value\"]\n",
+ " predictions.append(suggestion)\n",
+ "\n",
+ " results_scores[n_samples] = {\"true\": true, \"predictions\": predictions}\n",
+ "\n",
+ " del labeller"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "llm_results = {}\n",
+ "\n",
+ "for n_samples, data in results_scores.items():\n",
+ " true = data[\"true\"]\n",
+ " predictions = data[\"predictions\"]\n",
+ "\n",
+ " acc = sum([t == p for t, p in zip(true, predictions) if p is not None]) / len(\n",
+ " [p for p in predictions if p is not None]\n",
+ " )\n",
+ "\n",
+ " print(f\"Accuracy for {n_samples} samples: {acc}\")\n",
+ " llm_results[n_samples] = {\"accuracy\": acc}\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# SetFit Efficient Classifier"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Let's make the required imports:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from datasets import load_dataset, Dataset\n",
+ "from setfit import (\n",
+ " SetFitModel,\n",
+ " Trainer,\n",
+ " get_templated_dataset,\n",
+ " sample_dataset,\n",
+ " TrainingArguments,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "train_dataset = train_dataset.rename_column(\"sentiment\", \"label\")\n",
+ "test_dataset = test_dataset.rename_column(\"sentiment\", \"label\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def train_model(\n",
+ " model_name,\n",
+ " eval_dataset,\n",
+ " train_dataset=None,\n",
+ "):\n",
+ " model = SetFitModel.from_pretrained(model_name)\n",
+ "\n",
+ " args = TrainingArguments(\n",
+ " num_epochs=1,\n",
+ " eval_strategy=\"epoch\",\n",
+ " save_strategy=\"epoch\",\n",
+ " load_best_model_at_end=True,\n",
+ " )\n",
+ " if train_dataset is None or len(train_dataset) == 0:\n",
+ " print(\"Sampling dataset for zero shot\")\n",
+ " train_dataset = get_templated_dataset(\n",
+ " candidate_labels=labels,\n",
+ " )\n",
+ " eval_dataset = eval_dataset.map(lambda x: {\"label\": labels.index(x[\"label\"])})\n",
+ "\n",
+ " trainer = Trainer(\n",
+ " model=model,\n",
+ " train_dataset=train_dataset,\n",
+ " eval_dataset=eval_dataset,\n",
+ " # args=args,\n",
+ " )\n",
+ "\n",
+ " trainer.train()\n",
+ "\n",
+ " results = trainer.evaluate()\n",
+ "\n",
+ " print(results)\n",
+ "\n",
+ " return model, results"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Let's train the model. We will use `TaylorAI/bge-micro-v2`, available in the [Hugging Face Hub](https://huggingface.co/TaylorAI/bge-micro-v2)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "model_head.pkl not found on HuggingFace Hub, initialising classification head with random weights. You should TRAIN this model on a downstream task to use it for predictions and inference.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Sampling dataset for zero shot\n"
+ ]
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "da6b33573257484b95f4b5119eaf574c",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Map: 0%| | 0/6 [00:00, ? examples/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "***** Running training *****\n",
+ " Num unique pairs = 24\n",
+ " Batch size = 16\n",
+ " Num epochs = 1\n"
+ ]
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "44e0f7c3c7e447a2b501c473d9f7c820",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/2 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'embedding_loss': 0.2891, 'grad_norm': 1.4333018064498901, 'learning_rate': 2e-05, 'epoch': 0.5}\n"
+ ]
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "95efd6758a3f4d8d8a77b3faa1622f99",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Computing widget examples: 0%| | 0/1 [00:00, ?example/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "***** Running evaluation *****\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'train_runtime': 0.3945, 'train_samples_per_second': 60.831, 'train_steps_per_second': 5.069, 'train_loss': 0.2889108806848526, 'epoch': 1.0}\n",
+ "{'accuracy': 0.4875}\n"
+ ]
+ }
+ ],
+ "source": [
+ "model, results = train_model(\n",
+ " model_name=\"TaylorAI/bge-micro-v2\", eval_dataset=test_dataset\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Dataset({\n",
+ " features: ['label', 'text'],\n",
+ " num_rows: 20\n",
+ "})"
+ ]
+ },
+ "execution_count": 42,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "train_dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can save it locally or push it to the Hub. And then, load it from there."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results_scores = {}\n",
+ "\n",
+ "for n_samples in [0, 4, 8, 16]:\n",
+ "\n",
+ " _train_dataset = sample_dataset(\n",
+ " dataset=train_dataset, label_column=\"label\", num_samples=n_samples\n",
+ " )\n",
+ " print(f\"Results for {n_samples} samples:\")\n",
+ " model, results = train_model(\n",
+ " model_name=\"TaylorAI/bge-micro-v2\",\n",
+ " train_dataset=_train_dataset,\n",
+ " eval_dataset=test_dataset,\n",
+ " )\n",
+ " results_scores[n_samples] = results"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "370203c422754c31bd954010a9aac493",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Upload 2 LFS files: 0%| | 0/2 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2995c8fe660d41008160fedab6389bba",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "model_head.pkl: 0%| | 0.00/10.2k [00:00, ?B/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "a0a02473915c428da53e05af04e4716e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "model.safetensors: 0%| | 0.00/69.6M [00:00, ?B/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "CommitInfo(commit_url='https://huggingface.co/argilla/pc_components_classifier/commit/5c471988d1019eec0ec7f13a076e62b9d3f90c72', commit_message='Push model using huggingface_hub.', commit_description='', oid='5c471988d1019eec0ec7f13a076e62b9d3f90c72', pr_url=None, repo_url=RepoUrl('https://huggingface.co/argilla/pc_components_classifier', endpoint='https://huggingface.co', repo_type='model', repo_id='argilla/pc_components_classifier'), pr_revision=None, pr_num=None)"
+ ]
+ },
+ "execution_count": 44,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Save and load locally\n",
+ "# model.save_pretrained(\"text_classification_model\")\n",
+ "# model = SetFitModel.from_pretrained(\"text_classification_model\")\n",
+ "\n",
+ "# Push and load in HF\n",
+ "\n",
+ "model.push_to_hub(repo_id=\"argilla/pc_components_classifier\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "df = pd.DataFrame(results_scores).T\n",
+ "\n",
+ "df = df.rename(columns={\"accuracy\": \"SetFit-TaylorAI/bge-micro-v2\"})\n",
+ "\n",
+ "\n",
+ "df.at[0, \"LlaMA-3.1-8b-zero-shot\"] = 0.5875\n",
+ "df.at[4, \"LlaMA-3.1-8b-zero-shot\"] = 0.6125\n",
+ "df.at[8, \"LlaMA-3.1-8b-zero-shot\"] = 0.625\n",
+ "df.at[16, \"LlaMA-3.1-8b-zero-shot\"] = 0.765"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 53,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+kAAAIjCAYAAAB/OVoZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB7DUlEQVR4nO3dd3gU1dvG8Xs3vVcIvUrvNQICgiCCUhQUEaVjRUCUpnSE0FRUQCwUCwiKgvqjKKJIlSoo0gSpCoEESANSduf9I2/WLEkggSS7ge/nuvYie3bO7DMTArn3nDljMgzDEAAAAAAAcDizowsAAAAAAACpCOkAAAAAADgJQjoAAAAAAE6CkA4AAAAAgJMgpAMAAAAA4CQI6QAAAAAAOAlCOgAAAAAAToKQDgAAAACAkyCkAwAAAADgJAjpAAAgT6xfv14mk0nLli1zdCnZEhkZqS5duigkJEQmk0kzZ850dEm5auHChTKZTDp+/LijSwEAXAchHQCQLXPmzJHJZFJ4eLijS0E6acHL09NT//zzT4bX7733XlWvXt0BlRU8L730kr7//nuNHDlSn376qR544AFHlwQAuAMR0gEA2bJo0SKVKVNG27dv15EjRxxdDq6RmJioKVOmOLqMAu2nn35Sx44d9corr+jJJ59U5cqVHV0SAOAOREgHANzQsWPHtGXLFr355psqVKiQFi1a5OiSspSQkODoEhyidu3a+vDDD/Xvv/86upR8l1vf83PnzikwMDBX9gUAwM0ipAMAbmjRokUKCgrSgw8+qC5dumQZ0i9duqSXXnpJZcqUkYeHh0qUKKEePXooKirKts3Vq1c1btw4VaxYUZ6enipatKgeeeQRHT16VNJ/1zGvX7/ebt/Hjx+XyWTSwoULbW29evWSr6+vjh49qnbt2snPz0/du3eXJG3cuFGPPvqoSpUqJQ8PD5UsWVIvvfSSrly5kqHugwcP6rHHHlOhQoXk5eWlSpUq6bXXXpMk/fzzzzKZTFq+fHmGfosXL5bJZNLWrVszPR87d+6UyWTSxx9/nOG177//XiaTSf/73/8kSXFxcRo8eLDt3BUuXFitW7fW7t27M933tV599VVZLJYbjqZndh7TmEwmjRs3zvZ83LhxMplMOnz4sJ588kkFBASoUKFCGj16tAzD0KlTp9SxY0f5+/urSJEieuONNzJ9T4vFoldffVVFihSRj4+POnTooFOnTmXYbtu2bXrggQcUEBAgb29vNW/eXJs3b7bbJq2m/fv364knnlBQUJDuueee6x7z33//rUcffVTBwcHy9vbW3XffrZUrV9peT7tkwDAMzZ49WyaTSSaT6br7XLJkierVqyc/Pz/5+/urRo0aevvtt22vX7hwQa+88opq1KghX19f+fv7q23bttq7d6/dftL+vn/xxRcaP368ihcvLj8/P3Xp0kUxMTFKTEzU4MGDVbhwYfn6+qp3795KTEy024fJZNKAAQO0aNEiVapUSZ6enqpXr542bNhw3WNIs3r1ajVt2lQ+Pj7y8/PTgw8+qD///NNum7Nnz6p3794qUaKEPDw8VLRoUXXs2JHr2wEgD7g6ugAAgPNbtGiRHnnkEbm7u6tbt2567733tGPHDjVo0MC2TXx8vJo2baoDBw6oT58+qlu3rqKiovTtt9/q9OnTCg0NlcVi0UMPPaR169bp8ccf16BBgxQXF6e1a9dq3759Kl++fI5rS0lJUZs2bXTPPfdoxowZ8vb2liR9+eWXunz5sp577jmFhIRo+/btevfdd3X69Gl9+eWXtv6///67mjZtKjc3Nz399NMqU6aMjh49qu+++06TJk3Svffeq5IlS2rRokV6+OGHM5yX8uXLq1GjRpnWVr9+fZUrV05ffPGFevbsaffa0qVLFRQUpDZt2kiSnn32WS1btkwDBgxQ1apVFR0drU2bNunAgQOqW7fuDc9D2bJl1aNHD3344YcaMWKEihUrlqPzeD1du3ZVlSpVNGXKFK1cuVKvv/66goOD9f7776tly5aaOnWqFi1apFdeeUUNGjRQs2bN7PpPmjRJJpNJw4cP17lz5zRz5ky1atVKe/bskZeXl6TUqeZt27ZVvXr1NHbsWJnNZi1YsEAtW7bUxo0b1bBhQ7t9Pvroo6pQoYImT54swzCyrD0yMlKNGzfW5cuXNXDgQIWEhOjjjz9Whw4dtGzZMj388MNq1qyZPv30Uz311FNq3bq1evTocd3zsXbtWnXr1k333Xefpk6dKkk6cOCANm/erEGDBklK/WBgxYoVevTRR1W2bFlFRkbq/fffV/PmzbV///4M35+IiAh5eXlpxIgROnLkiN599125ubnJbDbr4sWLGjdunH799VctXLhQZcuW1ZgxY+z6//LLL1q6dKkGDhwoDw8PzZkzRw888IC2b99+3TUJPv30U/Xs2VNt2rTR1KlTdfnyZb333nu655579Ntvv6lMmTKSpM6dO+vPP//Uiy++qDJlyujcuXNau3atTp48adsGAJBLDAAArmPnzp2GJGPt2rWGYRiG1Wo1SpQoYQwaNMhuuzFjxhiSjK+//jrDPqxWq2EYhjF//nxDkvHmm29muc3PP/9sSDJ+/vlnu9ePHTtmSDIWLFhga+vZs6chyRgxYkSG/V2+fDlDW0REhGEymYwTJ07Y2po1a2b4+fnZtaWvxzAMY+TIkYaHh4dx6dIlW9u5c+cMV1dXY+zYsRneJ72RI0cabm5uxoULF2xtiYmJRmBgoNGnTx9bW0BAgPHCCy9cd1+ZWbBggSHJ2LFjh3H06FHD1dXVGDhwoO315s2bG9WqVbM9z+w8ppFkdzxjx441JBlPP/20rS0lJcUoUaKEYTKZjClTptjaL168aHh5eRk9e/a0taV9L4sXL27Exsba2r/44gtDkvH2228bhpF6ritUqGC0adPG7rxfvnzZKFu2rNG6desMNXXr1i1b52fw4MGGJGPjxo22tri4OKNs2bJGmTJlDIvFYnf82fkeDBo0yPD39zdSUlKy3Obq1at2+zaM1HPv4eFhTJgwwdaWdo6qV69uJCUl2dq7detmmEwmo23btnb7aNSokVG6dGm7NkmGJGPnzp22thMnThienp7Gww8/bGtL+7ty7Ngx23kIDAw0+vfvb7e/s2fPGgEBAbb2ixcvGpKM6dOnX+esAAByC9PdAQDXtWjRIoWFhalFixaSUqfWdu3aVUuWLJHFYrFt99VXX6lWrVoZRpvT+qRtExoaqhdffDHLbW7Gc889l6EtbYRWSr1mOSoqSo0bN5ZhGPrtt98kSefPn9eGDRvUp08flSpVKst6evToocTERLtbiS1dulQpKSl68sknr1tb165dlZycrK+//trW9sMPP+jSpUvq2rWrrS0wMFDbtm27pWvKy5Urp6eeekoffPCBzpw5c9P7uVa/fv1sX7u4uKh+/foyDEN9+/a1tQcGBqpSpUr6+++/M/Tv0aOH/Pz8bM+7dOmiokWLatWqVZKkPXv26K+//tITTzyh6OhoRUVFKSoqSgkJCbrvvvu0YcMGWa1Wu30+++yz2ap91apVatiwod2UeF9fXz399NM6fvy49u/fn72TkE5gYKASEhK0du3aLLfx8PCQ2Zz6a5bFYlF0dLR8fX1VqVKlTC9h6NGjh9zc3GzPw8PDZRiG+vTpY7ddeHi4Tp06pZSUFLv2Ro0aqV69erbnpUqVUseOHfX999/b/Zymt3btWl26dEndunWznfOoqCi5uLgoPDxcP//8s6TUnyV3d3etX79eFy9evMHZAQDcKkI6ACBLFotFS5YsUYsWLXTs2DEdOXJER44cUXh4uCIjI7Vu3TrbtkePHr3hrb6OHj2qSpUqydU19662cnV1VYkSJTK0nzx5Ur169VJwcLB8fX1VqFAhNW/eXJIUExMjSbZAeaO6K1eurAYNGthdi79o0SLdfffduuuuu67bt1atWqpcubKWLl1qa1u6dKlCQ0PVsmVLW9u0adO0b98+lSxZUg0bNtS4ceMyDbw3MmrUKKWkpOTqSu/XfoAREBAgT09PhYaGZmjPLMRVqFDB7rnJZNJdd91lu575r7/+kiT17NlThQoVsnt89NFHSkxMtH3P0pQtWzZbtZ84cUKVKlXK0F6lShXb6zn1/PPPq2LFimrbtq1KlCihPn36aM2aNXbbWK1WvfXWW6pQoYI8PDwUGhqqQoUK6ffff89wLFLm51iSSpYsmaHdarVm2Me151iSKlasqMuXL+v8+fOZHkfaeW/ZsmWG8/7DDz/o3LlzklI/cJg6dapWr16tsLAwNWvWTNOmTdPZs2evd5oAADeJa9IBAFn66aefdObMGS1ZskRLlizJ8PqiRYt0//335+p7ZjWintVoYPoRy/Tbtm7dWhcuXNDw4cNVuXJl+fj46J9//lGvXr0yjMpmR48ePTRo0CCdPn1aiYmJ+vXXXzVr1qxs9e3atasmTZqkqKgo+fn56dtvv1W3bt3sPqx47LHH1LRpUy1fvlw//PCDpk+frqlTp+rrr79W27Zts11nuXLl9OSTT+qDDz7QiBEjMrye0/MrpY6eZ6dN0nWvD89K2vdj+vTpql27dqbb+Pr62j1PP1MivxUuXFh79uzR999/r9WrV2v16tVasGCBevToYVskcPLkyRo9erT69OmjiRMnKjg4WGazWYMHD870719W5zM3z/O10ur49NNPVaRIkQyvp//7OXjwYLVv314rVqzQ999/r9GjRysiIkI//fST6tSpc8u1AAD+Q0gHAGRp0aJFKly4sGbPnp3hta+//lrLly/X3Llz5eXlpfLly2vfvn3X3V/58uW1bds2JScn203tTS8oKEhS6krx6eVkxPOPP/7Q4cOH9fHHH9stAnbt9ORy5cpJ0g3rlqTHH39cQ4YM0eeff64rV67Izc3Nbrr69XTt2lXjx4/XV199pbCwMMXGxurxxx/PsF3RokX1/PPP6/nnn9e5c+dUt25dTZo0KUchXUodTf/ss89si5qllxvnN6fSRmzTGIahI0eOqGbNmpJkWzDQ399frVq1ytX3Ll26tA4dOpSh/eDBg7bXb4a7u7vat2+v9u3by2q16vnnn9f777+v0aNH66677tKyZcvUokULzZs3z67fpUuXMsxAyA3XnmNJOnz4sLy9vVWoUKFM+6Sd98KFC2frvJcvX14vv/yyXn75Zf3111+qXbu23njjDX322We3VjwAwA7T3QEAmbpy5Yq+/vprPfTQQ+rSpUuGx4ABAxQXF6dvv/1WUurqz3v37s30VmVpo36dO3dWVFRUpiPQaduULl1aLi4uGW4fNWfOnGzXnjb6mH600TAMu1tkSVKhQoXUrFkzzZ8/XydPnsy0njShoaFq27atPvvsMy1atEgPPPBAtsNWlSpVVKNGDS1dulRLly5V0aJF7VZAt1gsGaYvFy5cWMWKFctwu63sKF++vJ588km9//77GaYk+/v7KzQ09JbOb0598skniouLsz1ftmyZzpw5Y/vwoV69eipfvrxmzJih+Pj4DP2zmq6dHe3atdP27dvtbpOXkJCgDz74QGXKlFHVqlVzvM/o6Gi752az2faBQ9r3y8XFJcPfoS+//FL//PNPjt8vO7Zu3Wp3rfupU6f0zTff6P77789yNL5Nmzby9/fX5MmTlZycnOH1tPN++fJlXb161e618uXLy8/P76b+fgIAro+RdABApr799lvFxcWpQ4cOmb5+9913q1ChQlq0aJG6du2qoUOHatmyZXr00UfVp08f1atXTxcuXNC3336ruXPnqlatWurRo4c++eQTDRkyRNu3b1fTpk2VkJCgH3/8Uc8//7w6duyogIAAPfroo3r33XdlMplUvnx5/e9//7NdH5sdlStXVvny5fXKK6/on3/+kb+/v7766qtMr5d+5513dM8996hu3bp6+umnVbZsWR0/flwrV67Unj177Lbt0aOHunTpIkmaOHFi9k+mUkfTx4wZI09PT/Xt29duin5cXJxKlCihLl26qFatWvL19dWPP/6oHTt2ZHnv8Rt57bXX9Omnn+rQoUOqVq2a3Wv9+vXTlClT1K9fP9WvX18bNmzQ4cOHb+p9siM4OFj33HOPevfurcjISM2cOVN33XWX+vfvLyk15H700Udq27atqlWrpt69e6t48eL6559/9PPPP8vf31/ffffdTb33iBEj9Pnnn6tt27YaOHCggoOD9fHHH+vYsWP66quvMlwqkR39+vXThQsX1LJlS5UoUUInTpzQu+++q9q1a9uudX/ooYc0YcIE9e7dW40bN9Yff/yhRYsW2WZv5Lbq1aurTZs2drdgk6Tx48dn2cff31/vvfeennrqKdWtW1ePP/64ChUqpJMnT2rlypVq0qSJZs2apcOHD+u+++7TY489pqpVq8rV1VXLly9XZGRkpjNCAAC3yDGLygMAnF379u0NT09PIyEhIcttevXqZbi5uRlRUVGGYRhGdHS0MWDAAKN48eKGu7u7UaJECaNnz5621w0j9bZar732mlG2bFnDzc3NKFKkiNGlSxfj6NGjtm3Onz9vdO7c2fD29jaCgoKMZ555xti3b1+mt2Dz8fHJtLb9+/cbrVq1Mnx9fY3Q0FCjf//+xt69ezO9/di+ffuMhx9+2AgMDDQ8PT2NSpUqGaNHj86wz8TERCMoKMgICAgwrly5kp3TaPPXX3/ZbpW1adOmDPsdOnSoUatWLcPPz8/w8fExatWqZcyZM+eG+01/C7Zrpd2iLv0t2Awj9XvQt29fIyAgwPDz8zMee+wx49y5c1negu38+fMZ9pvZeb/2dm9ptxf7/PPPjZEjRxqFCxc2vLy8jAcffDDDLe8MwzB+++0345FHHjFCQkIMDw8Po3Tp0sZjjz1mrFu37oY1Xc/Ro0eNLl262L6/DRs2NP73v/9l2E7ZvAXbsmXLjPvvv98oXLiw4e7ubpQqVcp45plnjDNnzti2uXr1qvHyyy8bRYsWNby8vIwmTZoYW7duNZo3b240b948wzn68ssv7d4jq+9rZsefVvdnn31mVKhQwfDw8DDq1KmT4TaG196CLX0Nbdq0MQICAgxPT0+jfPnyRq9evWy3dIuKijJeeOEFo3LlyoaPj48REBBghIeHG1988cUNzxUAIOdMhpELK48AAHAHSElJUbFixdS+ffsM1xoDjmIymfTCCy9keyFDAIBz45p0AACyacWKFTp//rzdYnQAAAC5iWvSAQC4gW3btun333/XxIkTVadOHdv91gEAAHIbI+kAANzAe++9p+eee06FCxfWJ5984uhyAADAbcyhIX3Dhg1q3769ihUrJpPJpBUrVtywz/r161W3bl15eHjorrvu0sKFC/O8TgDAnW3hwoVKSUnRzp07Vb16dUeXA9gxDIPr0QHgNuLQkJ6QkKBatWpp9uzZ2dr+2LFjevDBB9WiRQvt2bNHgwcPVr9+/fT999/ncaUAAAAAAOQ9p1nd3WQyafny5erUqVOW2wwfPlwrV67Uvn37bG2PP/64Ll26pDVr1uRDlQAAAAAA5J0CtXDc1q1b1apVK7u2Nm3aaPDgwVn2SUxMVGJiou251WrVhQsXFBISIpPJlFelAgAAAAAgKfXSpLi4OBUrVkxm8/UntBeokH727FmFhYXZtYWFhSk2NlZXrlyRl5dXhj4REREaP358fpUIAAAAAECmTp06pRIlSlx3mwIV0m/GyJEjNWTIENvzmJgYlSpVSqdOnZK/v78DKwMAAAAA3AliY2NVsmRJ+fn53XDbAhXSixQposjISLu2yMhI+fv7ZzqKLkkeHh7y8PDI0O7v709IBwAAAADkm+xccl2g7pPeqFEjrVu3zq5t7dq1atSokYMqAgAAAAAg9zg0pMfHx2vPnj3as2ePpNRbrO3Zs0cnT56UlDpVvUePHrbtn332Wf39998aNmyYDh48qDlz5uiLL77QSy+95IjyAQAAAADIVQ4N6Tt37lSdOnVUp04dSdKQIUNUp04djRkzRpJ05swZW2CXpLJly2rlypVau3atatWqpTfeeEMfffSR2rRp45D6AQAAAADITU5zn/T8Ehsbq4CAAMXExHBNOgAAAJyCYRhKSUmRxWJxdCkAbpKbm5tcXFwyfS0nObRALRwHAAAA3G6SkpJ05swZXb582dGlALgFJpNJJUqUkK+v7y3th5AOAAAAOIjVatWxY8fk4uKiYsWKyd3dPVurPwNwLoZh6Pz58zp9+rQqVKiQ5Yh6dhDSAQAAAAdJSkqS1WpVyZIl5e3t7ehyANyCQoUK6fjx40pOTr6lkF6gbsEGAAAA3I7MZn4tBwq63JoFw78GAAAAAAA4CUI6AAAAAABOgpAOAAAAoMAwmUxasWKFo8uwKVOmjGbOnOnoMmx69eqlTp06ObqMHHG276mjEdIBAAAA3JTz58/rueeeU6lSpeTh4aEiRYqoTZs22rx5c7b6jxs3TrVr187QXqZMGZlMJrtHiRIlJElnzpxR27ZtJUnHjx+XyWTSnj17Mt3/+vXrM+zn2sf69etv5tDzzNatW+Xi4qIHH3www2tZHe+JEyfk5eWl+Pj4fKoyd6X/njqTr7/+Wq1bt1ahQoXk7++vRo0a6fvvv8/z92V1dwAAAAA3pXPnzkpKStLHH3+scuXKKTIyUuvWrVN0dPQt73vChAnq37+/7XnaatlFihTJ9j4aN26sM2fO2J4PGjRIsbGxWrBgga0tODj4lmu9FUlJSXJ3d7c9nzdvnl588UXNmzdP//77r4oVK3bDfXzzzTdq0aLFLd+f21Fy8j291rXnLzdt2LBBrVu31uTJkxUYGKgFCxaoffv22rZtm+rUqZMn7ykxkg4AAAA4FcMwlJCQ5JCHYRjZrvPSpUvauHGjpk6dqhYtWqh06dJq2LChRo4cqQ4dOti26devn20ksmXLltq7d68kaeHChRo/frz27t1rG9VeuHChbf9+fn4qUqSI7VGoUCFJ9lOjy5YtK0mqU6eOTCaT7r33Xrsa3d3d7fbh5eVlG/EvUqSI9uzZo5YtWyowMFAhISF66KGHdPToUVv/li1basCAAXb7PH/+vNzd3bVu3bpMz8vJkyfVsWNH+fr6yt/fX4899pgiIyNtr6fNHvjoo49UtmxZeXp62l6Lj4/X0qVL9dxzz+nBBx+0Ox/X880339jOeZrx48fbzvuzzz6rpKQk22txcXHq3r27fHx8VLRoUb311lu69957NXjwYNs2iYmJeuWVV1S8eHH5+PgoPDz8hrMO0o5t/vz5KlWqlHx9ffX888/LYrFo2rRpKlKkiAoXLqxJkybZ9bt2uvvp06fVrVs3BQcHy8fHR/Xr19e2bduue/5udN6v9cEHH6hYsWKyWq127R07dlSfPn0kSTNnztSwYcPUoEEDVahQQZMnT1aFChX03XffXfc83CpG0gEAAAAncvlysnx933HIe8fHD5SPT/ZGJX19feXr66sVK1bo7rvvloeHR4ZtHn30UXl5eWn16tUKCAjQ+++/r/vuu0+HDx9W165dtW/fPq1Zs0Y//vijJCkgICBH9W7fvl0NGzbUjz/+qGrVquV4RDUhIUFDhgxRzZo1FR8frzFjxujhhx/Wnj17ZDab1a9fPw0YMEBvvPGG7fg+++wzFS9eXC1btsywP6vVaguKv/zyi1JSUvTCCy+oa9eudgH3yJEj+uqrr/T111/b3U/7iy++UOXKlVWpUiU9+eSTGjx4sEaOHHndW3tdunRJmzZt0qeffmprW7dunTw9PbV+/XodP35cvXv3VkhIiC0cDxkyRJs3b9a3336rsLAwjRkzRrt377a79GDAgAHav3+/lixZomLFimn58uV64IEH9Mcff6hChQpZ1nP06FGtXr1aa9as0dGjR9WlSxf9/fffqlixon755Rdt2bJFffr0UatWrRQeHp6hf3x8vJo3b67ixYvr22+/VZEiRbR79267MH3t+cvueU/v0Ucf1Ysvvqiff/5Z9913nyTpwoULWrNmjVatWpVpH6vVqri4uDyffUFIBwAAAJBjrq6uWrhwofr376+5c+eqbt26at68uR5//HHVrFlTmzZt0vbt23Xu3DlbwJ0xY4ZWrFihZcuW6emnn5avr69cXV0zne48fPhwjRo1yvZ88uTJGjhwoN02aaPrISEhNzVlunPnznbP58+fr0KFCmn//v2qXr26HnnkEQ0YMEDffPONHnvsMUmpMwB69eqVaXBet26d/vjjDx07dkwlS5aUJH3yySeqVq2aduzYoQYNGkhKnaL9ySef2OpPM2/ePD355JOSpAceeEAxMTH65ZdfMswQSG/VqlWqWbOm3bR4d3d3zZ8/X97e3qpWrZomTJigoUOHauLEiUpISNDHH3+sxYsX28LpggUL7PqfPHlSCxYs0MmTJ23tr7zyitasWaMFCxZo8uTJWdZjtVo1f/58+fn5qWrVqmrRooUOHTqkVatWyWw2q1KlSpo6dap+/vnnTEP64sWLdf78ee3YscMWhu+66y67ba49f2vXrs3WeU8vKChIbdu2tTsPy5YtU2hoqFq0aJHpsc2YMUPx8fG2vwt5hZAOAAAAOBFvbzfFxw+88YZ59N450blzZz344IPauHGjfv31V61evVrTpk3TRx99pISEBMXHxyskJMSuz5UrV+ymlGdl6NCh6tWrl+15aGhotmrauHGj3SJk77//vrp3757ptn/99ZfGjBmjbdu2KSoqyjZae/LkSVWvXl2enp566qmnNH/+fD322GPavXu39u3bp2+//TbT/R04cEAlS5a0BUVJqlq1qgIDA3XgwAFbWCxd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YsUKR5fh9Hr16qVOnTo5uow8c++992rw4MGOLqPAIaQDAAAAyLHcDJgLFy6UyWRSlSpVMrz25ZdfymQyqUyZMhleu3LlioKDgxUaGqrExMQbvs+hQ4fUokULhYWFydPTU+XKldOoUaOUnJx83X4DBw5UvXr15OHhodq1a2f3sLRo0SLVqlVL3t7eKlq0qPr06aPo6Ohs94c0bty4HJ3z2wEhHQAAAIDD+fj46Ny5c9q6datd+7x581SqVKlM+3z11VeqVq2aKleunK2Rezc3N/Xo0UM//PCDDh06pJkzZ+rDDz/U2LFjb9i3T58+6tq1a7aORZI2b96sHj16qG/fvvrzzz/15Zdfavv27erfv3+295FfbvQhBfIXIR0AAABwIoZhyEhKcszDMPLkmIYPH66KFSvK29tb5cqV0+jRozMEQ1dXVz3xxBOaP3++re306dNav369nnjiiUz3O2/ePD355JN68sknNW/evBvWUa5cOfXu3Vu1atVS6dKl1aFDB3Xv3l0bN268br933nlHL7zwgsqVK5eNo021detWlSlTRgMHDlTZsmV1zz336JlnntH27dszbDt+/HgVKlRI/v7+evbZZ5WUlJTlftevXy+TyZTh0atXL9s233zzjerWrWubLTB+/HilpKTYXjeZTHrvvffUoUMH+fj4aNKkSZKk9957T+XLl5e7u7sqVaqkTz/99IbHOWfOHFWoUEGenp4KCwtTly5d7F63Wq0aNmyYgoODVaRIEY0bN87u9ZMnT6pjx47y9fWVv7+/HnvsMUVGRkpKnWExfvx47d2713acCxcuvGFNBZ2rowsAAAAAkE5ysmIjIhzy1v4jR0ru7rm+Xz8/Py1cuFDFihXTH3/8of79+8vPz0/Dhg2z265Pnz6699579fbbb8vb21sLFy7UAw88oLCwsAz7PHr0qLZu3aqvv/5ahmHopZde0okTJ1S6dOls13XkyBGtWbNGjzzyyC0f47UaNWqkV199VatWrVLbtm117tw5LVu2TO3atbPbbt26dfL09NT69et1/Phx9e7dWyEhIbbgfK3GjRvrzJkztucHDhxQu3bt1KxZM0nSxo0b1aNHD73zzjtq2rSpjh49qqefflqS7GYMjBs3TlOmTNHMmTPl6uqq5cuXa9CgQZo5c6ZatWql//3vf+rdu7dKlCihFi1aZFrLzp07NXDgQH366adq3LixLly4kOEDj48//lhDhgzRtm3btHXrVvXq1UtNmjRR69atZbVabQH9l19+UUpKil544QV17dpV69evV9euXbVv3z6tWbNGP/74oyQpICAgh9+JgoeRdAAAAAB5atSoUWrcuLHKlCmj9u3b65VXXtEXX3yRYbs6deqoXLlyWrZsmQzD0MKFC9WnT59M9zl//ny1bdtWQUFBCg4OVps2bbRgwYJs1dO4cWN5enqqQoUKatq0qSZMmHBLx5eZJk2aaNGiReratavc3d1VpEgRBQQEaPbs2Xbbubu7a/78+apWrZoefPBBTZgwQe+8846sVmum+03bV5EiReTm5qZ+/fqpT58+tvM0fvx4jRgxQj179lS5cuXUunVrTZw4Ue+//77dfp544gn17t1b5cqVU6lSpTRjxgz16tVLzz//vCpWrKghQ4bokUce0YwZM7I8xpMnT8rHx0cPPfSQSpcurTp16mjgwIF229SsWVNjx45VhQoV1KNHD9WvX1/r1q2TlPoBxR9//KHFixerXr16Cg8P1yeffKJffvlFO3bskJeXl3x9feXq6mo7Zi8vrxx/LwoaRtIBAAAAZ+Lmljqi7aD3zgtLly7VO++8o6NHjyo+Pl4pKSny9/fPdNs+ffpowYIFKlWqlBISEtSuXTvNmjXLbhuLxaKPP/5Yb7/9tq3tySef1CuvvKIxY8bIbDarWrVqOnHihCSpadOmWr16tV09cXFx2rt3r4YOHaoZM2ZkGNXPCV9fX7s65s6dq/3792vQoEEaM2aM2rRpozNnzmjo0KF69tln7abmpy0sl6ZRo0aKj4/XqVOntGnTJj3zzDO211avXq2mTZtKSr2OvHPnzipdurTdedi7d682b95sNxJvsVh09epVXb582fZe9evXtzuGAwcO2Ebc0zRp0sS270WLFmWopXXr1ipdurTKlSunBx54QA888IAefvhhu+OpWbOm3T6LFi2qc+fO2d6zZMmSKlmypO31qlWrKjAwUAcOHFCDBg0yP+G3OUI6AAAA4ERMJlOeTDl3lK1bt6p79+4aP3682rRpo4CAAC1ZskRvvPFGptt3795dw4YN07hx4/TUU0/J1TVjZPn+++/1zz//ZFjIzWKxaN26dWrdurVWrVplu+792tHXtFBYtWpVWSwWPf3003r55Zfl4uJyU8e4Z88e29dpHz5E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vXrZvWY2m23TudMkJydn2Iebm5vdc5PJlGmb1WrNdl3x8fFq3769pk6dmuG1okWL2r728fHJ9j5vhYuLi9auXastW7bohx9+0LvvvqvXXntN27ZtU9myZdWzZ09FR0fr7bffVunSpeXh4aFGjRplWMwu/XlJW0k/s7acnKv04uPjJUkrV660C/aS5OHhIUlq27atTpw4oVWrVmnt2rW677779MILL2jGjBk39Z4AAFwPI+kAAOTQlClT9N1332nr1q127YUKFdLZs2ftgnpu3tv8119/tX2dkpKiXbt2qUqVKpKkunXr6s8//1SZMmV011132T1yEsz9/f1VrFgxbd682a598+bNqlq1ao7qNZlMatKkicaPH6/ffvtN7u7uWr58uW1/AwcOVLt27VStWjV5eHjYLXJ3K06ePKl///3X9vzXX3+V2WxWpUqVMmxbtWpVeXh46OTJkxnOW8mSJW3bFSpUSD179tRnn32mmTNn6oMPPsiVWgEAuBYj6QAA5FCNGjXUvXt3vfPOO3bt9957r86fP69p06apS5cuWrNmjVavXi1/f/9ced/Zs2erQoUKqlKlit566y1dvHhRffr0kSS98MIL+vDDD9WtWzcNGzZMwcHBOnLkiJYsWaKPPvpILi4u2X6foUOHauzYsSpfvrxq166tBQsWaM+ePVq0aFG297Ft2zatW7dO999/vwoXLqxt27bp/Pnztg8VKlSooE8//VT169dXbGyshg4dKi8vr5ydkCx4enqqZ8+emjFjhmJjYzVw4EA99thjKlKkSIZt/fz89Morr+ill16S1WrVPffco5iYGG3evFn+/v7q2bOnxowZo3r16qlatWpKTEzU//73P9txAACQ2xhJBwDgJkyYMCHDFOsqVapozpw5mj17tmrVqqXt27dnuvL5zZoyZYqmTJmiWrVqadOmTfr2229tq4ynjX5bLBbdf//9qlGjhgYPHqzAwEC769+zY+DAgRoyZIhefvll1ahRQ2vWrNG3336rChUqZHsf/v7+2rBhg9q1a6eKFStq1KhReuONN9S2bVtJ0rx583Tx4kXVrVtXTz31lAYOHKjChQvnqM6s3HXXXXrkkUfUrl073X///apZs6bmzJmT5fYTJ07U6NGjFRERoSpVquiBBx7QypUrVbZsWUmSu7u7Ro4cqZo1a6pZs2ZycXHRkiVLcqVWAACuZTKuvXgOAACggBo3bpxWrFiRq5cZAACQnxhJBwAAAADASRDSAQAAAABwEkx3BwAAAADASTCSDgAAAACAkyCkAwAAAADgJAjpAAAAAAA4CUI6AAAAAABOgpAOAAAAAICTIKQDAAAAAOAkCOkAAAAAADgJQjoAAAAAAE7i/wADqQn3enuTfAAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "df.plot(\n",
+ " xlabel=\"Number of samples\",\n",
+ " ylabel=\"Accuracy\",\n",
+ " title=\"Accuracy vs Number of samples\",\n",
+ " xticks=[0, 4, 8, 16],\n",
+ " yticks=[0.0, 0.2, 0.4, 0.6, 0.8, 1.0],\n",
+ " color=[\"darkblue\", \"lightcoral\"],\n",
+ " figsize=(12, 6),\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": ".venv",
+ "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.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}