{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "ccf41206-01d8-4d2a-b4dd-7e2566d256c1", "metadata": { "tags": [] }, "outputs": [], "source": [ "import torch\n", "from datasets import load_dataset\n", "from transformers import AutoModelForSequenceClassification, AutoTokenizer, get_scheduler\n", "from torch.utils.data import DataLoader\n", "from transformers import AdamW, TrainingArguments\n", "from tqdm.auto import tqdm\n", "import evaluate\n", "from accelerate import Accelerator" ] }, { "cell_type": "code", "execution_count": 15, "id": "7f47de86-d2d7-45b9-b14d-95d5572590e7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dataset Information:\n", "\n", "RangeIndex: 8544 entries, 0 to 8543\n", "Data columns (total 2 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 label 8544 non-null int64 \n", " 1 cleaned_text 8544 non-null object\n", "dtypes: int64(1), object(1)\n", "memory usage: 133.6+ KB\n", "None\n", "\n", "Descriptive Statistics for Label:\n", "| | label |\n", "|:------|:--------|\n", "| count | 8544 |\n", "| mean | 2.05805 |\n", "| std | 1.28157 |\n", "| min | 0 |\n", "| 25% | 1 |\n", "| 50% | 2 |\n", "| 75% | 3 |\n", "| max | 4 |\n", "\n", "Descriptive Statistics for Review Length:\n", "| | review_length |\n", "|:------|:----------------|\n", "| count | 8544 |\n", "| mean | 136.027 |\n", "| std | 68.8262 |\n", "| min | 5 |\n", "| 25% | 83 |\n", "| 50% | 130 |\n", "| 75% | 182 |\n", "| max | 368 |\n" ] } ], "source": [ "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import altair as alt\n", "import nltk\n", "\n", "# Load the dataset\n", "df = pd.read_csv('sentence_train.csv')\n", "\n", "# Basic Information and Summary Statistics\n", "print(\"Dataset Information:\")\n", "print(df.info())\n", "\n", "print(\"\\nDescriptive Statistics for Label:\")\n", "print(df['label'].describe().to_markdown(numalign=\"left\", stralign=\"left\"))\n", "\n", "print(\"\\nDescriptive Statistics for Review Length:\")\n", "df['review_length'] = df['cleaned_text'].apply(len)\n", "print(df['review_length'].describe().to_markdown(numalign=\"left\", stralign=\"left\"))\n", "\n" ] }, { "cell_type": "code", "execution_count": 16, "id": "7c2c2368-c29c-4061-a395-f35e677c6374", "metadata": { "tags": [] }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsAAAAIhCAYAAABANwzIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAwzElEQVR4nO3df1RVdb7/8ddREMjgKCK/ipDMn6H9QFNsSk3FKHQcp6ws0ntNrfwRo2aZ3xId07l6U26SZk1Jpl5s1mg1UxfDH1kmFNKQP3PVvVpYImp4EAdBcH//aNyrI2CKHA/6eT7W2mt59vmcc96bs5r1vPtuNg7LsiwBAAAAhmji7QEAAACAS4kABgAAgFEIYAAAABiFAAYAAIBRCGAAAAAYhQAGAACAUQhgAAAAGIUABgAAgFEIYAAAABiFAAZwxcrIyJDD4dC2bdsa5P0cDofGjx/fIO/1y/dMTU09r3VntqZNm6ply5a66aabNHbsWOXm5tZYv3//fjkcDmVkZFzQPKtWrVJaWtoFvaa2z0pNTZXD4dCRI0cu6L3OZffu3UpNTdX+/ftrPDdy5Ei1adOmwT4LwJWNAAaAy8R9992nnJwcbdmyRZmZmXr00UeVm5ur+Ph4PfXUU25rIyIilJOTo3vvvfeCPqM+AVzfz7pQu3fv1syZM2sN4Oeff15r16716OcDuHL4eHsAAMD5CQsLU8+ePe3HAwcOVEpKisaMGaOXX35ZHTt21BNPPCFJ8vPzc1vrCdXV1aqqqrokn/Vr2rZt69XPB3B54QwwAKOdPHlSkydP1s033yyn06ng4GDFx8frvffeq/M1S5cuVfv27eXn56fOnTsrMzOzxpqioiKNHTtW1157rZo1a6aYmBjNnDlTVVVVDTp/06ZNlZ6erpCQEM2fP9/eX9tlCYcPH9aYMWMUFRUlPz8/tW7dWrfffrvWr18vSerTp48++OADfffdd26XXPzy/ebNm6fZs2crJiZGfn5+2rRp0zkvtygsLNTQoUMVFBQkp9OpRx55RIcPH3ZbU9dlIG3atNHIkSMl/Xw5y/333y9J6tu3rz3bmc+s7RKIkydPatq0aYqJiVGzZs10zTXXaNy4cTp27FiNz0lKSlJWVpZuvfVWBQQEqGPHjnrzzTd/5acP4HLFGWAARquoqNBPP/2kKVOm6JprrlFlZaXWr1+voUOHatmyZXr00Ufd1r///vvatGmTZs2apebNm2vx4sV66KGH5OPjo/vuu0/Sz/F72223qUmTJnrhhRfUtm1b5eTkaPbs2dq/f7+WLVvWoMcQEBCg/v37KzMzUwcOHNC1115b67rk5GR9+eWXevHFF9W+fXsdO3ZMX375pY4ePSpJWrx4scaMGaP//d//rfNygpdfflnt27fXf/7nfyooKEjt2rU752y/+93vNGzYMD3++OPatWuXnn/+ee3evVuff/65fH19z/sY7733Xs2ZM0fPPfecXnnlFd16662S6j7za1mWhgwZog0bNmjatGm64447tH37ds2YMUM5OTnKycmRn5+fvf6rr77S5MmT9eyzzyosLEx//vOfNWrUKN1www268847z3tOAJcHAhiA0ZxOp1uQVldXq1+/fiopKVFaWlqNAD5y5Ijy8vIUFhYmSbrnnnsUGxuradOm2QGcmpqqkpIS7dq1S9ddd50kqV+/fgoICNCUKVP09NNPq3Pnzg16HNHR0ZKkH3/8sc4A/uyzz/TYY49p9OjR9r7f/va39r87d+6sFi1anPOSBn9/f61bt84tXmu7JveMoUOHat68eZKkhIQEhYWF6eGHH9Y777yjhx9++LyPr3Xr1nZsd+7c+Vcvufjoo4+0bt06zZs3T08//bQkacCAAYqKitIDDzyg5cuXu/0cjhw5os8++8z+vu68805t2LBBq1atIoCBKxCXQAAw3l/+8hfdfvvtuvrqq+Xj4yNfX1+98cYb2rNnT421/fr1s+NX+vkShAceeEDffvutDhw4IEn6+9//rr59+yoyMlJVVVX2lpiYKEnavHlzgx+DZVm/uua2225TRkaGZs+erdzcXJ06deqCP2fw4MEXdOb27MgdNmyYfHx8tGnTpgv+7AuxceNGSbIvoTjj/vvvV/PmzbVhwwa3/TfffLMdv9LPod++fXt99913Hp0TgHcQwACMtmbNGg0bNkzXXHONVqxYoZycHOXl5enf//3fdfLkyRrrw8PD69x35lKCQ4cO6W9/+5t8fX3dthtvvFGSGvTWYGecCbXIyMg616xevVojRozQn//8Z8XHxys4OFiPPvqoioqKzvtzIiIiLmius39ePj4+atWqlf2z8pSjR4/Kx8dHrVu3dtvvcDgUHh5e4/NbtWpV4z38/PxUXl7u0TkBeAeXQAAw2ooVKxQTE6PVq1fbv/Al/XxtcG1qi8Uz+85EVEhIiLp27aoXX3yx1vc4V6TWR3l5udavX6+2bdvWefnDmbnS0tKUlpam77//Xu+//76effZZFRcXKysr67w+65c/o/NRVFSka665xn5cVVWlo0ePugWnn59frT/vi4nkVq1aqaqqSocPH3aLYMuyVFRUpO7du9f7vQFc/jgDDMBoDodDzZo1cwu7oqKiOu8CsWHDBh06dMh+XF1drdWrV7vFZ1JSknbu3Km2bduqW7duNbaGDODq6mqNHz9eR48e1TPPPHPer7vuuus0fvx4DRgwQF9++aW9v6HPeq5cudLt8TvvvKOqqir16dPH3temTRtt377dbd3GjRtVVlbmtu/ML62dz3z9+vWT9PP/gfNLf/3rX3XixAn7eQBm4gwwgCvexo0ba/1FrXvuuUdJSUlas2aNnnzySd13330qLCzUH//4R0VEROibb76p8ZqQkBDdddddev755+27QHz99ddut0KbNWuWsrOz1atXL02cOFEdOnTQyZMntX//fn344Yd69dVXz3mmti6HDh1Sbm6uLMvS8ePHtXPnTi1fvlxfffWV/vCHP7j9UtfZXC6X+vbtq+HDh6tjx44KDAxUXl6esrKyNHToUHtdly5dtGbNGi1ZskRxcXFq0qSJunXrdsGznrFmzRr5+PhowIAB9l0gbrrpJg0bNsxek5ycrOeff14vvPCCevfurd27dys9PV1Op9PtvWJjYyVJr732mgIDA+Xv76+YmJhaL18YMGCABg4cqGeeeUalpaW6/fbb7btA3HLLLUpOTq73MQG4AlgAcIVatmyZJanObd++fZZlWdaf/vQnq02bNpafn5/VqVMn6/XXX7dmzJhhnf0/kZKscePGWYsXL7batm1r+fr6Wh07drRWrlxZ47MPHz5sTZw40YqJibF8fX2t4OBgKy4uzpo+fbpVVlbm9p4zZsz41WP55dxNmjSxgoKCrC5dulhjxoyxcnJyaqzft2+fJclatmyZZVmWdfLkSevxxx+3unbtagUFBVkBAQFWhw4drBkzZlgnTpywX/fTTz9Z9913n9WiRQvL4XDYP4Mz7zd//vxf/SzLsuyfX35+vjVo0CDr6quvtgIDA62HHnrIOnTokNvrKyoqrKlTp1pRUVFWQECA1bt3b6ugoMCKjo62RowY4bY2LS3NiomJsZo2ber2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5ORkHTx4UE6nU127dlVWVpYGDBjg7dEAr+I+wAAAADAK1wADAADAKAQwAAAAjEIAAwAAwCgEMAAAAIxCAAMAAMAoBDAAAACMQgADAADAKAQwAAAAjEIAA4BhMjIy1KJFi4t+H4fDoXffffei3wcALjUCGAAuQyNHjtSQIUO8PQYAXJYIYAAAABiFAAaAK8yCBQvUpUsXNW/eXFFRUXryySdVVlZWY927776r9u3by9/fXwMGDFBhYaHb83/7298UFxcnf39/XX/99Zo5c6aqqqou1WEAgMcQwABwhWnSpIlefvll7dy5U2+99ZY2btyoqVOnuq355z//qRdffFFvvfWWPvvsM5WWlurBBx+0n1+3bp0eeeQRTZw4Ubt379bSpUuVkZGhF1988VIfDgA0OIdlWZa3hwAAXJiRI0fq2LFj5/VLaH/5y1/0xBNP6MiRI5J+/iW4f/u3f1Nubq569OghSfr666/VqVMnff7557rtttt05513KjExUdOmTbPfZ8WKFZo6dap+/PFHST//EtzatWu5FhnAZcfH2wMAABrWpk2bNGfOHO3evVulpaWqqqrSyZMndeLECTVv3lyS5OPjo27dutmv6dixo1q0aKE9e/botttuU35+vvLy8tzO+FZXV+vkyZP65z//qauuuuqSHxcANBQCGACuIN99953uuecePf744/rjH/+o4OBgbdmyRaNGjdKpU6fc1jocjhqvP7Pv9OnTmjlzpoYOHVpjjb+/v2eGB4BLhAAGgCvItm3bVFVVpZdeeklNmvz8ax7vvPNOjXVVVVXatm2bbrvtNknS3r17dezYMXXs2FGSdOutt2rv3r264YYbLt3wAHCJEMAAcJlyuVwqKChw29e6dWtVVVVp0aJFGjRokD777DO9+uqrNV7r6+urCRMm6OWXX5avr6/Gjx+vnj172kH8wgsvKCkpSVFRUbr//vvVpEkTbd++XTt27NDs2bMvxeEBgMdwFwgAuEx9/PHHuuWWW9y2N998UwsWLNB//Md/KDY2VitXrtTcuXNrvPaqq67SM888o+HDhys+Pl4BAQHKzMy0nx84cKD+/ve/Kzs7W927d1fPnj21YMECRUdHX8pDBACP4C4QAAAAMApngAEAAGAUAhgAAABGIYABAABgFAIYAAAARiGAAQAAYBQCGAAAAEYhgAEAAGAUAhgAAABGIYABAABgFAIYAAAARiGAAQAAYJT/D85D4K1rgPmcAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "[nltk_data] Downloading package stopwords to /home/studio-lab-\n", "[nltk_data] user/nltk_data...\n", "[nltk_data] Unzipping corpora/stopwords.zip.\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1sAAAL3CAYAAAB8lV8kAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABvm0lEQVR4nO3dd3QU5eLG8WdTSWIIkJCEYIBIR4oKSlMg9I6ggoLUiKj0ooheFdQLXL0UFREUCB0UBcsF6QlSpYYuIFJEEkBKQiip8/uDk/2xJLSYyWzg+zlnj+7sm91nU9h9dt55x2YYhiEAAAAAQI5ysToAAAAAANyLKFsAAAAAYALKFgAAAACYgLIFAAAAACagbAEAAACACShbAAAAAGACyhYAAAAAmICyBQAAAAAmoGwBAAAAgAkoWwBgIpvNdkeX6OhoU3PExsbqX//6l2rWrKmAgADlz59fVatW1Zdffqm0tLRM4xMTEzVgwACFhIQoX758euSRRzR//vw7eqzhw4fLZrPJxcVFf/zxR6bbL126pPz588tms6lbt27/9Kllad++fRo+fLiOHj16R+OnT59+05/NkCFDTMnorObOnavx48ff0diWLVvK19dXqampDtt37Nghm82mIkWKZPqatWvXymaz6dNPP82JuDfVrVs3lShRwtTHAIDbcbM6AADcyzZu3Ohw/YMPPlBUVJRWr17tsL1ChQqm5ti2bZtmzpypLl266J133pG7u7t+/vlnvfrqq9q0aZOmTZvmML5du3basmWLRo8erTJlymju3Ll64YUXlJ6ero4dO97RYz7wwAOKjIzUBx984LB9wYIFSklJkbu7e449vxvt27dPI0aMUL169e7qDXdkZKTKlSvnsC0kJCSH0zm3uXPnas+ePRowYMBtx4aHh2vx4sXaunWratSoYd8eHR0tHx8fxcXF6bfffnP4nmZ8sBAeHp7T0QHA6VC2AMBE178BlaTChQvLxcUl03az1a5dW4cPH3YoOI0aNVJycrI+//xzjRgxQqGhoZKkJUuWaMWKFfaCJV17Y3zs2DG9/vrr6tChg1xdXW/7mB06dNCMGTM0YsQIubj8/0SKqVOnqm3btvrxxx9z+Fn+cxUrVlS1atXuaGxKSopsNpvc3O7fl9KMwhQdHZ2pbLVp00ZRUVGKiorKVLYCAgJUsWLFf/TYfP8B5AVMIwQAi507d06vvfaaihYtKg8PDz300EN6++23lZSU5DDOZrOpT58+mjx5ssqUKSNPT09VqFDhjqb3FSxYMMs9SU888YQk6cSJE/ZtixYt0gMPPKDnnnvOYWz37t118uRJ/frrr3f0vHr06KE///xTK1assG87ePCg1q1bpx49emT5NcePH9eLL76owMBAeXp6qnz58hozZozS09Mdxn3xxReqUqWKHnjgAfn6+qpcuXJ66623JF2bEpiRPTw83D4dcPr06XeUOyvR0dGy2WyaNWuWBg8erKJFi8rT01O///67JGnlypVq0KCB8ufPL29vb9WuXVurVq3KdD+LFy/WI488Ik9PT4WFhem///2vfdplhqNHj940r81m0/Dhwx22HTp0SB07dnT4nn3++edZ5p83b57efvtthYSEKH/+/GrYsKEOHDhgH1evXj0tXrxYx44dc5hKeTOPPPKIChYs6DANNj09XWvXrlW9evVUt25dRUVF2W9LTk7Wxo0bVa9ePfv97tmzR23atFHBggXtU1ZnzJhxV9//6dOnq2zZsvbnP3PmzCzz3ur3BgDMwMdBAGChq1evKjw8XIcPH9aIESNUuXJlrV27VqNGjVJMTIwWL17sMP7HH39UVFSU3n//ffn4+GjixIl64YUX5ObmpmefffauH3/16tVyc3NTmTJl7Nv27Nmj8uXLZ9pjULlyZfvttWrVuu19ly5dWk899ZSmTZumJk2aSJKmTZumEiVKqEGDBpnGnzlzRrVq1VJycrI++OADlShRQv/73/80ZMgQHT58WBMnTpQkzZ8/X6+99pr69u2r//73v3JxcdHvv/+uffv2SZJatGihkSNH6q233tLnn3+uxx57TJJUsmTJ22ZOS0vLdPzR9d+HYcOGqWbNmpo0aZJcXFwUGBio2bNnq0uXLmrTpo1mzJghd3d3TZ48WU2aNNGyZcvsz3XVqlVq06aNatasqfnz5ystLU0fffSRTp06ddtcN7Nv3z7VqlVLxYoV05gxYxQcHKxly5apX79++vvvv/Xee+85jH/rrbdUu3ZtTZkyRQkJCRo6dKhatWql/fv3y9XVVRMnTtTLL7+sw4cPa9GiRbd9fBcXF9WpU0crV65Uamqq3NzcFBMTo/Pnz6tu3bpKS0tzyLBp0yZduXLFvkfswIEDqlWrlgIDA/Xpp5/K399fs2fPVrdu3XTq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oTn1VAEAAADcByydRni9Pn36aNeuXVq3bp3D9g4dOtj/v2LFiqpWrZqKFy+uxYsXq127dje9P8MwZLPZ7Nev//+bjbnesGHDNGjQIPv1hIQEChcAAACAO+YUe7b69u2rH3/8UVFRUXrwwQdvObZIkSIqXry4Dh06JEkKDg5WcnKyzp8/7zDu9OnTCgoKso85depUpvs6c+aMfcyNPD09lT9/focLAAAAANwpS8uWYRjq06ePFi5cqNWrVyssLOy2X3P27Fn9+eefKlKkiCSpatWqcnd314oVK+xjYmNjtWfPHtWqVUuSVLNmTcXHx2vz5s32Mb/++qvi4+PtYwAAAAAgJ1k6jbB3796aO3eufvjhB/n6+tqPn/Lz85OXl5cSExM1fPhwPfPMMypSpIiOHj2qt956SwEBAWrbtq19bEREhAYPHix/f38VKlRIQ4YMUaVKleyrE5YvX15NmzZVz549NXnyZEnSyy+/rJYtW7ISIQAAAABTWFq2vvjiC0lSvXr1HLZHRkaqW7ducnV11e7duzVz5kxduHBBRYoUUXh4uL7++mv5+vrax48bN05ubm5q3769rly5ogYNGmj69OlydXW1j5kzZ4769etnX7WwdevWmjBhgvlPEgAAAMB9yWYYhmF1iLwgISFBfn5+io+Pv+XxWyXeXJyjj3t0dIscvT8AAAAA/8yddgOnWCADAAAAAO41lC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2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WS1btmQlQgAAAACmsbRsbd26VeHh4fbrgwYNkiR17dpV06dP1xtvvKErV67otdde0/nz51W9enUtX75cvr6+9q8ZN26c3Nzc1L59e125ckUNGjTQ9OnT5erqah8zZ84c9evXz75qYevWrW96bi8AAAAAyAk2wzAMq0PkBQkJCfLz81N8fPwtj98q8ebiHH3co6Nb5Nh93S/ZcjIXAAAAcKM77QZOe8wWAAAAAORllC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADABZQsAAAAATEDZAgAAAAATULYAAAAAwASULQAAAAAwAWULAAAAAExA2QIAAAAAE1C2AAAAAMAElC0AAAAAMAFlCwAAAABMQNkCAAAAABNQtgAAAADABJQtAAAAADCBm9UBAGdX4s3FOXZfR0e3yLH7AgAAgHNjzxYAAAAAmICyBQAAAAAmoGwBAAAAgAkoWwAAAABgAsoWAAAAAJiAsgUAAAAAJqBsAQAAAIAJKFsAAAAAYALKFgAAAACYgLIFAAAAACagbAEAAACACShbAAAAAGACyhYAAAAAmICyBQAAAAAmoGwBAAAAgAkoWwAAAABgAsoWAAAAAJiAsgUAAAAAJqBsAQAAAIAJKFsAAAAAYALKFgAAAACYgLIFAAAAACagbAEAAACACShbAAAAAGACyhYAAAAAmICyBQAA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vPOOSpQooYiICEtyXS85OVlHjhxRyZIl5eZm7T9D77//vsP1d99916Ikt3f69GkdOHBANptNZcqUUWBgoNWRnNZPP/2kDz/8UHXr1lVERITatWunfPnyWR0Ld+HTTz+947H9+vUzMcmtXbp0SaNHj9aqVat0+vRppaenO9z+xx9/WJLr4sWLaty4sUJDQ9W9e3d17dpVRYsWtSTLjQYMGKBKlSopIiJCaWlpqlu3rjZs2CBvb2/973//U7169SzLtmbNGjVr1ky1a9fWL7/8on//+98KDAzUrl27NGXKFH377beW5CpRooR69Oihbt26qVixYpZkuJ3U1FRFR0fr8OHD6tixo3x9fXXy5Enlz59fDzzwgCWZnOHvgPNs5aL27durTp066tOnj65cuaIqVaro6NGjMgxD8+fP1zPPPJPrmWrVqiVJ6t+/v4KCgmSz2Rxur1u3bq5nutGsWbM0adIkHTlyRBs3blTx4sU1fvx4hYWFqU2bNpblcnFxUVxcXKY3vKdPn1bRokWVkpJiSa73339fM2bM0Pvvv6+ePXtqz549euihh/TNN99o3Lhx2rhxoyW5JOny5cvq27evZsyYIUn2ItivXz+FhITozTffzPVM3bt3t/+/zWbTtGnTcj3D7SQkJKh3796aP3++/QMQV1dXdejQQZ9//rn8/Pwsy3b+/HlNnTpV+/fvl81mU7ly5dSjRw8VKlTIskwZdu3apcjISM2dO1fJycl6/vnn1aNHDz3++OOW5Jk5c6bD9S5duliS43YOHjyo6OjoLItDbn4YERYW5nD9zJkzunz5sv0DrgsXLsjb21uBgYGWFRpJeuGFF7RmzRp17txZRYoUyfQ62r9/f4uSSWfPntXs2bM1ffp07dmzRw0bNlRERITatGkjd3d3y3I9+OCD+v7771WtWjV9//336t27t6KiojRz5kxFRUVp/fr1lmWrWbOmnnvuOQ0aNEi+vr7auXOnHnroIW3ZskVPP/20/vrrL0tyffbZZ5o+fbp27typ8PBwRUREqG3btk5z4uBjx46padOmOn78uJKSkuyv7wMGDNDVq1c1adIky7JZ/ndgINcEBQUZMTExhmEYxpw5c4xSpUoZly5dMiZOnGg88sgjlmTy8fExfvvtN0se+05MnDjRCAgIMD788EPDy8vLOHz4sGEYhhEZGWnUq1fPkkw7d+40du7cadhsNiMqKsp+fefOncb27duNkSNHGsWLF7ckm2EYRsmSJY2VK1cahmEYDzzwgP17tn//fqNAgQKW5TIMw+jXr59RtWpVY+3atYaPj4892w8//GDZ30Be8NxzzxmlS5c2li5dasTHxxsJCQnG0qVLjbJlyxrPPfecZbmio6MNPz8/IzQ01Gjbtq3Rtm1bo1ixYkb+/PmN6Ohoy3LdKCUlxVi4cKHRqlUrw93d3ahYsaIxfvx448KFC7mao169evZLeHh4rj72nfryyy8NV1dXIygoyKhSpYrxyCOP2C+PPvqoZbnmzJlj1K5d2+H16rfffjOeeuopY/bs2ZblMgzD8PPzM9atW2dphjuxfft2o0+fPka+fPmMgIAAY8CAAcbBgwctyeLp6Wn8+eefhmEYRs+ePY3+/fsbhmEYf/zxh+Hr62tJpgw+Pj7GH3/8YRiG42vokSNHDE9PTyujGYZhGDExMUa/fv2MwoULGwULFjR69+5tbNu2zepYRps2bYwXX3zRSEpKcvi+RUdHG6VKlbI43f+z4u+AspWL8uXLZxw/ftwwDMPo3LmzMXToUMMwDOPYsWOGj4+PJZnq1atnrFixwpLHvhPly5c3Fi1aZBiG4z96u3fvNvz9/S3JZLPZDBcXF8PFxcWw2WyZLt7e3sbUqVMtyWYY137Pjh49ahiG4/ds7969lv2eZShWrJixceNGwzAcsx06dMjyF1hn5u3tbaxduzbT9l9++cXw9va2INE1Dz/8sNGzZ08jNTXVvi01NdV4+eWXjYcfftiyXDdKSkoy5s+fbzRu3Nhwc3Mz6tSpY5QtW9bw9fU15s+fb3U8p1KsWDFj9OjRVsfI5KGHHjK2b9+eafvWrVuNEiVKWJDo/5UoUcLYt2+fpRlu5+TJk8bo0aONMmXKGD4+PkaXLl2MRo0aGW5ubsbYsWNzPU+xYsWMZcuWGampqUZoaKjx008/GYZhGHv27LH8Q8GiRYsa69evNwzD8XVq4cKFxkMPPWRlNAfJycnG+PHjDU9PT8PFxcWoXLmyMXXqVCM9Pd2SPP7+/vYPQ24sqV5eXpZkupFVfwccs5WLQkNDtXHjRhUqVEhLly7V/PnzJV2bhmPVsQRTpkzRK6+8or/++ksVK1bMtDu1cuXKluTKcOTIET366KOZtnt6eurSpUsWJLqWyTAMPfTQQ9q8ebMKFy5sv83Dw0OBgYFydXW1JJskPfzww1q7dq2KFy/usH3BggVZfi9z05kzZ7I8zujSpUuZpt7g//n7+2c5VdDPz08FCxa0INE1hw8f1nfffefw++7q6qpBgwZlmjJnhW3btikyMlLz5s2Tp6enunTpos8//1ylSpWSJI0ZM0b9+vVThw4dciVPXjg+8Pz583ruueesjpFJbGxsllOz09LSdOrUKQsS/b8PPvhA7777rmbMmCFvb29Ls1wvJSVFP/74oyIjI7V8+XJVrlxZAwcOVKdOneTr6ytJmj9/vl599VUNHDgwV7N1795d7du3t0+7bNSokSTp119/Vbly5XI1y406duyooUOHasGCBbLZbEpPT9f69es1ZMgQp5j6m5KSokWLFikyMlIrVqxQjRo1FBERoZMnT+rtt9/WypUrNXfu3FzPlZ6enuVx/idOnLD/vlnBKf4OTKtxyOTzzz833NzcjAIFChhVqlQx0tLSDMMwjE8//dSyKXEbN240wsLCHPbMZOyxcXFxsSTT9cqXL298//33hmE4flLyySefGI899piV0ZzWjz/+aPj5+RmjR482vL29jY8//th46aWXDA8PD2P58uWWZqtTp47x6aefGoZx7eeZMVWjd+/eRpMmTayM5tQmT55sNGzY0Dh58qR9W2xsrNG4cWNj0qRJluWqVauWfc/z9RYtWmTUqFEj9wNdp1KlSoabm5vRvHlzY9GiRQ573zKcPn3asNlsuZapW7duDhdn1KNHD+OLL76wOkYmLVu2NCpXrmxs2bLF/sn9li1bjEceecRo1aqVpdkeeeQRw9fX13jggQeMihUrGo8++qjDxSr+/v5GwYIFjddee83YsWNHlmPOnTtn2Z7Bb7/91hg7dqx9OqFhGMb06dPtr/lWSU5ONjp27Gh/L+Tu7m64uLgYL774Ypb/juSWbdu2GX369DH8/f2NwMBAY/Dgwcb+/fsdxmzevNnIly+fJfnat29v9OzZ0zCM/399v3jxolG/fn1L/71zhr8DFsjIZdu2bdPx48fVqFEj+8osixcvVoECBVS7du1cz1OhQgWVL19eb7zxRpYLZNy4dyS3RUZG6p133tGYMWMUERGhKVOm6PDhwxo1apSmTJmi559/Ptcz3biEaJ06dXI9w+0sW7ZMI0eO1LZt25Senq7HHntM7777rho3bmxprg0bNqhp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/fffdfjwYdWpU0deXl72f9OsNHz4cI0YMULTpk1zqoUdnP21febMmerQoYM8PT0dticnJ9un8lmhUKFCunjxoqRrx/Lu2bNHlSpV0oULF3T58uVcycCerfvQ9cv83o6Vb5aka59Ov/jii6pfv77l/wDfaOjQoXrggQf0zjvvWB3FwerVq/Wvf/1LI0eOzPI4vNzeC5LVnO6UlBQNHDhQjRs3dpjH7UzHCDqLlJQUNWrUSC+88MJNP9GsW7duLqe65lar2DnDynXStSXDDxw4IJvNpjJlylj65jcvePzxx9WqVatMq+YOHz5cP/30k7Zt22ZJrooVK6pjx4566623HLZ/+OGH+vrrr7V7925LcknSyy+/rDNnzuibb75RoUKFtGvXLrm6uurpp59WnTp1NH78eEtyDRo0SNOnT9dbb73lcGqG0aNHq0uXLpYeF3X27Fm1b99eUVFRstlsOnTokB566CFFRESoQIECGjNmjGXZLl++rHbt2mn9+vUqUaJEptdQqw5fcLbX9hu5uroqNjY20yJmZ8+eVWBgoGUfCnbs2FHVqlXToEGD9O9//1uffPKJ2rRpoxUrVuixxx7LlSnllK37UF5a5rd169Zavny5/P399fzzz6tz58565JFHLM2UoX///po5c6YqV66sypUrZ/qHz6oXsuvnUDvDXpC8MKfb2bFM8t27dOmS+vbtq5kzZ9o/xXd1dVWXLl302Wefydvb2+KEzunHH3/UM888o44dO6p+/fqSri0ENG/ePC1YsMCyFUO/++47dejQQQ0bNlTt2rVls9m0bt06rVq1St98802uHeielYSEBDVv3lx79+7VxYsXFRISori4ONWsWVNLlizJtMc3t6Snp+u///2vPvnkE/vevyJFiqh///4aPHiw/TguK3Tp0kWnT5/WlClTVL58efvUy+XLl2vgwIHau3evZdkySuCzzz6b5QIZVh2+kPFaemMeq2c4ZHBxcdGpU6cyfaC1c+dOhYeH69y5c5bkOnfunK5evaqQkBD738S6detUqlQpvfPOO7my8BRlC07vwoUL+uabbzR37lytXbtWZcuW1YsvvqiOHTuqRIkSluVy1gN816xZc8vbrdoLguxzpmWS7/T4LJvNZumn07169dLKlSs1YcIE+wnj161bp379+qlRo0b64osvLMvm7BYvXqyRI0cqJiZGXl5e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TXK9lJQUXblyxYJE/y8yMtLSx78b+fPn1/vvv6+WLVtaUrYyjsHDrVG24NSWLl2qLl26ON3xAwCcW6lSpfT999+rbdu2WrZsmQYOHChJOn36dJ74xNoqEyZM0HPPPae1a9dmeS4fqw5yb9OmjXr06KExY8bo8ccfl81m0+bNmzVkyBD7SVU3b96sMmXK5Hq2N954Q/Hx8QoPD9fVq1dVp04deXp6asiQIerTp0+u58kwatQotWzZUkuXLs3yZzl27FiLkkmPP/64vvzyS3322WcO2ydNmqSqVatalCpvunDhguLj462OgVtgGiGcmrMePwDAuX377bfq2LGj0tLS1KBBAy1fvlzStTegv/zyi37++WeLEzqnKVOm6JVXXpGXl5dTLaqQmJiogQMHaubMmfY9Im5uburatavGjRsnHx8fxcTESJJl57q6fPmy9u3bp/T0dFWoUEEPPPCAJTkyfPDBB3rvvfdUtmxZBQUFZfpZWjmta/369WrYsKEef/xxNWjQQJK0atUqbdmyRcuXL+d47CzcuFCYYRiKjY21r7Y3b948i5LhdihbcGrOevwAAOcXFxen2NhYValSxb5AwObNm5U/f/4sTykBKTg4WP369dObb77pdIsqSNdK1x9//CHDMFSyZEnLC40zK1iwoMaNG6du3bpZHSVLMTEx+vjjjxUTEyMvLy9VrlxZw4YNs/QcW85m165dqlixolxcXBQWFuZwW8Y58OrXr69hw4bZp03D+VC24NR69Oih2rVrKyIiwuooAHDPK1SokLZs2cIHXPeA4OBgrV27lvKSh11/guWwsDBt2bJFAQEBVsfCXaJswaldvnxZzz33nAoXLuxUxw8AwL1o4MCBKly4sN566y2ro+AfGjVqlGJjYzNNP3M2V65cUUpKisM2jqu8xt/fX0uWLFH16tXl6uqquLg4FS5c2OpYuEsskAGnNnfuXC1btkxeXl6Kjo7ONOecsgUAOSctLU0fffSRli1bpsqVKzvVogq4O5s3b9bq1av1v//9Tw8//HCmn+XChQstSnbtg9Q33nhD33zzTZbLvLP41TXPPPOM6tatqyJFikiSqlWrJldX1yzHWnmSatwaZQtO7V//+pfef/99pz1+AADuJbt377afPHXPnj0Ot13/YRecX4ECBdSuXTurY2Tp9ddfV1RUlCZOnKguXbro888/119//aXJkydr9OjRVsdzGl9++aXatWun33//Xf369VPPnj05NisPYhohnBrHDwAAcG8pVqyYZs6cqXr16il//vzavn27SpUqpVmzZmnevHlasmSJ1RGdTvfu3fXpp59StvIgdhXAqXXt2lVff/211TEAAMiTzpw5o3Xr1mn9+vU6c+aM1XEkSefOnbOvrpc/f36dO3dOkvTkk0/ql19+sTKa04qMjKRo5VFMI4RT4/gBAADu3qVLl9S3b1/NnDlT6enpkq6tbtelSxd99tln8vb2tizbQw89pKNHj6p48eKqUKGCvvnmGz3xxBP66aefVKBAActyAWZgGiGcWnh4+E1vs/qkjAAAOKtevXpp5cqVmjBhgmrXri1JWrdunfr166dGjRrpiy++sCzbuHHj5Orqqn79+ikqKkotWrRQWlqaUlNTNXbsWPXv39+ybEBOo2wBAADcYwICAvTtt9+qXr16DtujoqLUvn17p5lSKEnHjx/X1q1bVbJkSVWpUsXqOECO4pgtAACAe8zly5cVFBSUaXtgYKAuX75sQaJrUlJSFB4eroMHD9q3FStWTO3ataNo4Z5E2QIAALjH1KxZU++9956uXr1q33blyhWNGDFCNWvWtCyXu7u79uzZw6kEcN9gGiEAAMA9Zvfu3WrWrJmuXr2qKlWqyGazKSYmRp6enlq+fLkefvhhy7INHjxY7u7unFML9wXKFgAAwD3oypUrmj17tn777TcZhqEKFSqoU6dO8vLysjRXxiqJpUqVUrVq1eTj4+NwOysN415C2QIAALjHjBo1SkFBQerRo4fD9mnTpunMmTMaOnSoRclYaRj3F8oWAADAPaZEiRKaO3euatWq5bD9119/1fPPP68jR45YlAy4v7BABgAAwD0mLi5ORYoUybS9cOHCio2NtSARcH9yszoAAAAAclZoaKjWr1+vsLAwh+3r169XSEiIRan+35YtW7RgwQIdP35cycnJDrctXLjQolRAzmPPFgAAwD3mpZde0oABAxQZGaljx47p2LFjmjZtmgYOHKiePXtamm3+/PmqXbu29u3bp0WLFiklJUX79u3T6tWr5efnZ2k2IKdxzBYAAMA9xjAMvfnmm/r000/te47y5cunoUOH6t1337U0W+XKldWrVy/17t1bvr6+2rlzp8LCwtSrVy8VKVJEI0aMsDQfkJMoWwAAAPeoxMRE7d+/X15eXipdurQ8PT2tjiQfHx/t3btXJUqUUEBAgKKiolSpUiXt379f9evX55gy3FM4ZgsAAOAe9cADD+jxxx+3OoaDQoUK6eLFi5KkokWLas+ePapUqZIuXLigy5cvW5wOyFmULQAAAOSap556SitWrFClSpXUvn179e/fX6tXr9aKFSvUoEEDq+MBOYpphAAAAMg1586d09WrVxUSEqL09HT997//1bp161SqVCm98847KliwoNURgRxD2QIAAAAAEzCNEAAAALkqPT1dv//+u06fPq309HSH2+rUqWNRKiDnUbYAAACQazZt2qSOHTvq2LFjunGClc1mU1pamkXJgJzHNEIAAADkmkceeURlypTRiBEjVKRIEdlsNofbObEx7iWULQAAAOQaHx8f7dy5U6VKlbI6CmA6F6sDAAAA4P5RvXp1/f7771bHAHIFx2wBAADAVLt27bL/f9++fTV48GDFxcWpUqVKcnd3dxhbuXLl3I4HmIZphAAAADCVi4uLbDZbpgUxMmTcxgIZuNewZwsAAACmOnLkiNURAEuwZwsAAAC5ZtSoUQoKClKPHj0ctk+bNk1nzpzR0KFDLUoG5DwWyAAAAECumTx5ssqVK5dp+8MPP6xJkyZZkAgwD2ULAAAAuSYuLk5FihTJtL1w4cKKjY21IBFgHsoWAAAAck1oaKjWr1+fafv69esVEhJiQSLAPCyQAQAAgFzz0ksvacCAAUpJSVH9+vUlSatWrdIbb7yhwYMHW5wOyFkskAEAAIBcYxiG3nzzTX366adKTk6WJOXLl09Dhw7Vu+++a3E6IGdRtgAAAJDrEhMTtX//fnl5eal06dLy9PS0OhKQ4yhbAAAAAGACFsgAAAAAABNQtgAAAADABJQtAAAAADABZQsAgFxSokQJjR8/3uoYAIBcQtkCANw3Jk2aJF9fX6Wmptq3JSYmyt3dXU899ZTD2LVr18pms+ngwYO5HRMAcI+gbAEA7hvh4eFKTEzU1q1b7dvWrl2r4OBgbdmyRZcvX7Zvj46OVkhIiMqUKXNXj5GWlqb09PQcywwAyLsoWwCA+0bZsmUVEhKi6Oho+7bo6Gi1adNGJUuW1IYNGxy2h4eH6/z58+rSpYsKFiwob29vNWvWTIcOHbKPmz59ugoUKKD//e9/qlChgjw9PXXs2DGdPn1arVq1kpeXl8LCwjRnzpzcfKoAACdA2QIA3Ffq1aunqKgo+/WoqCjVq1dPdevWtW9PTk7Wxo0bFR4erm7dumnr1q368ccftXHjRhmGoebNmyslJcV+H5cvX9aoUaM0ZcoU7d27V4GBgerWrZuOHj2q1atX69tvv9XEiRN1+vTpXH++AADruFkdAACA3FSvXj0NHDhQqampunLlinbs2KE6deooLS1Nn376qSRp06ZNunLlip588km99NJLWr9+vWrVqiVJmjNnjkJDQ/X999/rueeekySlpKRo4sSJqlKliiTp4MGD+vnnn7Vp0yZVr15dkjR16lSVL1/egmcMALAKZQsAcF8JDw/XpUuXtGXLFp0/f15lypRRYGCg6tatq86dO+vSpUuKjo5WsWLFdODAAbm5udkLkyT5+/urbNmy2r9/v32bh4eHKleubL++f/9+ubm5qVq1avZt5cqVU4ECBXLlOQIAnANlCwBwXylVqpQefPBBRUVF6fz586pbt64kKTg4WGFhYVq/fr2ioqJUv359GYaR5X0YhiGbzWa/7uXl5XA94+uu3wYAuP9wzBYA4L4THh6u6OhoRUdHq169evbtdevW1bJly7Rp0yaFh4erQoUKSk1N1a+//mofc/bsWR08ePCWUwLLly+v1NRUh1UPDxw4oAsXLpjxdAAAToqyBQC474SHh2vdunWKiYmx79mSrpWtr776SlevXlV4eLhKly6tNm3aqGfPnlq3bp127typF198UUWLFlWbNm1uev9ly5ZV06ZN1bNnT/3666/atm2bXnrpJXl5eeXG0wMAOAnKFgDgvhMeHq4rV66oVKlSCgoKsm+vW7euLl68qJIlSyo0NFSSFBkZqapVq6ply5aqWbOmDMPQkiVL5O7ufsvHiIyMVGhoqOrWrat27drp5ZdfVmBgoKnPCwDgXGzGzSakAwAAAACyjT1bAAAAAGACyhYAAAAAmICyBQAAAAAmoGwBAAAAgAkoWwAAAABgAsoWAAAAAJiAsgUAAAAAJqBsAQAAAIAJKFsAAAAAYALKFgAAAACYgLIFAAAAACagbAEAAACACf4P640bYwSFqoUAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Label Distribution Visualization\n", "plt.figure(figsize=(8, 6))\n", "sns.countplot(data=df, x='label')\n", "plt.title('Label Distribution')\n", "plt.xlabel('Label')\n", "plt.ylabel('Count')\n", "plt.show()\n", "\n", "# Review Length Distribution Visualization\n", "chart = alt.Chart(df).mark_bar().encode(\n", " x=alt.X('review_length:Q', bin=True, title='Review Length'),\n", " y=alt.Y('count()', title='Frequency'),\n", " tooltip=[alt.Tooltip('review_length:Q', bin=True, title='Review Length'), 'count()']\n", ").properties(\n", " title='Distribution of Review Lengths'\n", ").interactive()\n", "\n", "chart.save('review_length_histogram.json')\n", "\n", "\n", "# Word Frequency Analysis (Top 20 Words)\n", "nltk.download('stopwords')\n", "from nltk.corpus import stopwords\n", "\n", "all_words = ' '.join(df['cleaned_text']).lower().split()\n", "stop_words = set(stopwords.words('english'))\n", "filtered_words = [word for word in all_words if word not in stop_words]\n", "word_freq = pd.Series(filtered_words).value_counts()\n", "\n", "plt.figure(figsize=(10, 8))\n", "word_freq[:20].plot(kind='bar')\n", "plt.title('Top 20 Most Frequent Words')\n", "plt.xlabel('Word')\n", "plt.ylabel('Frequency')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "a2b8434a-1227-4dca-becb-f226bc767aed", "metadata": {}, "source": [ "BASIC EDA" ] }, { "cell_type": "code", "execution_count": 2, "id": "849cc17e-d710-4c27-badc-8b03ff762c99", "metadata": { "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Repo card metadata block was not found. Setting CardData to empty.\n", "/opt/conda/envs/sagemaker-distribution/lib/python3.10/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", " warnings.warn(\n" ] } ], "source": [ "from datasets import load_dataset\n", "from transformers import AutoTokenizer, DataCollatorWithPadding\n", "\n", "raw_datasets = load_dataset(\"rohith2812/STANFORD-SENTIMENT-TREEBANK\")\n", "checkpoint = \"bert-base-cased\"\n", "tokenizer = AutoTokenizer.from_pretrained(checkpoint)\n", "\n", "\n", "def tokenize_function(example):\n", " return tokenizer(example[\"cleaned_text\"], truncation=True)\n", "\n", "\n", "tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)\n", "data_collator = DataCollatorWithPadding(tokenizer=tokenizer)" ] }, { "cell_type": "markdown", "id": "4225d5f3-c256-4b24-8d9d-99f562a8a29e", "metadata": {}, "source": [ "For have given the text files which contains movie reviews and its respective labels, i have cleaned the data and uploaded the data into hugging face and downloaded the same from hugging face for training the model. I have used the bert base cased model as given and imported the same tokenizer and applied the tokenized function." ] }, { "cell_type": "code", "execution_count": 3, "id": "657a47c3-f906-4f18-bed7-a8c7918fd00f", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "DatasetDict({\n", " train: Dataset({\n", " features: ['label', 'cleaned_text', 'input_ids', 'token_type_ids', 'attention_mask'],\n", " num_rows: 8544\n", " })\n", " validation: Dataset({\n", " features: ['label', 'cleaned_text', 'input_ids', 'token_type_ids', 'attention_mask'],\n", " num_rows: 1101\n", " })\n", "})" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tokenized_datasets" ] }, { "cell_type": "markdown", "id": "6d187a8f-21bc-4d33-a9d7-b9a3ce78452b", "metadata": {}, "source": [ "This are after applying the tokenizzer, it converted the respective text into tensors labeled as input_ids, along with that it has token_type_ids and attention_mask." ] }, { "cell_type": "code", "execution_count": 4, "id": "3ee93984-71c1-42b6-9f9f-4c992594efb2", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "['labels', 'input_ids', 'token_type_ids', 'attention_mask']" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tokenized_datasets = tokenized_datasets.remove_columns([\"cleaned_text\"])\n", "tokenized_datasets = tokenized_datasets.rename_column(\"label\", \"labels\")\n", "tokenized_datasets.set_format(\"torch\")\n", "tokenized_datasets[\"train\"].column_names" ] }, { "cell_type": "markdown", "id": "e2d52f3b-5a2d-4245-9e4e-af7570ac0daf", "metadata": {}, "source": [ "As the model takes only the tenosors(numerical representation) i have dropped the column cleaned_text" ] }, { "cell_type": "code", "execution_count": 5, "id": "b61ac8d0-ebdb-4237-9d77-19ab850a8171", "metadata": { "tags": [] }, "outputs": [], "source": [ "from torch.utils.data import DataLoader\n", "\n", "train_dataloader = DataLoader(\n", " tokenized_datasets[\"train\"], shuffle=True, batch_size=8, collate_fn=data_collator\n", ")\n", "eval_dataloader = DataLoader(\n", " tokenized_datasets[\"validation\"], batch_size=8, collate_fn=data_collator\n", ")" ] }, { "cell_type": "markdown", "id": "867d62c9-3bbc-4225-a28f-729c228dca89", "metadata": {}, "source": [ "Applied batching and i chose to applying the padding after batching so that theres no need to look for the maximum length of the text of entire dataset" ] }, { "cell_type": "code", "execution_count": 6, "id": "38945319-426f-4b34-9b56-5493776ef67f", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "{'labels': torch.Size([8]),\n", " 'input_ids': torch.Size([8, 66]),\n", " 'token_type_ids': torch.Size([8, 66]),\n", " 'attention_mask': torch.Size([8, 66])}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for batch in train_dataloader:\n", " break\n", "{k: v.shape for k, v in batch.items()}" ] }, { "cell_type": "markdown", "id": "48925639-53dd-42cd-ac81-ae5ccff11abe", "metadata": {}, "source": [ "for a single batch the maximum length is 66 after padding" ] }, { "cell_type": "code", "execution_count": 7, "id": "2fd4700a-fd3e-4217-9ed0-57ec3e3e69a1", "metadata": { "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-cased and are newly initialized: ['classifier.bias', 'classifier.weight']\n", "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n" ] } ], "source": [ "from transformers import AutoModelForSequenceClassification\n", "\n", "model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=5)" ] }, { "cell_type": "code", "execution_count": 8, "id": "861cf7ce-8067-4773-ba1b-fd0f748f77b4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor(1.6697, grad_fn=) torch.Size([8, 5])\n" ] } ], "source": [ "outputs = model(**batch)\n", "print(outputs.loss, outputs.logits.shape)" ] }, { "cell_type": "code", "execution_count": 30, "id": "6e917908-2096-4f7c-a208-ecffd63b2e93", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "BertForSequenceClassification(\n", " (bert): BertModel(\n", " (embeddings): BertEmbeddings(\n", " (word_embeddings): Embedding(28996, 768, padding_idx=0)\n", " (position_embeddings): Embedding(512, 768)\n", " (token_type_embeddings): Embedding(2, 768)\n", " (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", " (dropout): Dropout(p=0.1, inplace=False)\n", " )\n", " (encoder): BertEncoder(\n", " (layer): ModuleList(\n", " (0-11): 12 x BertLayer(\n", " (attention): BertAttention(\n", " (self): BertSelfAttention(\n", " (query): Linear(in_features=768, out_features=768, bias=True)\n", " (key): Linear(in_features=768, out_features=768, bias=True)\n", " (value): Linear(in_features=768, out_features=768, bias=True)\n", " (dropout): Dropout(p=0.1, inplace=False)\n", " )\n", " (output): BertSelfOutput(\n", " (dense): Linear(in_features=768, out_features=768, bias=True)\n", " (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", " (dropout): Dropout(p=0.1, inplace=False)\n", " )\n", " )\n", " (intermediate): BertIntermediate(\n", " (dense): Linear(in_features=768, out_features=3072, bias=True)\n", " (intermediate_act_fn): GELUActivation()\n", " )\n", " (output): BertOutput(\n", " (dense): Linear(in_features=3072, out_features=768, bias=True)\n", " (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", " (dropout): Dropout(p=0.1, inplace=False)\n", " )\n", " )\n", " )\n", " )\n", " (pooler): BertPooler(\n", " (dense): Linear(in_features=768, out_features=768, bias=True)\n", " (activation): Tanh()\n", " )\n", " )\n", " (dropout): Dropout(p=0.1, inplace=False)\n", " (classifier): Linear(in_features=768, out_features=5, bias=True)\n", ")" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import torch\n", "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", "model.to(device)" ] }, { "cell_type": "markdown", "id": "e146bd01-f29b-464d-9201-bfa81b50bb6e", "metadata": {}, "source": [ "These are layers present in the bert base cased model, i just used this model and fine tuned the weights based on the dataset " ] }, { "cell_type": "code", "execution_count": 9, "id": "4118cc0b-f212-4081-960f-ffd36193e76f", "metadata": { "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_833/768120370.py:6: FutureWarning: load_metric is deprecated and will be removed in the next major version of datasets. Use 'evaluate.load' instead, from the new library 🤗 Evaluate: https://huggingface.co/docs/evaluate\n", " accuracy_metric = load_metric(\"accuracy\")\n", "/opt/conda/envs/sagemaker-distribution/lib/python3.10/site-packages/datasets/load.py:759: FutureWarning: The repository for accuracy contains custom code which must be executed to correctly load the metric. You can inspect the repository content at https://raw.githubusercontent.com/huggingface/datasets/2.19.1/metrics/accuracy/accuracy.py\n", "You can avoid this message in future by passing the argument `trust_remote_code=True`.\n", "Passing `trust_remote_code=True` will be mandatory to load this metric from the next major release of `datasets`.\n", " warnings.warn(\n", "/opt/conda/envs/sagemaker-distribution/lib/python3.10/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", " warnings.warn(\n", "Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-cased and are newly initialized: ['classifier.bias', 'classifier.weight']\n", "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n", "/opt/conda/envs/sagemaker-distribution/lib/python3.10/site-packages/transformers/optimization.py:521: FutureWarning: This implementation of AdamW is deprecated and will be removed in a future version. Use the PyTorch implementation torch.optim.AdamW instead, or set `no_deprecation_warning=True` to disable this warning\n", " warnings.warn(\n", " 20%|█▉ | 1067/5340 [01:24<05:11, 13.70it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/5\n", "Training loss: 0.1617\n", "Training accuracy: 0.4283\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 20%|██ | 1069/5340 [01:27<34:42, 2.05it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Validation loss: 0.1447\n", "Validation accuracy: 0.4923\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 40%|███▉ | 2135/5340 [02:52<04:31, 11.80it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 2/5\n", "Training loss: 0.1235\n", "Training accuracy: 0.5757\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 40%|████ | 2137/5340 [02:55<26:35, 2.01it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Validation loss: 0.1471\n", "Validation accuracy: 0.4832\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 60%|█████▉ | 3203/5340 [04:20<03:01, 11.76it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 3/5\n", "Training loss: 0.0836\n", "Training accuracy: 0.7230\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 60%|██████ | 3205/5340 [04:23<17:41, 2.01it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Validation loss: 0.1719\n", "Validation accuracy: 0.4796\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 80%|███████▉ | 4271/5340 [05:48<01:21, 13.05it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4/5\n", "Training loss: 0.0446\n", "Training accuracy: 0.8708\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " 80%|████████ | 4273/5340 [05:51<08:47, 2.02it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Validation loss: 0.2328\n", "Validation accuracy: 0.4650\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|█████████▉| 5339/5340 [07:16<00:00, 12.57it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 5/5\n", "Training loss: 0.0176\n", "Training accuracy: 0.9556\n", "Validation loss: 0.2825\n", "Validation accuracy: 0.4650\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 5340/5340 [07:30<00:00, 12.57it/s]" ] } ], "source": [ "import torch\n", "from tqdm import tqdm\n", "from datasets import load_metric\n", "\n", "# Load accuracy metric\n", "accuracy_metric = load_metric(\"accuracy\")\n", "\n", "from accelerate import Accelerator\n", "from transformers import AdamW, AutoModelForSequenceClassification, get_scheduler\n", "\n", "# Initialize Accelerator\n", "accelerator = Accelerator()\n", "\n", "# Load the model and tokenizer\n", "model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=5)\n", "optimizer = AdamW(model.parameters(), lr=5e-5)\n", "\n", "# Prepare the dataloaders and model with Accelerator\n", "train_dl, eval_dl, model, optimizer = accelerator.prepare(\n", " train_dataloader, eval_dataloader, model, optimizer\n", ")\n", "\n", "\n", "num_epochs = 5 \n", "num_training_steps = num_epochs * len(train_dl)\n", "lr_scheduler = get_scheduler(\n", " \"linear\",\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=num_training_steps,\n", ")\n", "\n", "progress_bar = tqdm(range(num_training_steps))\n", "\n", "for epoch in range(num_epochs):\n", " model.train() # Ensure the model is in training mode\n", " \n", " total_loss = 0\n", " total_correct = 0\n", " num_samples = 0\n", " \n", " for batch in train_dl:\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " predictions = outputs.logits.argmax(dim=-1)\n", " labels = batch[\"labels\"]\n", "\n", " total_loss += loss.item()\n", " total_correct += (predictions == labels).sum().item()\n", " num_samples += len(labels)\n", "\n", " accelerator.backward(loss)\n", "\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", " progress_bar.update(1)\n", "\n", " avg_loss = total_loss / num_samples\n", " accuracy = total_correct / num_samples\n", "\n", " print(f\"Epoch {epoch + 1}/{num_epochs}\")\n", " print(f\"Training loss: {avg_loss:.4f}\")\n", " print(f\"Training accuracy: {accuracy:.4f}\")\n", "\n", " # Evaluate on the validation set\n", " model.eval() # Set the model to evaluation mode\n", " \n", " total_eval_loss = 0\n", " total_eval_correct = 0\n", " num_eval_samples = 0\n", " \n", " for batch in eval_dl:\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " predictions = outputs.logits.argmax(dim=-1)\n", " labels = batch[\"labels\"]\n", " \n", " total_eval_loss += loss.item()\n", " total_eval_correct += (predictions == labels).sum().item()\n", " num_eval_samples += len(labels)\n", " \n", " avg_eval_loss = total_eval_loss / num_eval_samples\n", " eval_accuracy = total_eval_correct / num_eval_samples\n", "\n", " print(f\"Validation loss: {avg_eval_loss:.4f}\")\n", " print(f\"Validation accuracy: {eval_accuracy:.4f}\")" ] }, { "cell_type": "markdown", "id": "30cf2072-c55d-4463-917e-261097c5157d", "metadata": {}, "source": [ "Fine Tuned the model here, used the adamw optimizer and learning rate of 5e-5, first i have uised 3e-5 but the results weren't promising so changed it to 5e-5, also updated the num_epochs from 3 to 5.\n", "used linear method for backward propagation to learn the weights. once the model is applied we will get the outputs in the form of logits so used agmax to convert the logits better understand the output.\n", "\n", "observing the pattern of training accuracy and validation accuracy, the training accuracy went on increased and validation accuracy started decreased from epoch 3 which suggests the model might be overfitting." ] }, { "cell_type": "code", "execution_count": 10, "id": "58ef7c5e-a3ac-4bf2-b18b-126f38a0555a", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Validation loss: 0.2825\n", "Validation accuracy: 0.4650\n" ] } ], "source": [ " model.eval()\n", " total_eval_loss = 0\n", " total_eval_correct = 0\n", " num_eval_samples = 0\n", " \n", " for batch in eval_dl:\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " predictions = outputs.logits.argmax(dim=-1)\n", " labels = batch[\"labels\"]\n", " \n", " total_eval_loss += loss.item()\n", " total_eval_correct += (predictions == labels).sum().item()\n", " num_eval_samples += len(labels)\n", " \n", " avg_eval_loss = total_eval_loss / num_eval_samples\n", " eval_accuracy = total_eval_correct / num_eval_samples\n", "\n", " print(f\"Validation loss: {avg_eval_loss:.4f}\")\n", " print(f\"Validation accuracy: {eval_accuracy:.4f}\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "066cfa8b-e9e2-4ca2-a03a-dda0d6a059b6", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Review: Prabhas' latest film, Kalki, is nothing short of a cinematic marvel that transcends the boundaries of conventional storytelling. This epic saga, directed by the visionary filmmaker Nag Ashwin, masterfully blends mythology, action, and drama to create a mesmerizing experience for audiences.\n", "Predicted Label: 4 (Very Positive)\n" ] } ], "source": [ "\n", "review_text = \"Prabhas' latest film, Kalki, is nothing short of a cinematic marvel that transcends the boundaries of conventional storytelling. This epic saga, directed by the visionary filmmaker Nag Ashwin, masterfully blends mythology, action, and drama to create a mesmerizing experience for audiences.\"\n", "\n", "inputs = tokenizer(review_text, return_tensors=\"pt\", padding=True, truncation=True)\n", "\n", "# Move tensors to the same device as the model\n", "inputs = {key: value.to(model.device) for key, value in inputs.items()}\n", "\n", "# Perform inference\n", "with torch.no_grad():\n", " outputs = model(**inputs)\n", " logits = outputs.logits\n", " predictions = logits.argmax(dim=-1)\n", "\n", "# Define a mapping from label indices to sentiment\n", "label_map = {\n", " 0: \"Very Negative\",\n", " 1: \"Negative\",\n", " 2: \"Neutral\",\n", " 3: \"Positive\",\n", " 4: \"Very Positive\"\n", "}\n", "\n", "# Get the predicted label\n", "predicted_label = predictions.item()\n", "predicted_sentiment = label_map[predicted_label]\n", "\n", "print(f\"Review: {review_text}\")\n", "print(f\"Predicted Label: {predicted_label} ({predicted_sentiment})\")\n" ] }, { "cell_type": "markdown", "id": "68ab95c0-1c70-4c38-acda-e4d697744fdd", "metadata": {}, "source": [ "Tested the model on recently released kalki review and it performed well" ] }, { "cell_type": "code", "execution_count": null, "id": "fd6b72c9-07a9-4729-a96c-4d785b18095b", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "sagemaker-distribution:Python", "language": "python", "name": "conda-env-sagemaker-distribution-py" }, "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.10.14" } }, "nbformat": 4, "nbformat_minor": 5 }