{"id":3628,"date":"2025-05-07T07:02:21","date_gmt":"2025-05-07T07:02:21","guid":{"rendered":"https:\/\/mailitics.com\/index.php\/2025\/05\/07\/retrieval-augmented-classification-improving-text-classification-with-external-knowledge\/"},"modified":"2025-05-07T07:02:21","modified_gmt":"2025-05-07T07:02:21","slug":"retrieval-augmented-classification-improving-text-classification-with-external-knowledge","status":"publish","type":"post","link":"https:\/\/mailitics.com\/index.php\/2025\/05\/07\/retrieval-augmented-classification-improving-text-classification-with-external-knowledge\/","title":{"rendered":"Retrieval Augmented Classification: Improving Text Classification with External Knowledge"},"content":{"rendered":"<p>    Retrieval Augmented Classification: Improving Text Classification with External Knowledge<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n    <!-- no image --><br \/>\n \t<BR><br \/>\n<BR><\/BR><\/p>\n<div>\n<p class=\"wp-block-paragraph\"><mdspan datatext=\"el1746589026776\" class=\"mdspan-comment\">Text<\/mdspan> <a href=\"https:\/\/towardsdatascience.com\/tag\/classification\/\" title=\"Classification\">Classification<\/a> stands as one of the most basic yet most important applications of natural language processing. It has a vital role in many real-world applications that go from filtering unwanted emails like spam, detecting product categories or classifying user intent in a chat-bot application. The default way of building text classifiers is to gather large amounts of labeled data, meaning input texts and their corresponding labels, and then training a custom Machine Learning model. Things changed a bit as LLMs became more powerful, where you can often get decent performance by using general purpose large language models as zero-shot or few-shot classifiers, significantly reducing the time-to-deployment of text classification services. However, the accuracy can lag behind custom built models and is highly dependent on crafting custom prompts to better define the classification task to the LLM. In this blog, we aim at minimizing the gap between custom ML models for classification and general purpose LLMs while also minimizing the effort needed in adapting the LLM prompt to your task.<\/p>\n<h2 class=\"wp-block-heading\">LLMs vs Custom ML models for text classification<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Pros:<\/strong><\/p>\n<p class=\"wp-block-paragraph\">Let\u2019s first explore the pro and cons of each of the two approaches to do text classification.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Large language models as general purpose classifiers:<\/strong><\/p>\n<ol class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">High generalization ability given the vast pre-training corpus and reasoning abilities of the LLM.<\/li>\n<li class=\"wp-block-list-item\">A single general purpose LLM can handle multiple classifications tasks without the need to deploy a model for each.<\/li>\n<li class=\"wp-block-list-item\">As <a href=\"https:\/\/towardsdatascience.com\/tag\/llms\/\" title=\"Llms\">Llms<\/a> continue to improve, you can potentially enhance accuracy with minimal effort simply by adopting newer, more powerful models as they become available.<\/li>\n<li class=\"wp-block-list-item\">The availability of most LLMs as managed services significantly reduces the deployment knowledge and effort required to get started.<\/li>\n<li class=\"wp-block-list-item\">LLMs often outperform custom ML models in low-data scenarios where labeled data is limited or costly to obtain.<\/li>\n<li class=\"wp-block-list-item\">LLMs generalize to multiple languages.<\/li>\n<li class=\"wp-block-list-item\">LLMs can be cheaper when having low or unpredictable volumes of predictions if you pay per token.<\/li>\n<li class=\"wp-block-list-item\">Class definitions can be changed dynamically without retraining by simply modifying the prompts.<\/li>\n<\/ol>\n<p class=\"wp-block-paragraph\"><strong>Cons:<\/strong><\/p>\n<ol class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">LLMs are prone to hallucinations.<\/li>\n<li class=\"wp-block-list-item\">LLMs can be slow, or at least slower than small custom ML models.<\/li>\n<li class=\"wp-block-list-item\">They require prompt engineering effort.<\/li>\n<li class=\"wp-block-list-item\">High-throughput applications using LLMs-as-a-service may quickly encounter quota limitations.<\/li>\n<li class=\"wp-block-list-item\">This approach becomes less effective with a very large number of potential classes due to context size constraints. Defining all the classes would consume a significant portion of the available and effective input context.<\/li>\n<li class=\"wp-block-list-item\">LLMs usually have worse accuracy than custom models in the high data regime.<\/li>\n<\/ol>\n<p class=\"wp-block-paragraph\"><strong>Custom <a href=\"https:\/\/towardsdatascience.com\/tag\/machine-learning\/\" title=\"Machine Learning\">Machine Learning<\/a> models:<\/strong><\/p>\n<p class=\"wp-block-paragraph\"><strong>Pros:<\/strong><\/p>\n<ol class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Efficient and fast.<\/li>\n<li class=\"wp-block-list-item\">More flexible in architecture choice, training and serving method.<\/li>\n<li class=\"wp-block-list-item\">Ability to add interpretability and uncertainty estimation aspects to the model.<\/li>\n<li class=\"wp-block-list-item\">Higher accuracy in the high data regime.<\/li>\n<li class=\"wp-block-list-item\">You keep control of your model and serving infrastructure.<\/li>\n<\/ol>\n<p class=\"wp-block-paragraph\"><strong>Cons:<\/strong><\/p>\n<ol class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Requires frequent re-trainings to adapt to new data or distribution changes.<\/li>\n<li class=\"wp-block-list-item\">May need significant amounts of labeled data.<\/li>\n<li class=\"wp-block-list-item\">Limited generalization.<\/li>\n<li class=\"wp-block-list-item\">Sensitive to out-of-domain vocabulary or formulations.<\/li>\n<li class=\"wp-block-list-item\">Requires MLOps knowledge for deployment.<\/li>\n<\/ol>\n<h2 class=\"wp-block-heading\">Bridging the gap between custom text classifier and LLMs:<\/h2>\n<p class=\"wp-block-paragraph\">Let\u2019s work on a way to keep the pros of using LLMs for classification while alleviating some of the cons. We will take inspiration from RAG and use a prompting technique called few-shot prompting.<\/p>\n<p class=\"wp-block-paragraph\">Let\u2019s define both:<\/p>\n<p class=\"wp-block-paragraph\"><strong>RAG<\/strong><\/p>\n<p class=\"wp-block-paragraph\">Retrieval Augmented Generation is a popular method that augments the LLM context with external knowledge before asking a question. This reduces the likelihood of hallucination and improves the quality of the responses.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Few-shot prompting<\/strong><\/p>\n<p class=\"wp-block-paragraph\">In each classification task, we show the LLM examples of inputs and expected outputs as part of the prompt to help it understand the task.<\/p>\n<p class=\"wp-block-paragraph\">Now, the main idea of this project is mixing both. We dynamically fetch examples that are the most similar to the text query to be classified and inject them as few-shot example prompts. We also limit the scope of possible classes dynamically using those of the K-nearest neighbors. This frees up a significant amount of tokens in the input context when working with a classification problem with a large number of possible classes.<\/p>\n<p class=\"wp-block-paragraph\">Here is how that would work:<\/p>\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXegGN0nUJOjBpN431umzXQoCuHGcsDP9bjg1leOK3YmK_bmaL0U-sSs-Z_5yKP_jcnZerVvIYjkLhvVzxzkhnQPK5vxE0tNLXQMp5YzJEZmKWKoiEJNsqKjuUv1pl_R7xBkW1FWcQ?key=7bn2d-D6uELdmrql8Yks9-6l\"><\/a><a href=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXegGN0nUJOjBpN431umzXQoCuHGcsDP9bjg1leOK3YmK_bmaL0U-sSs-Z_5yKP_jcnZerVvIYjkLhvVzxzkhnQPK5vxE0tNLXQMp5YzJEZmKWKoiEJNsqKjuUv1pl_R7xBkW1FWcQ?key=7bn2d-D6uELdmrql8Yks9-6l\"><\/a><\/p>\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/05\/mermaid-diagram-2025-05-03-214217.png?ssl=1\" alt=\"\" class=\"wp-image-603317\"><\/figure>\n<p class=\"wp-block-paragraph\">Let\u2019s go through the practical steps of getting this approach to run:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Building a knowledge base of labeled input text \/ category pairs. This will be our source of external knowledge for the LLM. We will be using ChromaDB.<\/li>\n<\/ul>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-julia\">from typing import List\nfrom uuid import uuid4\n\nfrom langchain_core.documents import Document\nfrom chromadb import PersistentClient\nfrom langchain_chroma import Chroma\nfrom langchain_community.embeddings import HuggingFaceBgeEmbeddings\nimport torch\nfrom tqdm import tqdm\nfrom chromadb.config import Settings\nfrom retrieval_augmented_classification.logger import logger\n\n\nclass DatasetVectorStore:\n    \"\"\"ChromaDB vector store for PublicationModel objects with SentenceTransformers embeddings.\"\"\"\n\n    def __init__(\n        self,\n        db_name: str = \"retrieval_augmented_classification\",  # Using db_name as collection name in Chroma\n        collection_name: str = \"classification_dataset\",\n        persist_directory: str = \"chroma_db\",  # Directory to persist ChromaDB\n    ):\n        self.db_name = db_name\n        self.collection_name = collection_name\n        self.persist_directory = persist_directory\n\n        # Determine if CUDA is available\n        device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n        logger.info(f\"Using device: {device}\")\n\n        self.embeddings = HuggingFaceBgeEmbeddings(\n            model_name=\"BAAI\/bge-small-en-v1.5\",\n            model_kwargs={\"device\": device},\n            encode_kwargs={\n                \"device\": device,\n                \"batch_size\": 100,\n            },  # Adjust batch_size as needed\n        )\n\n        # Initialize Chroma vector store\n        self.client = PersistentClient(\n            path=self.persist_directory, settings=Settings(anonymized_telemetry=False)\n        )\n        self.vector_store = Chroma(\n            client=self.client,\n            collection_name=self.collection_name,\n            embedding_function=self.embeddings,\n            persist_directory=self.persist_directory,\n        )\n\n    def add_documents(self, documents: List) -&gt; None:\n        \"\"\"\n        Add multiple documents to the vector store.\n\n        Args:\n            documents: List of dictionaries containing document data.  Each dict needs a \"text\" key.\n        \"\"\"\n\n        local_documents = []\n        ids = []\n\n        for doc_data in documents:\n            if not doc_data.get(\"id\"):\n                doc_data[\"id\"] = str(uuid4())\n\n            local_documents.append(\n                Document(\n                    page_content=doc_data[\"text\"],\n                    metadata={k: v for k, v in doc_data.items() if k != \"text\"},\n                )\n            )\n            ids.append(doc_data[\"id\"])\n\n        batch_size = 100  # Adjust batch size as needed\n        for i in tqdm(range(0, len(documents), batch_size)):\n            batch_docs = local_documents[i : i + batch_size]\n            batch_ids = ids[i : i + batch_size]\n\n            # Chroma's add_documents doesn't directly support pre-defined IDs. Upsert instead.\n            self._upsert_batch(batch_docs, batch_ids)\n\n    def _upsert_batch(self, batch_docs: List[Document], batch_ids: List[str]):\n        \"\"\"Upsert a batch of documents into Chroma.  If the ID exists, it updates; otherwise, it creates.\"\"\"\n        texts = [doc.page_content for doc in batch_docs]\n        metadatas = [doc.metadata for doc in batch_docs]\n\n        self.vector_store.add_texts(texts=texts, metadatas=metadatas, ids=batch_ids)<\/code><\/pre>\n<p class=\"wp-block-paragraph\">This class handles creating a collection and embedding each document\u2019s before inserting it into the vector index. We use BAAI\/bge-small-en-v1.5 but any embedding model would work, even those available as-a-service from Gemini, OpenAI, or Nebius.<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Finding the K nearest neighbors for an input text<\/li>\n<\/ul>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-julia\">def search(self, query: str, k: int = 5) -&gt; List[Document]:\n    \"\"\"Search documents by semantic similarity.\"\"\"\n    results = self.vector_store.similarity_search(query, k=k)\n    return results<\/code><\/pre>\n<p class=\"wp-block-paragraph\">This method returns the documents in the vector database that are most similar to our input.<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Building the Retrieval Augmented Classifier<\/li>\n<\/ul>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-julia\">from typing import Optional\nfrom pydantic import BaseModel, Field\nfrom collections import Counter\n\nfrom retrieval_augmented_classification.vector_store import DatasetVectorStore\nfrom tenacity import retry, stop_after_attempt, wait_exponential\nfrom langchain_core.messages import AIMessage, HumanMessage, SystemMessage\n\n\nclass PredictedCategories(BaseModel):\n    \"\"\"\n    Pydantic model for the predicted categories from the LLM.\n    \"\"\"\n\n    reasoning: str = Field(description=\"Explain your reasoning\")\n    predicted_category: str = Field(description=\"Category\")\n\n\nclass RAC:\n    \"\"\"\n    A hybrid classifier combining K-Nearest Neighbors retrieval with an LLM for multi-class prediction.\n    Finds top K neighbors, uses top few-shot for context, and uses all neighbor categories\n    as potential prediction candidates for the LLM.\n    \"\"\"\n\n    def __init__(\n        self,\n        vector_store: DatasetVectorStore,\n        llm_client,\n        knn_k_search: int = 30,\n        knn_k_few_shot: int = 5,\n    ):\n        \"\"\"\n        Initializes the classifier.\n\n        Args:\n            vector_store: An instance of DatasetVectorStore with a search method.\n            llm_client: An instance of the LLM client capable of structured output.\n            knn_k_search: The number of nearest neighbors to retrieve from the vector store.\n            knn_k_few_shot: The number of top neighbors to use as few-shot examples for the LLM.\n                           Must be less than or equal to knn_k_search.\n        \"\"\"\n\n        self.vector_store = vector_store\n        self.llm_client = llm_client\n        self.knn_k_search = knn_k_search\n        self.knn_k_few_shot = knn_k_few_shot\n\n    @retry(\n        stop=stop_after_attempt(3),  # Retry LLM call a few times\n        wait=wait_exponential(multiplier=1, min=2, max=5),  # Shorter waits for demo\n    )\n    def predict(self, document_text: str) -&gt; Optional[str]:\n        \"\"\"\n        Predicts the relevant categories for a given document text using KNN retrieval and an LLM.\n\n        Args:\n            document_text: The text content of the document to classify.\n\n        Returns:\n            The predicted category\n        \"\"\"\n        neighbors = self.vector_store.search(document_text, k=self.knn_k_search)\n\n        all_neighbor_categories = set()\n        valid_neighbors = []  # Store neighbors that have metadata and categories\n        for neighbor in neighbors:\n            if (\n                hasattr(neighbor, \"metadata\")\n                and isinstance(neighbor.metadata, dict)\n                and \"category\" in neighbor.metadata\n            ):\n                all_neighbor_categories.add(neighbor.metadata[\"category\"])\n                valid_neighbors.append(neighbor)\n            else:\n                pass  # Suppress warnings for cleaner demo output\n\n        if not valid_neighbors:\n            return None\n\n        category_counts = Counter(all_neighbor_categories)\n        ranked_categories = [\n            category for category, count in category_counts.most_common()\n        ]\n\n        if not ranked_categories:\n            return None\n\n        few_shot_neighbors = valid_neighbors[: self.knn_k_few_shot]\n\n        messages = []\n\n        system_prompt = f\"\"\"You are an expert multi-class classifier. Your task is to analyze the provided document text and assign the most relevant category from the list of allowed categories.\nYou MUST only return categories that are present in the following list: {ranked_categories}.\nIf none of the allowed categories are relevant, return an empty list.\nReturn the categories by likelihood (more confident to least confident).\nOutput your prediction as a JSON object matching the Pydantic schema: {PredictedCategories.model_json_schema()}.\n\"\"\"\n        messages.append(SystemMessage(content=system_prompt))\n\n        for i, neighbor in enumerate(few_shot_neighbors):\n            messages.append(\n                HumanMessage(content=f\"Document: {neighbor.page_content}\")\n            )\n            expected_output_json = PredictedCategories(\n                reasoning=\"Your reasoning here\",\n                predicted_category=neighbor.metadata[\"category\"]\n            ).model_dump_json()\n            # Simulate the structure often used with tool calling\/structured output\n\n            ai_message_with_tool = AIMessage(\n                content=expected_output_json,\n            )\n\n            messages.append(ai_message_with_tool)\n\n        # Final user message: The document text to classify\n        messages.append(HumanMessage(content=f\"Document: {document_text}\"))\n\n        # Configure the client for structured output with the Pydantic schema\n        structured_client = self.llm_client.with_structured_output(PredictedCategories)\n        llm_response: PredictedCategories = structured_client.invoke(messages)\n\n        predicted_category = llm_response.predicted_category\n\n        return predicted_category if predicted_category in ranked_categories else None<\/code><\/pre>\n<p class=\"wp-block-paragraph\">The first part of the code defines the structure of the output we expect from the LLM. The Pydantic class has two fields, the reasoning, used for chain-of-though prompting (<a href=\"https:\/\/www.promptingguide.ai\/techniques\/cot\">https:\/\/www.promptingguide.ai\/techniques\/cot<\/a>) and the predicted category.<\/p>\n<p class=\"wp-block-paragraph\">The predict method first finds the K nearest neighbors and uses them as few-shot prompts by creating a synthetic message history as if the LLM gave the correct categories for each of the KNN, then we inject the query text as the last human message.<\/p>\n<p class=\"wp-block-paragraph\">We filter the value to check if it is valid and if so, return it.<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Example prediction:<\/li>\n<\/ul>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-julia\">_rac = RAC(\n    vector_store=store,\n    llm_client=llm_client,\n    knn_k_search=50,\n    knn_k_few_shot=10,\n)\nprint(\n    f\"Initialized rac with knn_k_search={_rac.knn_k_search}, knn_k_few_shot={_rac.knn_k_few_shot}.\"\n)\n\ntext = \"\"\"Ivanoe Bonomi [i\u02c8va\u02d0noe bo\u02c8n\u0254\u02d0mi] (18 October 1873 \u2013 20 April 1951) was an Italian politician and statesman before and after World War II. Bonomi was born in Mantua. He was elected to the Italian Chamber of Deputies in ...\n\"\"\"\ncategory = _rac.predict(text)\n\nprint(text)\nprint(category)\n\ntext = \"\"\"Michel Rocard, n\u00e9 le 23 ao\u00fbt 1930 \u00e0 Courbevoie et mort le 2 juillet 2016 \u00e0 Paris, est un haut fonctionnaire et ... \n\"\"\"\ncategory = _rac.predict(text)\n\nprint(text)\nprint(category)<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Both inputs return the prediction \u201cPrimeMinister\u201d even though the second example is in french while the training dataset is fully in English. This illustrates the generalization abilities of this approach even across similar languages.<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Evaluation:<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">We use the <strong>DBPedia Classes<\/strong> dataset\u2019s l3 categories (<a href=\"https:\/\/www.kaggle.com\/datasets\/danofer\/dbpedia-classes\">https:\/\/www.kaggle.com\/datasets\/danofer\/dbpedia-classes<\/a> ,License <a href=\"https:\/\/en.wikipedia.org\/wiki\/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License\">CC BY-SA 3.0<\/a>.) for our evaluation. This dataset has more than 200 categories and 240000 training samples.<\/p>\n<p class=\"wp-block-paragraph\">We benchmark the Retrieval Augmented Classification approach against a simple KNN classifier with majority vote and obtain the following results the DBpedia dataset\u2019s <strong>l3 categories<\/strong>:<\/p>\n<figure class=\"wp-block-table\">\n<table class=\"has-fixed-layout\">\n<tbody>\n<tr>\n<td><\/td>\n<td>Accuracy<\/td>\n<td>Average Latency<\/td>\n<td>Throughput (multi-threaded)<\/td>\n<\/tr>\n<tr>\n<td>KNN classifier<\/td>\n<td>87%<\/td>\n<td><strong>24ms<\/strong><\/td>\n<td>\n<strong>108<\/strong> predictions \/ s<\/td>\n<\/tr>\n<tr>\n<td>LLM only classifier<\/td>\n<td>88%<\/td>\n<td>~600ms<\/td>\n<td>47 predictions \/ s<\/td>\n<\/tr>\n<tr>\n<td>RAC<\/td>\n<td><strong>96%<\/strong><\/td>\n<td>~1s<\/td>\n<td>27 predictions \/ s<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p class=\"wp-block-paragraph\">By reference, the best accuracy I found on Kaggle notebooks for this dataset\u2019s l3 level was around <em>94%<\/em> using custom ML models.<\/p>\n<p class=\"wp-block-paragraph\">We note that combining a KNN search with the reasoning abilities of an LLM allows us to gain +9% accuracy points but comes at a cost of a lower throughput and higher latency.<\/p>\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n<p class=\"wp-block-paragraph\">In this project we built a text classifier that leverages \u201cretrieval\u201d to boost the ability of an LLM to find the correct category of the input content. This approach offers several advantages over traditional ML text classifiers. These include the ability to dynamically change the training dataset without retraining, a higher generalization ability due to the reasoning and general knowledge of LLMs, easy deployment when using managed LLM services compared to custom ML models, and the capability to handle multiple classification tasks with a single base LLM model. This comes at a cost of higher latency and lower throughput and a risk of LLM vendor lock-in.<\/p>\n<p class=\"wp-block-paragraph\">This method should not be your first go-to when working on a classification task but would still be useful as part of your toolbox when your application can benefit from the flexibility of not having to re-train a classifier every time the data changes or when working with a small amount of labeled data. It can also allow you to get a target of having a classification service up and running very quickly when a deadline is looming <img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f603.png?ssl=1\" alt=\"\ud83d\ude03\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\">.<\/p>\n<p class=\"wp-block-paragraph\">Sources:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><a href=\"https:\/\/aclanthology.org\/2023.findings-emnlp.447.pdf\">[1] G. Yu, L. Liu, H. Jiang, S. Shi and X. Ao, Retrieval-Augmented Few-shot Text Classification (2023), Findings of the Association for Computational Linguistics: EMNLP 2023<\/a><\/li>\n<li class=\"wp-block-list-item\"><a href=\"https:\/\/www.amazon.science\/publications\/retrieval-augmented-classification-for-long-tail-visual-recognition\">[2] A. Long, W. Yin, T. Ajanthan, V. Nguyen, P. Purkait, R. Garg, C. Shen and A. van den Hengel, Retrieval augmented classification for long-tail visual recognition (2022)<\/a><\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Code: <a href=\"https:\/\/github.com\/CVxTz\/retrieval_augmented_classification\">https:\/\/github.com\/CVxTz\/retrieval_augmented_classification<\/a><\/p>\n<p class=\"wp-block-paragraph\">\n<p>The post <a href=\"https:\/\/towardsdatascience.com\/retrieval-augmented-classification-improving-text-classification-with-external-knowledge\/\">Retrieval Augmented Classification: Improving Text Classification with External Knowledge<\/a> appeared first on <a href=\"https:\/\/towardsdatascience.com\/\">Towards Data Science<\/a>.<\/p>\n<\/div>\n<p> \t<BR><br \/>\n <BR><\/BR><br \/>\n    Youness MANSAR<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n<a href=\"https:\/\/towardsdatascience.com\/retrieval-augmented-classification-improving-text-classification-with-external-knowledge\/\">Go to original source<\/a><br \/>\n \t<BR><br \/>\n <BR><\/BR><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Retrieval Augmented Classification: Improving Text Classification with External Knowledge Text Classification stands as one of the most basic yet most important applications of natural language processing. It has a vital role in many real-world applications that go from filtering unwanted emails like spam, detecting product categories or classifying user intent in a chat-bot application. The [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62,837,83,71,1839,70,157],"tags":[1245,318,834],"class_list":["post-3628","post","type-post","status-publish","format-standard","hentry","category-aimldsaimlds","category-classification","category-data-science","category-large-language-models","category-llms","category-machine-learning","category-python","tag-classification","tag-llms","tag-text"],"_links":{"self":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/3628"}],"collection":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/comments?post=3628"}],"version-history":[{"count":0,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/3628\/revisions"}],"wp:attachment":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/media?parent=3628"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/categories?post=3628"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/tags?post=3628"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}