{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "520712d7-0867-492e-a7e5-388d91db9ba6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, re\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.naive_bayes import MultinomialNB\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.svm import LinearSVC\n",
    "from sklearn.metrics import accuracy_score, precision_recall_fscore_support, classification_report\n",
    "import joblib\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e1c3ae04-4748-4576-b8dd-c3173a88d4c6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train shape: (320, 2)\n",
      "Test shape: (80, 2)\n",
      "\n",
      "Train sample:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Disease</th>\n",
       "      <th>Symptoms</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Influenza</td>\n",
       "      <td>headache, exhaustion, coughing, pyrexia, runny...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Urinary Tract Infection</td>\n",
       "      <td>dysuria, lower abdominal pain, high temperatur...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Urinary Tract Infection</td>\n",
       "      <td>suprapubic pain, cloudy urine, burning urinati...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Strep Throat</td>\n",
       "      <td>cephalalgia, pyrexia, lymphadenopathy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Gastric Ulcer</td>\n",
       "      <td>epigastric pain, dyspepsia, queasiness, abdomi...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   Disease                                           Symptoms\n",
       "0                Influenza  headache, exhaustion, coughing, pyrexia, runny...\n",
       "1  Urinary Tract Infection  dysuria, lower abdominal pain, high temperatur...\n",
       "2  Urinary Tract Infection  suprapubic pain, cloudy urine, burning urinati...\n",
       "3             Strep Throat              cephalalgia, pyrexia, lymphadenopathy\n",
       "4            Gastric Ulcer  epigastric pain, dyspepsia, queasiness, abdomi..."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Test sample:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Disease</th>\n",
       "      <th>Symptoms</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Otitis Media</td>\n",
       "      <td>ear pain, hearing difficulty, irritability, ch...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Bronchitis</td>\n",
       "      <td>throat pain, chest discomfort, wheezing, cough</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Dermatitis</td>\n",
       "      <td>dizziness, erythema, pruritus, skin eruption</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Sinusitis</td>\n",
       "      <td>cough, maxillary pain, headache, purulent nasa...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Gastric Ulcer</td>\n",
       "      <td>indigestion, upper abdominal pain, abdominal d...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         Disease                                           Symptoms\n",
       "0   Otitis Media  ear pain, hearing difficulty, irritability, ch...\n",
       "1     Bronchitis     throat pain, chest discomfort, wheezing, cough\n",
       "2     Dermatitis       dizziness, erythema, pruritus, skin eruption\n",
       "3      Sinusitis  cough, maxillary pain, headache, purulent nasa...\n",
       "4  Gastric Ulcer  indigestion, upper abdominal pain, abdominal d..."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "\n",
    "TRAIN_PATH = r\"C:/Users/hp/Downloads/train.csv\"\n",
    "TEST_PATH  = r\"C:/Users/hp/Downloads/test.csv\"\n",
    "\n",
    "\n",
    "train_df = pd.read_csv(TRAIN_PATH)\n",
    "test_df  = pd.read_csv(TEST_PATH)\n",
    "\n",
    "\n",
    "print(\"Train shape:\", train_df.shape)\n",
    "print(\"Test shape:\", test_df.shape)\n",
    "\n",
    "\n",
    "print(\"\\nTrain sample:\")\n",
    "display(train_df.head())\n",
    "\n",
    "print(\"\\nTest sample:\")\n",
    "display(test_df.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5a9c8974-40dd-41de-a4de-a4059b33e511",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data cleaned successfully ✅\n"
     ]
    }
   ],
   "source": [
    "def clean_text(s: str) -> str:\n",
    "    if pd.isna(s): \n",
    "        return \"\"\n",
    "    s = str(s).lower()\n",
    "    s = re.sub(r\"[^\\w\\s,]\", \" \", s)    \n",
    "    s = re.sub(r\"\\s+\", \" \", s).strip()\n",
    "    toks = [t.strip() for t in s.split(\",\") if t.strip()]\n",
    "    seen, out = set(), []\n",
    "    for t in toks:\n",
    "        if t not in seen:\n",
    "            out.append(t)\n",
    "            seen.add(t)\n",
    "    return \", \".join(out)\n",
    "\n",
    "for df_ in (train_df, test_df):\n",
    "    df_[\"Symptoms\"] = df_[\"Symptoms\"].apply(clean_text)\n",
    "    df_[\"Disease\"] = df_[\"Disease\"].astype(str).str.strip()\n",
    "\n",
    "print(\"Data cleaned successfully ✅\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7ede8e40-8a68-4f4d-9511-572ed306ae2c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train shape: (320, 1047)\n",
      "X_test shape: (80, 1047)\n"
     ]
    }
   ],
   "source": [
    "vectorizer = TfidfVectorizer(ngram_range=(1,2), max_features=20000)\n",
    "X_train = vectorizer.fit_transform(train_df[\"Symptoms\"])\n",
    "X_test  = vectorizer.transform(test_df[\"Symptoms\"])\n",
    "\n",
    "print(\"X_train shape:\", X_train.shape)\n",
    "print(\"X_test shape:\", X_test.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "ed1eff62-d3e2-4b7e-b1b6-291dace2e75a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of disease classes: 20\n"
     ]
    }
   ],
   "source": [
    "le = LabelEncoder()\n",
    "y_train = le.fit_transform(train_df[\"Disease\"])\n",
    "y_test  = le.transform(test_df[\"Disease\"])\n",
    "\n",
    "print(\"Number of disease classes:\", len(le.classes_))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f904f000-87d6-4c1f-98a9-da7bdc354459",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Models trained successfully\n"
     ]
    }
   ],
   "source": [
    "logreg = LogisticRegression(max_iter=2000, solver=\"lbfgs\", random_state=42).fit(X_train, y_train)\n",
    "mnb    = MultinomialNB().fit(X_train, y_train)\n",
    "rf     = RandomForestClassifier(n_estimators=300, random_state=42, n_jobs=-1).fit(X_train, y_train)\n",
    "svc    = LinearSVC(random_state=42).fit(X_train, y_train)\n",
    "\n",
    "print(\"✅ Models trained successfully\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1abd4240-c341-44df-bc9d-b4e0eb28f893",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Accuracy</th>\n",
       "      <th>Precision</th>\n",
       "      <th>Recall</th>\n",
       "      <th>F1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Logistic Regression</th>\n",
       "      <td>0.9875</td>\n",
       "      <td>0.9900</td>\n",
       "      <td>0.9875</td>\n",
       "      <td>0.987302</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Multinomial Naive Bayes</th>\n",
       "      <td>0.9750</td>\n",
       "      <td>0.9800</td>\n",
       "      <td>0.9750</td>\n",
       "      <td>0.974603</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Linear SVC</th>\n",
       "      <td>0.9750</td>\n",
       "      <td>0.9800</td>\n",
       "      <td>0.9750</td>\n",
       "      <td>0.974603</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Random Forest</th>\n",
       "      <td>0.9625</td>\n",
       "      <td>0.9675</td>\n",
       "      <td>0.9625</td>\n",
       "      <td>0.962103</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         Accuracy  Precision  Recall        F1\n",
       "Logistic Regression        0.9875     0.9900  0.9875  0.987302\n",
       "Multinomial Naive Bayes    0.9750     0.9800  0.9750  0.974603\n",
       "Linear SVC                 0.9750     0.9800  0.9750  0.974603\n",
       "Random Forest              0.9625     0.9675  0.9625  0.962103"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def eval_model(model, X_te, y_te):\n",
    "    y_pred = model.predict(X_te)\n",
    "    acc = accuracy_score(y_te, y_pred)\n",
    "    prec, rec, f1, _ = precision_recall_fscore_support(y_te, y_pred, average=\"macro\", zero_division=0)\n",
    "    return acc, prec, rec, f1, y_pred\n",
    "\n",
    "scores = {}\n",
    "for name, model in {\n",
    "    \"Logistic Regression\": logreg,\n",
    "    \"Multinomial Naive Bayes\": mnb,\n",
    "    \"Random Forest\": rf,\n",
    "    \"Linear SVC\": svc\n",
    "}.items():\n",
    "    acc,p,r,f1,y_pred = eval_model(model, X_test, y_test)\n",
    "    scores[name] = (acc,p,r,f1)\n",
    "\n",
    "results_df = pd.DataFrame(scores, index=[\"Accuracy\",\"Precision\",\"Recall\",\"F1\"]).T\n",
    "results_df = results_df.sort_values(\"F1\", ascending=False)\n",
    "display(results_df)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "08000979-ec94-4437-9a98-ff4de38e89b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAHqCAYAAAAZLi26AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABk30lEQVR4nO3dd3QU1eP+8WfTG6EESAIkEAgl9BJUQDpSpas0KdLEKCjoR0GkKqKISJGiQBJEQUAQaVJEKQIiLYgQ6RCUIAJKlRQyvz/4Zb8uKYSQ2UDyfp2Tc9g7d+beGfbu7LPTLIZhGAIAAAAAAFnOIbs7AAAAAABATkXoBgAAAADAJIRuAAAAAABMQugGAAAAAMAkhG4AAAAAAExC6AYAAAAAwCSEbgAAAAAATELoBgAAAADAJIRuAAAAAABMQugGAFhFRkbKYrHIYrFo06ZNKaYbhqHg4GBZLBY1aNAgS9u2WCwaPXr0Pc936tQpWSwWRUZGZqhe8p+Dg4N8fHzUsmVL7dixI3OdTse0adMUHBwsFxcXWSwW/fPPP1neRm5z4sQJvfTSSypTpozc3d3l4eGhChUq6K233tIff/yR3d0z3ejRo2WxWLK7GwCAe0ToBgCkkCdPHs2dOzdF+ebNm3X8+HHlyZMnG3qVNQYOHKgdO3Zo69atGj9+vPbv36+GDRtq3759WdZGVFSUBg0apIYNG+r777/Xjh07Hupt9iBYtWqVKleurFWrVql///5atWqV9d8rV67Uk08+md1dNF3fvn1N+YEIAGAup+zuAADgwdOpUyd98cUXmj59ury9va3lc+fOVa1atXTlypVs7N39CQwM1GOPPSZJqlOnjoKDg9W4cWPNmDFDs2fPvq9l37hxQx4eHjp48KAkqV+/fnrkkUfuu8//XXZudPLkSXXu3FllypTRDz/8oLx581qnNWrUSIMGDdLXX3+djT00V/L/fbFixVSsWLHs7g4A4B5xpBsAkEKXLl0kSQsXLrSWXb58WUuXLlXv3r1TnefSpUsKCwtT0aJF5eLiopIlS2r48OGKi4uzqXflyhX169dPPj4+8vLyUvPmzXXkyJFUl3n06FF17dpVhQsXlqurq0JCQjR9+vQsWsvbkgP46dOnrWXfffedGjduLG9vb3l4eKhOnTrauHGjzXzJp/ru3btXTz31lPLnz69SpUqpQYMGevbZZyVJjz76qCwWi3r16mWdLzw8XFWqVJGbm5sKFCig9u3bKzo62mbZvXr1kpeXlw4cOKCmTZsqT548aty4saTbp+G/9NJLioiIUNmyZeXu7q7Q0FD99NNPMgxDH3zwgYKCguTl5aVGjRrp2LFjNsvesGGD2rZtq2LFisnNzU3BwcF6/vnndeHChVTX7+DBg+rSpYvy5s0rX19f9e7dW5cvX7apm5SUpGnTpqlq1apyd3dXvnz59Nhjj2nFihU29RYtWqRatWrJ09NTXl5eatasWYbOMJg0aZKuX7+uGTNm2ATuZBaLRR06dLApu5ft/Ntvv6lZs2by9PSUv7+/3nvvPUnSTz/9pMcff1yenp4qU6aM5s2bZzN/8uUYGzZs0HPPPacCBQrI09NTrVu31okTJ+5ru9/5vvrvtP/6/vvv1aBBA/n4+Mjd3V2BgYHq2LGjbty4Ya2T0bGZ/N6aP3++QkJC5OHhoSpVqmjVqlVp/t8AAO6O0A0ASMHb21tPPfWUwsPDrWULFy6Ug4ODOnXqlKL+zZs31bBhQ3322WcaMmSIVq9erWeffVYTJkywCUOGYahdu3aaP3++Xn31VX399dd67LHH1KJFixTLPHTokGrWrKlff/1VH374oVatWqVWrVpp0KBBGjNmTJata3IoLVSokCTp888/V9OmTeXt7a158+Zp8eLFKlCggJo1a5YieEtShw4dFBwcrCVLlmjWrFmaMWOG3nrrLUlSRESEduzYoREjRkiSxo8frz59+qhChQpatmyZpkyZol9++UW1atXS0aNHbZYbHx+vNm3aqFGjRvrmm29s1nnVqlWaM2eO3nvvPS1cuFBXr15Vq1at9Oqrr2rbtm36+OOP9emnn+rQoUPq2LGjDMOwznv8+HHVqlVLM2fO1Pr16zVy5Ejt3LlTjz/+uBISElKsX8eOHVWmTBktXbpUQ4cO1YIFCzR48GCbOr169dLLL7+smjVratGiRfryyy/Vpk0bnTp1ylrn3XffVZcuXVS+fHktXrxY8+fP19WrV1W3bl0dOnQo3f+j9evXy9fX1/oDyd3cy3ZOSEhQhw4d1KpVK33zzTdq0aKFhg0bpjfffFM9e/ZU79699fXXX6ts2bLq1auX9uzZk6K9Pn36yMHBQQsWLNDkyZP1888/q0GDBjbX8d/rdr/zfZWaU6dOqVWrVnJxcVF4eLjWrl2r9957T56enoqPj5eU8bGZbPXq1fr44481duxYLV261PqDxZ0/IgAA7oEBAMD/FxERYUgydu3aZfzwww+GJOPXX381DMMwatasafTq1cswDMOoUKGCUb9+fet8s2bNMiQZixcvtlne+++/b0gy1q9fbxiGYXz77beGJGPKlCk29caNG2dIMkaNGmUta9asmVGsWDHj8uXLNnVfeuklw83Nzbh06ZJhGIZx8uRJQ5IRERGR7rol13v//feNhIQE4+bNm8aePXuMmjVrGpKM1atXG9evXzcKFChgtG7d2mbeW7duGVWqVDEeeeQRa9moUaMMScbIkSPT3Y7J/v77b8Pd3d1o2bKlTd2YmBjD1dXV6Nq1q7WsZ8+ehiQjPDw8xbIlGX5+fsa1a9esZcuXLzckGVWrVjWSkpKs5ZMnTzYkGb/88kuq2yQpKclISEgwTp8+bUgyvvnmmxTrN2HCBJt5wsLCDDc3N2s7W7ZsMSQZw4cPT7WN5HV0cnIyBg4caFN+9epVw8/Pz3jmmWfSnNcwDMPNzc147LHH0q2TLDPbeenSpdayhIQEo1ChQoYkY+/evdbyixcvGo6OjsaQIUOsZcn/z+3bt7dpa9u2bYYk45133km1jxnZ7qm9r5KnJfvqq68MSUZUVFSa2yOjY9Mwbr+3fH19jStXrljLzp07Zzg4OBjjx49Psw0AQPo40g0ASFX9+vVVqlQphYeH68CBA9q1a1eap5Z///338vT01FNPPWVTnnxadfIR4h9++EGS1K1bN5t6Xbt2tXl98+ZNbdy4Ue3bt5eHh4cSExOtfy1bttTNmzf1008/ZWq93njjDTk7O8vNzU01atRQTEyMPvnkE7Vs2VLbt2/XpUuX1LNnT5s2k5KS1Lx5c+3atUvXr1+3WV7Hjh0z1O6OHTv077//2pxqLkkBAQFq1KhRqkfR01p2w4YN5enpaX0dEhIiSWrRooXN6cfJ5f89df78+fMaMGCAAgIC5OTkJGdnZxUvXlySUpx+LUlt2rSxeV25cmXdvHlT58+flyR9++23kqQXX3wx9RWXtG7dOiUmJqpHjx4229XNzU3169dP9U75mXWv29lisahly5bW105OTgoODpa/v7+qVatmLS9QoIAKFy5ssy2T3fl+rl27tooXL259v0v3vt0z8r6qWrWqXFxc1L9/f82bNy/Vo9EZHZvJGjZsaHPTP19f3zTXGwCQMdxIDQCQKovFoueee05Tp07VzZs3VaZMGdWtWzfVuhcvXpSfn1+K600LFy4sJycnXbx40VrPyclJPj4+NvX8/PxSLC8xMVHTpk3TtGnTUm3zzmthM+rll1/Ws88+KwcHB+XLl09BQUHWfv/555+SlCKg/NelS5dsAq+/v3+G2k3eBqnVL1KkiDZs2GBT5uHhYXMTu/8qUKCAzWsXF5d0y2/evCnp9rXXTZs21dmzZzVixAhVqlRJnp6eSkpK0mOPPaZ///03RVt3/l+5urpKkrXuX3/9JUdHxxT/h/+VvF1r1qyZ6nQHh/SPAQQGBurkyZPp1kmWme3s5uZmU+bi4pJiWyaXJ2/L/0pt3f38/Kx9ycx2z8j7qlSpUvruu+80YcIEvfjii7p+/bpKliypQYMG6eWXX5aU8bGZ7M7/b+n2/3lqfQQAZAyhGwCQpl69emnkyJGaNWuWxo0bl2Y9Hx8f7dy5U4Zh2Hy5P3/+vBITE1WwYEFrvcTERF28eNHmy/25c+dslpc/f345Ojqqe/fuaR5BDQoKytQ6FStWTKGhoalOS+7ntGnT0rx+2NfX1+Z1Rp+bnLy+sbGxKaadPXvW2va9Lvde/Prrr9q/f78iIyPVs2dPa/mdN1u7F4UKFdKtW7d07ty5NINi8rp99dVX1qO796JZs2aaNm2afvrpp7te132v2zkr3Pn+TS4LDg6WlLntntH//7p166pu3bq6deuWdu/erWnTpumVV16Rr6+vOnfunOGxCQAwD6eXAwDSVLRoUf3vf/9T69atbcLCnRo3bqxr165p+fLlNuWfffaZdbp0+9RVSfriiy9s6i1YsMDmtYeHh/XZ2ZUrV1ZoaGiKv9SOyN2vOnXqKF++fDp06FCqbYaGhlqPHt+rWrVqyd3dXZ9//rlN+e+//67vv//euo3MlBy6ko9WJ/vkk08yvczkm+DNnDkzzTrNmjWTk5OTjh8/nuZ2Tc/gwYPl6empsLCwFHdOl27foC/5kWHZsZ3vfD9v375dp0+fVoMGDSSZs93v5OjoqEcffdR6d/+9e/dKyvjYBACYhyPdAIB0JT8+KT09evTQ9OnT1bNnT506dUqVKlXSjz/+qHfffVctW7ZUkyZNJElNmzZVvXr19Prrr+v69esKDQ3Vtm3bNH/+/BTLnDJlih5//HHVrVtXL7zwgkqUKKGrV6/q2LFjWrlypb7//vssX1cvLy9NmzZNPXv21KVLl/TUU0+pcOHC+uuvv7R//3799ddf6YbL9OTLl08jRozQm2++qR49eqhLly66ePGixowZIzc3N40aNSqL1yalcuXKqVSpUho6dKgMw1CBAgW0cuXKFKdc34u6deuqe/fueuedd/Tnn3/qySeflKurq/bt2ycPDw8NHDhQJUqU0NixYzV8+HCdOHFCzZs3V/78+fXnn3/q559/lqenZ7p3pA8KCtKXX36pTp06qWrVqnrppZes11sfOnRI4eHhMgxD7du3z5btvHv3bvXt21dPP/20zpw5o+HDh6to0aIKCwuTZM52l6RZs2bp+++/V6tWrRQYGKibN29anziQPOYyOjYBAOYhdAMA7pubm5t++OEHDR8+XB988IH++usvFS1aVK+99ppNyHFwcNCKFSs0ZMgQTZgwQfHx8apTp47WrFmjcuXK2SyzfPny2rt3r95++2299dZbOn/+vPLly6fSpUvb3Pgqqz377LMKDAzUhAkT9Pzzz+vq1asqXLiwqlatmuLmXPdq2LBhKly4sKZOnapFixbJ3d1dDRo00LvvvqvSpUtnzQqkw9nZWStXrtTLL7+s559/Xk5OTmrSpIm+++47BQYGZnq5kZGRql69uubOnavIyEi5u7urfPnyevPNN611hg0bpvLly2vKlClauHCh4uLi5Ofnp5o1a2rAgAF3bePJJ5/UgQMH9OGHH2rWrFk6c+aMHBwcFBQUpObNm2vgwIE2bdlzO8+dO1fz589X586dFRcXp4YNG2rKlCnW68LN2u5Vq1bV+vXrNWrUKJ07d05eXl6qWLGiVqxYoaZNm0rK+NgEAJjHYhj/eXgnAAAAMiQyMlLPPfecdu3adddT5AEAuRfXdAMAAAAAYBJCNwAAAAAAJuH0cgAAAAAATMKRbgAAAAAATELoBgAAAADAJIRuAAAAAABMkuue052UlKSzZ88qT548slgs2d0dAAAAAMBDyDAMXb16VUWKFJGDQ9rHs3Nd6D579qwCAgKyuxsAAAAAgBzgzJkzKlasWJrTc13ozpMnj6TbG8bb2zubewMAAAAAeBhduXJFAQEB1oyZllwXupNPKff29iZ0AwAAAADuy90uW+ZGagAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJ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AUm3Pwxu3bqV7vyVK1fWxo0b72PNpMGDB2v//v3WLxTVq1fXwYMHbT6Ikv9cXFxUrlw5JSYm2nzhP3bsWIae+1u9enUdPnw41WUn/0KZ3jZxcnJSkyZNNGHCBP3yyy/Wa4PuVL58eSUmJmrnzp3WsosXL+rIkSMKCQm5n82Fe5B8HVN8fLyaNWuWap1ChQrZ/NJ75coV65Gm1CT/qny3sXE35cuXV0xMjM6cOWMtO3TokC5fvpyl75Ft27apePHiGj58uEJDQ1W6dGmdPn36vpb5yCOPqEOHDjZHjSXpt99+04ULF/Tee++pbt26KleuXIbO3OjWrZvWrl2rgwcP6ocfflC3bt2s06pXr66jR4+qcOHCKcbsvT52zNHRUYmJidYvalu3btWgQYPUsmVLVahQQa6urrpw4YLNPD4+PmrXrp0iIiIUERGh5557zjqtfPnycnV1VUxMTIq+/fdISaFChdSrVy99/vnnmjx5sj799NN76jdynrvt5zI7ljIqf/788vf3t7lxW548efT0008rIiJC4eHhKlmypPXounT7BpPly5fXhx9+mGqYyMg+GMiIUaNGaeLEiTp79qyk25/VtWvXVlhYmKpVq6bg4OC7nul0p5CQECUmJto82u7w4cM271t77Zfvpnz58oqKirIZn9u2bZODg4P1x6/UZHR/Wa1aNQ0bNkzbt29XxYoVrT96Z+R7P/4Pofshd/ny5RS/UMXExCgsLExnzpzRwIED9dtvv+mbb77RqFGjNGTIEDk4OChPnjzq2bOn/ve//+mHH37QwYMH1bt3bzk4OKT5a1lkZKTmzp2rX3/9VSdOnND8+fPl7u6u4sWLS7p9+syWLVv0xx9/pPgimmzUqFFauHChRo0apejoaB04cEATJky4p3X29vZW3759NWrUKBmGoTfeeEM7duzQiy++qKioKB09elQrVqywnmpUrlw5NWnSRP3799fPP/+sffv2qX///nJ3d7/raW8jR47UZ599ptGjR+vgwYOKjo7WokWL9NZbb911m6xatUpTp05VVFSUTp8+rc8++0xJSUmpnsJfunRptW3bVv369dOPP/6o/fv369lnn1XRokXVtm3be9o+yDxHR0dFR0crOjra5pSz/2rUqJHmz5+vrVu36tdff1XPnj3TrCtJhQsXtt5x+88//9Tly5cz1bcmTZqocuXK6tat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",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = results_df[[\"Accuracy\",\"Precision\",\"Recall\",\"F1\"]].plot(kind=\"bar\", figsize=(10,5))\n",
    "ax.set_title(\"Model Performance Comparison\")\n",
    "ax.set_ylabel(\"Score\")\n",
    "ax.set_xlabel(\"Model\")\n",
    "ax.grid(axis=\"y\")\n",
    "plt.xticks(rotation=0)\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "50786ca8-7215-48c1-839f-635dc29bb612",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🏆 Best model: Logistic Regression\n",
      "✅ Files saved: best_model.pkl | vectorizer_tfidf.pkl | label_encoder.pkl\n"
     ]
    }
   ],
   "source": [
    "best_model_name = results_df[\"F1\"].idxmax()\n",
    "best_model = {\n",
    "    \"Logistic Regression\": logreg,\n",
    "    \"Multinomial Naive Bayes\": mnb,\n",
    "    \"Random Forest\": rf,\n",
    "    \"Linear SVC\": svc\n",
    "}[best_model_name]\n",
    "\n",
    "joblib.dump(best_model, \"best_model.pkl\")\n",
    "joblib.dump(vectorizer,  \"vectorizer_tfidf.pkl\")\n",
    "joblib.dump(le,          \"label_encoder.pkl\")\n",
    "\n",
    "print(\"🏆 Best model:\", best_model_name)\n",
    "print(\"✅ Files saved: best_model.pkl | vectorizer_tfidf.pkl | label_encoder.pkl\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3ce60748-d51a-46d1-b132-c002abfe5786",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predicted disease: Influenza\n"
     ]
    }
   ],
   "source": [
    "new_symptoms = [\"fever, cough, sore throat, headache\"]\n",
    "X_new = vectorizer.transform(new_symptoms)\n",
    "pred_id = best_model.predict(X_new)[0]\n",
    "predicted_disease = le.inverse_transform([pred_id])[0]\n",
    "print(\"Predicted disease:\", predicted_disease)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b8b1bf52-2962-4979-9faa-1898bad53e3a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
