{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ***Setup***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "from nltk.stem import WordNetLemmatizer\n",
    "from nltk.corpus import wordnet\n",
    "from nltk.tokenize import word_tokenize\n",
    "from nltk import pos_tag\n",
    "from nltk.corpus import stopwords\n",
    "\n",
    "\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.feature_selection import SelectKBest, chi2, f_classif\n",
    "from sklearn.naive_bayes import MultinomialNB\n",
    "from sklearn.metrics import accuracy_score, classification_report\n",
    "\n",
    "from tabulate import tabulate\n",
    "\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "import os\n",
    "parent_dir = os.path.abspath('..')\n",
    "sys.path.append(parent_dir)\n",
    "from constants import CONSTANTS\n",
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***Some helper functions***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "lemmatizer = WordNetLemmatizer()\n",
    "\n",
    "# Function to get wordnet POS tag\n",
    "def get_wordnet_pos(tag):\n",
    "    if tag.startswith('J'):\n",
    "        return wordnet.ADJ\n",
    "    elif tag.startswith('V'):\n",
    "        return wordnet.VERB\n",
    "    elif tag.startswith('N'):\n",
    "        return wordnet.NOUN\n",
    "    elif tag.startswith('R'):\n",
    "        return wordnet.ADV\n",
    "    else:\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def lemmatize_text_with_filter(text, filter = None):\n",
    "    tokens = word_tokenize(text)\n",
    "    pos_tags = pos_tag(tokens)\n",
    "    lemmatized_tokens = []\n",
    "    for word, tag in pos_tags:\n",
    "        wordnet_pos = get_wordnet_pos(tag) or wordnet.NOUN\n",
    "        if filter:\n",
    "            if wordnet_pos == filter:  # Extract with filter only\n",
    "                lemma = lemmatizer.lemmatize(word, pos=wordnet_pos)\n",
    "                lemmatized_tokens.append(lemma)\n",
    "        else:\n",
    "            lemma = lemmatizer.lemmatize(word, pos=wordnet_pos)\n",
    "            lemmatized_tokens.append(lemma)\n",
    "    return \" \".join(lemmatized_tokens)\n",
    "\n",
    "def create_lemmatizer_with_filter(filter):\n",
    "    def lemmatizer_with_filter(text):\n",
    "        return lemmatize_text_with_filter(text, filter)\n",
    "    return lemmatizer_with_filter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "stop_words = set(stopwords.words('english'))\n",
    "\n",
    "def remove_stopwords(text):\n",
    "    tokens = word_tokenize(text)  # Tokenize the text\n",
    "    filtered_tokens = [word for word in tokens if word not in stop_words]  # Remove stop words\n",
    "    return ' '.join(filtered_tokens)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_clf_report_as_table(report):\n",
    "    data = []\n",
    "    for key, value in report.items():\n",
    "        if key != 'accuracy' and key != 'macro avg' and key != 'weighted avg':\n",
    "            data.append([key, value['precision'], value['recall'], value['f1-score'], value['support']])\n",
    "\n",
    "    data.append(['accuracy', '', '', report['accuracy'], ''])\n",
    "\n",
    "    data.append(['macro avg', report['macro avg']['precision'], report['macro avg']['recall'], report['macro avg']['f1-score'], ''])\n",
    "\n",
    "    data.append(['weighted avg', report['weighted avg']['precision'], report['weighted avg']['recall'], report['weighted avg']['f1-score'], ''])\n",
    "\n",
    "    print(tabulate(data, headers=['Class', 'Precision', 'Recall', 'F1-score', 'Support'], tablefmt='psql'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_prepared_data():\n",
    "    train_set = pd.read_csv(CONSTANTS.AUGMENTED_TRAIN_SET_PATH)\n",
    "    X_train = train_set['text']\n",
    "    y_train = train_set['label']\n",
    "    test_set = pd.read_csv(CONSTANTS.AUGMENTED_TEST_SET_PATH)\n",
    "    X_test = test_set['text']\n",
    "    y_test = test_set['label']    \n",
    "    X_train = X_train.apply(remove_stopwords)\n",
    "    X_test = X_test.apply(remove_stopwords)   \n",
    "    return X_train, X_test, y_train, y_test "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = get_prepared_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def apply_lemmatization_with_filter(filter):\n",
    "    X_train, X_test, y_train, y_test = get_prepared_data()\n",
    "    # Apply lemmatization with filter\n",
    "    lemmatize_filter = create_lemmatizer_with_filter(filter)\n",
    "    X_train_filtered = X_train.apply(lemmatize_filter)\n",
    "    X_test_filtered = X_test.apply(lemmatize_filter)\n",
    "\n",
    "    # Apply TF_IDF\n",
    "    vectorizer = TfidfVectorizer()\n",
    "    X_train_filtered = vectorizer.fit_transform(X_train_filtered)\n",
    "    X_test_filtered = vectorizer.transform(X_test_filtered)\n",
    "    return X_train_filtered, X_test_filtered\n",
    "\n",
    "def features_selection(X_train_filtered, X_test_filtered, scorer, k_value):\n",
    "\n",
    "    # Apply features selection\n",
    "    selector = SelectKBest(score_func=scorer, k=k_value)\n",
    "    X_train_selected = selector.fit_transform(X_train_filtered, y_train)\n",
    "    X_test_selected = selector.transform(X_test_filtered)    \n",
    "    return X_train_selected, X_test_selected\n",
    "\n",
    "def tune_model(filter, model):\n",
    "    train_accuracies = []\n",
    "    test_accuracies = []\n",
    "    features_counts = []\n",
    "    X_train_filtered, X_test_filtered = apply_lemmatization_with_filter(filter)\n",
    "    _, max_count = X_train_filtered.shape\n",
    "    for i in range(100, max_count, 50):\n",
    "        X_train_selected, X_test_selected = features_selection(X_train_filtered, X_test_filtered, chi2, i)\n",
    "        model.fit(X_train_selected, y_train)\n",
    "        \n",
    "        # Training set acc\n",
    "        y_train_pred = model.predict(X_train_selected)\n",
    "        train_accuracy = accuracy_score(y_train, y_train_pred)\n",
    "        train_accuracies.append(train_accuracy)\n",
    "\n",
    "        # Testing set acc\n",
    "        y_pred = model.predict(X_test_selected)\n",
    "        test_accuracy = accuracy_score(y_test, y_pred)\n",
    "        test_accuracies.append(test_accuracy)\n",
    "\n",
    "        features_counts.append(i)\n",
    "\n",
    "    # Plotting the accuracies\n",
    "    plt.figure(figsize=(10, 6))\n",
    "    plt.plot(features_counts, train_accuracies, label='Train Accuracy', marker='.')\n",
    "    plt.plot(features_counts, test_accuracies, label='Test Accuracy', marker='.')\n",
    "    plt.title('Train and Test Accuracy vs Number of Features')\n",
    "    plt.xlabel('Number of Features Selected')\n",
    "    plt.ylabel('Accuracy')\n",
    "    plt.legend()\n",
    "    plt.grid()\n",
    "\n",
    "    # Finding closest points (3)\n",
    "    differences = np.abs(np.array(train_accuracies) - np.array(test_accuracies))\n",
    "    closest_indices = np.argsort(differences)[:3]  # indices of the three smallest differences\n",
    "    colors = ['darkgreen', 'mediumseagreen', 'lightgreen']\n",
    "\n",
    "    # Draw a rect\n",
    "    for i, idx in enumerate(closest_indices):\n",
    "        x = features_counts[idx] - 5\n",
    "        y_bottom = min(train_accuracies[idx], test_accuracies[idx])\n",
    "        y_top = max(train_accuracies[idx], test_accuracies[idx])\n",
    "        height = y_top - y_bottom\n",
    "\n",
    "        plt.gca().add_patch(plt.Rectangle(\n",
    "            (x, y_bottom), 10, height,\n",
    "            color=colors[i], alpha=0.5\n",
    "        ))\n",
    "\n",
    "    plt.show()    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_pos_filter(filter, scorer, k_value, model):\n",
    "    X_train_filtered, X_test_filtered = apply_lemmatization_with_filter(filter)\n",
    "    X_train_selected, X_test_selected = features_selection(X_train_filtered, X_test_filtered, scorer, k_value)\n",
    "    model.fit(X_train_selected, y_train)\n",
    "        \n",
    "    # Training set acc\n",
    "    y_train_pred = model.predict(X_train_selected)\n",
    "    train_accuracy = accuracy_score(y_train, y_train_pred)\n",
    "\n",
    "    # Testing set acc\n",
    "    y_pred = model.predict(X_test_selected)\n",
    "    test_accuracy = accuracy_score(y_test, y_pred)\n",
    "\n",
    "    print(f'Train Accuracy: {train_accuracy}')\n",
    "    print(f'Test Accuracy: {test_accuracy}')\n",
    "    print(f'Difference: {train_accuracy-test_accuracy}')    \n",
    "    # Print classification report\n",
    "    report = classification_report(y_test, y_pred, output_dict=True)\n",
    "    print_clf_report_as_table(report)   \n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ***1- Verbs only***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 61024 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "classifier = MultinomialNB()\n",
    "tune_model(wordnet.VERB, classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 62216 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "classifier = MultinomialNB(alpha=0.1)\n",
    "tune_model(wordnet.VERB, classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Accuracy: 0.7229166666666667\n",
      "Test Accuracy: 0.64375\n",
      "Difference: 0.07916666666666661\n",
      "+---------------------------------+---------------------+---------------------+------------+-----------+\n",
      "| Class                           | Precision           | Recall              |   F1-score | Support   |\n",
      "|---------------------------------+---------------------+---------------------+------------+-----------|\n",
      "| Acne                            | 0.85                | 0.8095238095238095  |   0.829268 | 21.0      |\n",
      "| Arthritis                       | 0.68                | 0.85                |   0.755556 | 20.0      |\n",
      "| Bronchial Asthma                | 0.6818181818181818  | 0.7894736842105263  |   0.731707 | 19.0      |\n",
      "| Cervical spondylosis            | 0.8461538461538461  | 0.5238095238095238  |   0.647059 | 21.0      |\n",
      "| Chicken pox                     | 0.17647058823529413 | 0.6                 |   0.272727 | 15.0      |\n",
      "| Common Cold                     | 0.65                | 0.6190476190476191  |   0.634146 | 21.0      |\n",
      "| Dengue                          | 0.5                 | 0.13636363636363635 |   0.214286 | 22.0      |\n",
      "| Dimorphic Hemorrhoids           | 0.76                | 1.0                 |   0.863636 | 19.0      |\n",
      "| Fungal infection                | 0.8333333333333334  | 0.7692307692307693  |   0.8      | 26.0      |\n",
      "| Hypertension                    | 0.5384615384615384  | 0.3888888888888889  |   0.451613 | 18.0      |\n",
      "| Impetigo                        | 0.8235294117647058  | 0.6086956521739131  |   0.7      | 23.0      |\n",
      "| Jaundice                        | 0.7894736842105263  | 0.6818181818181818  |   0.731707 | 22.0      |\n",
      "| Malaria                         | 0.7083333333333334  | 1.0                 |   0.829268 | 17.0      |\n",
      "| Migraine                        | 0.875               | 0.5833333333333334  |   0.7      | 24.0      |\n",
      "| Pneumonia                       | 0.8333333333333334  | 0.9090909090909091  |   0.869565 | 22.0      |\n",
      "| Psoriasis                       | 0.6470588235294118  | 0.6470588235294118  |   0.647059 | 17.0      |\n",
      "| Typhoid                         | 0.3125              | 0.2777777777777778  |   0.294118 | 18.0      |\n",
      "| Varicose Veins                  | 0.8947368421052632  | 0.68                |   0.772727 | 25.0      |\n",
      "| allergy                         | 0.47619047619047616 | 0.6666666666666666  |   0.555556 | 15.0      |\n",
      "| diabetes                        | 0.47058823529411764 | 0.47058823529411764 |   0.470588 | 17.0      |\n",
      "| drug reaction                   | 0.5454545454545454  | 0.375               |   0.444444 | 16.0      |\n",
      "| gastroesophageal reflux disease | 0.5862068965517241  | 0.8095238095238095  |   0.68     | 21.0      |\n",
      "| peptic ulcer disease            | 0.6666666666666666  | 0.5555555555555556  |   0.606061 | 18.0      |\n",
      "| urinary tract infection         | 0.875               | 0.6086956521739131  |   0.717949 | 23.0      |\n",
      "| accuracy                        |                     |                     |   0.64375  |           |\n",
      "| macro avg                       | 0.6675129056848458  | 0.6400059386671818  |   0.634127 |           |\n",
      "| weighted avg                    | 0.6880277139163489  | 0.64375             |   0.646794 |           |\n",
      "+---------------------------------+---------------------+---------------------+------------+-----------+\n"
     ]
    }
   ],
   "source": [
    "classifier = MultinomialNB(alpha=0.1)\n",
    "evaluate_pos_filter(wordnet.VERB, chi2, 350, classifier)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ***2- Adjectives only***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 62676 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "classifier = MultinomialNB(alpha=0.1)\n",
    "tune_model(wordnet.ADJ, classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Accuracy: 0.8037037037037037\n",
      "Test Accuracy: 0.625\n",
      "Difference: 0.1787037037037037\n",
      "+---------------------------------+---------------------+---------------------+------------+-----------+\n",
      "| Class                           | Precision           | Recall              |   F1-score | Support   |\n",
      "|---------------------------------+---------------------+---------------------+------------+-----------|\n",
      "| Acne                            | 0.6428571428571429  | 0.8571428571428571  |   0.734694 | 21.0      |\n",
      "| Arthritis                       | 0.5454545454545454  | 0.9                 |   0.679245 | 20.0      |\n",
      "| Bronchial Asthma                | 0.6956521739130435  | 0.8421052631578947  |   0.761905 | 19.0      |\n",
      "| Cervical spondylosis            | 0.7894736842105263  | 0.7142857142857143  |   0.75     | 21.0      |\n",
      "| Chicken pox                     | 0.1346153846153846  | 0.4666666666666667  |   0.208955 | 15.0      |\n",
      "| Common Cold                     | 0.75                | 0.7142857142857143  |   0.731707 | 21.0      |\n",
      "| Dengue                          | 0.6666666666666666  | 0.18181818181818182 |   0.285714 | 22.0      |\n",
      "| Dimorphic Hemorrhoids           | 0.6842105263157895  | 0.6842105263157895  |   0.684211 | 19.0      |\n",
      "| Fungal infection                | 0.7419354838709677  | 0.8846153846153846  |   0.807018 | 26.0      |\n",
      "| Hypertension                    | 0.6428571428571429  | 0.5                 |   0.5625   | 18.0      |\n",
      "| Impetigo                        | 0.64                | 0.6956521739130435  |   0.666667 | 23.0      |\n",
      "| Jaundice                        | 0.8461538461538461  | 1.0                 |   0.916667 | 22.0      |\n",
      "| Malaria                         | 0.6296296296296297  | 1.0                 |   0.772727 | 17.0      |\n",
      "| Migraine                        | 0.9130434782608695  | 0.875               |   0.893617 | 24.0      |\n",
      "| Pneumonia                       | 0.8235294117647058  | 0.6363636363636364  |   0.717949 | 22.0      |\n",
      "| Psoriasis                       | 0.5                 | 0.29411764705882354 |   0.37037  | 17.0      |\n",
      "| Typhoid                         | 0.6153846153846154  | 0.4444444444444444  |   0.516129 | 18.0      |\n",
      "| Varicose Veins                  | 1.0                 | 0.36                |   0.529412 | 25.0      |\n",
      "| allergy                         | 0.3333333333333333  | 0.13333333333333333 |   0.190476 | 15.0      |\n",
      "| diabetes                        | 0.42105263157894735 | 0.47058823529411764 |   0.444444 | 17.0      |\n",
      "| drug reaction                   | 0.75                | 0.5625              |   0.642857 | 16.0      |\n",
      "| gastroesophageal reflux disease | 0.5714285714285714  | 0.38095238095238093 |   0.457143 | 21.0      |\n",
      "| peptic ulcer disease            | 0.6                 | 0.5                 |   0.545455 | 18.0      |\n",
      "| urinary tract infection         | 0.7368421052631579  | 0.6086956521739131  |   0.666667 | 23.0      |\n",
      "| accuracy                        |                     |                     |   0.625    |           |\n",
      "| macro avg                       | 0.6530883488982869  | 0.6127824088259123  |   0.605689 |           |\n",
      "| weighted avg                    | 0.6730313401267114  | 0.625               |   0.621423 |           |\n",
      "+---------------------------------+---------------------+---------------------+------------+-----------+\n"
     ]
    }
   ],
   "source": [
    "classifier = MultinomialNB(alpha=0.1)\n",
    "evaluate_pos_filter(wordnet.ADJ, chi2, 450, classifier)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ***3- Nouns only***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 56368 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "classifier = MultinomialNB(alpha=0.1)\n",
    "tune_model(wordnet.NOUN, classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Accuracy: 0.9766203703703704\n",
      "Test Accuracy: 0.9229166666666667\n",
      "Difference: 0.0537037037037037\n",
      "+---------------------------------+--------------------+--------------------+------------+-----------+\n",
      "| Class                           | Precision          | Recall             |   F1-score | Support   |\n",
      "|---------------------------------+--------------------+--------------------+------------+-----------|\n",
      "| Acne                            | 1.0                | 1.0                |   1        | 21.0      |\n",
      "| Arthritis                       | 0.9523809523809523 | 1.0                |   0.97561  | 20.0      |\n",
      "| Bronchial Asthma                | 1.0                | 0.8947368421052632 |   0.944444 | 19.0      |\n",
      "| Cervical spondylosis            | 0.84               | 1.0                |   0.913043 | 21.0      |\n",
      "| Chicken pox                     | 0.6666666666666666 | 0.9333333333333333 |   0.777778 | 15.0      |\n",
      "| Common Cold                     | 1.0                | 1.0                |   1        | 21.0      |\n",
      "| Dengue                          | 0.8823529411764706 | 0.6818181818181818 |   0.769231 | 22.0      |\n",
      "| Dimorphic Hemorrhoids           | 0.9047619047619048 | 1.0                |   0.95     | 19.0      |\n",
      "| Fungal infection                | 1.0                | 0.9615384615384616 |   0.980392 | 26.0      |\n",
      "| Hypertension                    | 1.0                | 0.8888888888888888 |   0.941176 | 18.0      |\n",
      "| Impetigo                        | 0.8518518518518519 | 1.0                |   0.92     | 23.0      |\n",
      "| Jaundice                        | 1.0                | 0.9090909090909091 |   0.952381 | 22.0      |\n",
      "| Malaria                         | 0.9444444444444444 | 1.0                |   0.971429 | 17.0      |\n",
      "| Migraine                        | 1.0                | 1.0                |   1        | 24.0      |\n",
      "| Pneumonia                       | 1.0                | 1.0                |   1        | 22.0      |\n",
      "| Psoriasis                       | 0.9333333333333333 | 0.8235294117647058 |   0.875    | 17.0      |\n",
      "| Typhoid                         | 0.8095238095238095 | 0.9444444444444444 |   0.871795 | 18.0      |\n",
      "| Varicose Veins                  | 1.0                | 0.8                |   0.888889 | 25.0      |\n",
      "| allergy                         | 0.7368421052631579 | 0.9333333333333333 |   0.823529 | 15.0      |\n",
      "| diabetes                        | 0.9285714285714286 | 0.7647058823529411 |   0.83871  | 17.0      |\n",
      "| drug reaction                   | 0.8666666666666667 | 0.8125             |   0.83871  | 16.0      |\n",
      "| gastroesophageal reflux disease | 0.9523809523809523 | 0.9523809523809523 |   0.952381 | 21.0      |\n",
      "| peptic ulcer disease            | 0.8823529411764706 | 0.8333333333333334 |   0.857143 | 18.0      |\n",
      "| urinary tract infection         | 1.0                | 0.9565217391304348 |   0.977778 | 23.0      |\n",
      "| accuracy                        |                    |                    |   0.922917 |           |\n",
      "| macro avg                       | 0.9230054165915879 | 0.9204231547297993 |   0.917476 |           |\n",
      "| weighted avg                    | 0.931173893339012  | 0.9229166666666667 |   0.923054 |           |\n",
      "+---------------------------------+--------------------+--------------------+------------+-----------+\n"
     ]
    }
   ],
   "source": [
    "classifier = MultinomialNB(alpha=0.1)\n",
    "evaluate_pos_filter(wordnet.NOUN, chi2, 850, classifier)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "NLP",
   "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.9.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
