{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "tYNpi1MX7FmW" }, "source": [ "<div style='text-align: center;'>\n", " <img src='https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQzJzIHdangJTrH2mFXFgsLjuLCjpfXXwbxg&usqp=CAU' width='100'/>\n", " <h1>Sharif University of Technology</h1>\n", " <h2>Natural Language Processing</h2>\n", " <h3>Final Project</h3>\n", " <h4>Spoiler classification and summary generation</h4>\n", " <p><strong>Authors:</strong> Ali Nikkhah, Ramtin Khoshnevis, Sarina Zahedi</p>\n", " <p><strong>(Equal Contribution)</strong></p>\n", "</div>\n", "<hr/>\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "shi9eHWZaUNq", "outputId": "f70d8fff-e62f-4bc2-b0fe-5ec2d9592c89" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting datasets\n", " Downloading datasets-2.21.0-py3-none-any.whl.metadata (21 kB)\n", "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from datasets) (3.15.4)\n", "Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.10/dist-packages (from datasets) (1.26.4)\n", "Collecting pyarrow>=15.0.0 (from datasets)\n", " Downloading pyarrow-17.0.0-cp310-cp310-manylinux_2_28_x86_64.whl.metadata (3.3 kB)\n", "Collecting dill<0.3.9,>=0.3.0 (from datasets)\n", " Downloading dill-0.3.8-py3-none-any.whl.metadata (10 kB)\n", "Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from datasets) (2.1.4)\n", "Requirement already satisfied: requests>=2.32.2 in /usr/local/lib/python3.10/dist-packages (from datasets) (2.32.3)\n", "Requirement already satisfied: tqdm>=4.66.3 in /usr/local/lib/python3.10/dist-packages (from datasets) (4.66.5)\n", "Collecting xxhash (from datasets)\n", " Downloading xxhash-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (12 kB)\n", "Collecting multiprocess (from datasets)\n", " Downloading multiprocess-0.70.16-py310-none-any.whl.metadata (7.2 kB)\n", "Requirement already satisfied: fsspec<=2024.6.1,>=2023.1.0 in /usr/local/lib/python3.10/dist-packages (from fsspec[http]<=2024.6.1,>=2023.1.0->datasets) (2024.6.1)\n", "Requirement already satisfied: aiohttp in /usr/local/lib/python3.10/dist-packages (from datasets) (3.10.2)\n", "Requirement already satisfied: huggingface-hub>=0.21.2 in /usr/local/lib/python3.10/dist-packages (from datasets) (0.23.5)\n", "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from datasets) (24.1)\n", "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from datasets) (6.0.2)\n", "Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (2.3.5)\n", "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (1.3.1)\n", "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (24.2.0)\n", "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (1.4.1)\n", "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (6.0.5)\n", "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (1.9.4)\n", "Requirement already satisfied: async-timeout<5.0,>=4.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (4.0.3)\n", "Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.21.2->datasets) (4.12.2)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.32.2->datasets) (3.3.2)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.32.2->datasets) (3.7)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.32.2->datasets) (2.0.7)\n", "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests>=2.32.2->datasets) (2024.7.4)\n", "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets) (2.8.2)\n", "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets) (2024.1)\n", "Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets) (2024.1)\n", "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.2->pandas->datasets) (1.16.0)\n", "Downloading datasets-2.21.0-py3-none-any.whl (527 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m527.3/527.3 kB\u001b[0m \u001b[31m9.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hDownloading dill-0.3.8-py3-none-any.whl (116 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m116.3/116.3 kB\u001b[0m \u001b[31m11.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hDownloading pyarrow-17.0.0-cp310-cp310-manylinux_2_28_x86_64.whl (39.9 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m39.9/39.9 MB\u001b[0m \u001b[31m18.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hDownloading multiprocess-0.70.16-py310-none-any.whl (134 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m134.8/134.8 kB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hDownloading xxhash-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (194 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m194.1/194.1 kB\u001b[0m \u001b[31m16.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hInstalling collected packages: xxhash, pyarrow, dill, multiprocess, datasets\n", " Attempting uninstall: pyarrow\n", " Found existing installation: pyarrow 14.0.2\n", " Uninstalling pyarrow-14.0.2:\n", " Successfully uninstalled pyarrow-14.0.2\n", "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", "cudf-cu12 24.4.1 requires pyarrow<15.0.0a0,>=14.0.1, but you have pyarrow 17.0.0 which is incompatible.\n", "ibis-framework 8.0.0 requires pyarrow<16,>=2, but you have pyarrow 17.0.0 which is incompatible.\u001b[0m\u001b[31m\n", "\u001b[0mSuccessfully installed datasets-2.21.0 dill-0.3.8 multiprocess-0.70.16 pyarrow-17.0.0 xxhash-3.4.1\n" ] } ], "source": [ "!pip install datasets" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "3GvN0W_o5lCV", "outputId": "acf96d10-3d87-4369-9920-5ce825f16710" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: kaggle in /usr/local/lib/python3.10/dist-packages (1.6.17)\n", "Requirement already satisfied: six>=1.10 in /usr/local/lib/python3.10/dist-packages (from kaggle) (1.16.0)\n", "Requirement already satisfied: certifi>=2023.7.22 in /usr/local/lib/python3.10/dist-packages (from kaggle) (2024.7.4)\n", "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.10/dist-packages (from kaggle) (2.8.2)\n", "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from kaggle) (2.32.3)\n", "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from kaggle) (4.66.5)\n", "Requirement already satisfied: python-slugify in /usr/local/lib/python3.10/dist-packages (from kaggle) (8.0.4)\n", "Requirement already satisfied: urllib3 in /usr/local/lib/python3.10/dist-packages (from kaggle) (2.0.7)\n", "Requirement already satisfied: bleach in /usr/local/lib/python3.10/dist-packages (from kaggle) (6.1.0)\n", "Requirement already satisfied: webencodings in /usr/local/lib/python3.10/dist-packages (from bleach->kaggle) (0.5.1)\n", "Requirement already satisfied: text-unidecode>=1.3 in /usr/local/lib/python3.10/dist-packages (from python-slugify->kaggle) (1.3)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->kaggle) (3.3.2)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->kaggle) (3.7)\n" ] } ], "source": [ "!pip install kaggle" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "YbqRqUMT7cuE", "outputId": "320e8152-397a-41fe-ee9f-4b3cfdb98037" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cp: cannot stat 'kaggle.json': No such file or directory\n", "chmod: cannot access '/root/.kaggle/kaggle.json': No such file or directory\n", "Dataset URL: https://www.kaggle.com/datasets/rmisra/imdb-spoiler-dataset\n", "License(s): Attribution 4.0 International (CC BY 4.0)\n", "Downloading imdb-spoiler-dataset.zip to /content\n", "100% 330M/331M [00:18<00:00, 23.0MB/s]\n", "100% 331M/331M [00:18<00:00, 19.1MB/s]\n" ] } ], "source": [ "!mkdir -p ~/.kaggle\n", "!cp kaggle.json ~/.kaggle/\n", "!chmod 600 ~/.kaggle/kaggle.json\n", "\n", "# Download the dataset\n", "!kaggle datasets download -d rmisra/imdb-spoiler-dataset" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "fAIBnB8I7jIv", "outputId": "ba9dc80c-26c0-4ade-f22e-a4f4405e1dea" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Archive: imdb-spoiler-dataset.zip\n", " inflating: IMDB_movie_details.json \n", " inflating: IMDB_reviews.json \n", "IMDB_movie_details.json IMDB_reviews.json imdb-spoiler-dataset.zip sample_data\n" ] } ], "source": [ "!unzip imdb-spoiler-dataset.zip\n", "!ls" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 538 }, "id": "7dTJhfAd76Qu", "outputId": "bb68ad6b-8364-44ad-8ba7-1dca651499f9" }, "outputs": [ { "data": { "application/vnd.google.colaboratory.intrinsic+json": { "type": "dataframe", "variable_name": "reviews_df" }, "text/html": [ "\n", " <div id=\"df-3c86f47a-cc4a-4e79-94c4-74e8426404ea\" class=\"colab-df-container\">\n", " <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>review_date</th>\n", " <th>movie_id</th>\n", " <th>user_id</th>\n", " <th>is_spoiler</th>\n", " <th>review_text</th>\n", " <th>rating</th>\n", " <th>review_summary</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>10 February 2006</td>\n", " <td>tt0111161</td>\n", " <td>ur1898687</td>\n", " <td>True</td>\n", " <td>In its Oscar year, Shawshank Redemption (writt...</td>\n", " <td>10</td>\n", " <td>A classic piece of unforgettable film-making.</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>6 September 2000</td>\n", " <td>tt0111161</td>\n", " <td>ur0842118</td>\n", " <td>True</td>\n", " <td>The Shawshank Redemption is without a doubt on...</td>\n", " <td>10</td>\n", " <td>Simply amazing. The best film of the 90's.</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>3 August 2001</td>\n", " <td>tt0111161</td>\n", " <td>ur1285640</td>\n", " <td>True</td>\n", " <td>I believe that this film is the best story eve...</td>\n", " <td>8</td>\n", " <td>The best story ever told on film</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>1 September 2002</td>\n", " <td>tt0111161</td>\n", " <td>ur1003471</td>\n", " <td>True</td>\n", " <td>**Yes, there are SPOILERS here**This film has ...</td>\n", " <td>10</td>\n", " <td>Busy dying or busy living?</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>20 May 2004</td>\n", " <td>tt0111161</td>\n", " <td>ur0226855</td>\n", " <td>True</td>\n", " <td>At the heart of this extraordinary movie is a ...</td>\n", " <td>8</td>\n", " <td>Great story, wondrously told and acted</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>\n", " <div class=\"colab-df-buttons\">\n", "\n", " <div class=\"colab-df-container\">\n", " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-3c86f47a-cc4a-4e79-94c4-74e8426404ea')\"\n", " title=\"Convert this dataframe to an interactive table.\"\n", " style=\"display:none;\">\n", "\n", " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n", " <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n", " </svg>\n", " </button>\n", "\n", " <style>\n", " .colab-df-container {\n", " display:flex;\n", " gap: 12px;\n", " }\n", "\n", " .colab-df-convert {\n", " background-color: #E8F0FE;\n", " border: none;\n", " border-radius: 50%;\n", " cursor: pointer;\n", " display: none;\n", " fill: #1967D2;\n", " height: 32px;\n", " padding: 0 0 0 0;\n", " width: 32px;\n", " }\n", "\n", " .colab-df-convert:hover {\n", " background-color: #E2EBFA;\n", " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", " fill: #174EA6;\n", " }\n", "\n", " .colab-df-buttons div {\n", " margin-bottom: 4px;\n", " }\n", "\n", " [theme=dark] .colab-df-convert {\n", " background-color: #3B4455;\n", " fill: #D2E3FC;\n", " }\n", "\n", " [theme=dark] .colab-df-convert:hover {\n", " background-color: #434B5C;\n", " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", " fill: #FFFFFF;\n", " }\n", " </style>\n", "\n", " <script>\n", " const buttonEl =\n", " document.querySelector('#df-3c86f47a-cc4a-4e79-94c4-74e8426404ea button.colab-df-convert');\n", " buttonEl.style.display =\n", " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", "\n", " async function convertToInteractive(key) {\n", " const element = document.querySelector('#df-3c86f47a-cc4a-4e79-94c4-74e8426404ea');\n", " const dataTable =\n", " await google.colab.kernel.invokeFunction('convertToInteractive',\n", " [key], {});\n", " if (!dataTable) return;\n", "\n", " const docLinkHtml = 'Like what you see? Visit the ' +\n", " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", " + ' to learn more about interactive tables.';\n", " element.innerHTML = '';\n", " dataTable['output_type'] = 'display_data';\n", " await google.colab.output.renderOutput(dataTable, element);\n", " const docLink = document.createElement('div');\n", " docLink.innerHTML = docLinkHtml;\n", " element.appendChild(docLink);\n", " }\n", " </script>\n", " </div>\n", "\n", "\n", "<div id=\"df-8e53e93f-562f-4c0a-9edf-098685085d94\">\n", " <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-8e53e93f-562f-4c0a-9edf-098685085d94')\"\n", " title=\"Suggest charts\"\n", " style=\"display:none;\">\n", "\n", "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", " width=\"24px\">\n", " <g>\n", " <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n", " </g>\n", "</svg>\n", " </button>\n", "\n", "<style>\n", " .colab-df-quickchart {\n", " --bg-color: #E8F0FE;\n", " --fill-color: #1967D2;\n", " --hover-bg-color: #E2EBFA;\n", " --hover-fill-color: #174EA6;\n", " --disabled-fill-color: #AAA;\n", " --disabled-bg-color: #DDD;\n", " }\n", "\n", " [theme=dark] .colab-df-quickchart {\n", " --bg-color: #3B4455;\n", " --fill-color: #D2E3FC;\n", " --hover-bg-color: #434B5C;\n", " --hover-fill-color: #FFFFFF;\n", " --disabled-bg-color: #3B4455;\n", " --disabled-fill-color: #666;\n", " }\n", "\n", " .colab-df-quickchart {\n", " background-color: var(--bg-color);\n", " border: none;\n", " border-radius: 50%;\n", " cursor: pointer;\n", " display: none;\n", " fill: var(--fill-color);\n", " height: 32px;\n", " padding: 0;\n", " width: 32px;\n", " }\n", "\n", " .colab-df-quickchart:hover {\n", " background-color: var(--hover-bg-color);\n", " box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n", " fill: var(--button-hover-fill-color);\n", " }\n", "\n", " .colab-df-quickchart-complete:disabled,\n", " .colab-df-quickchart-complete:disabled:hover {\n", " background-color: var(--disabled-bg-color);\n", " fill: var(--disabled-fill-color);\n", " box-shadow: none;\n", " }\n", "\n", " .colab-df-spinner {\n", " border: 2px solid var(--fill-color);\n", " border-color: transparent;\n", " border-bottom-color: var(--fill-color);\n", " animation:\n", " spin 1s steps(1) infinite;\n", " }\n", "\n", " @keyframes spin {\n", " 0% {\n", " border-color: transparent;\n", " border-bottom-color: var(--fill-color);\n", " border-left-color: var(--fill-color);\n", " }\n", " 20% {\n", " border-color: transparent;\n", " border-left-color: var(--fill-color);\n", " border-top-color: var(--fill-color);\n", " }\n", " 30% {\n", " border-color: transparent;\n", " border-left-color: var(--fill-color);\n", " border-top-color: var(--fill-color);\n", " border-right-color: var(--fill-color);\n", " }\n", " 40% {\n", " border-color: transparent;\n", " border-right-color: var(--fill-color);\n", " border-top-color: var(--fill-color);\n", " }\n", " 60% {\n", " border-color: transparent;\n", " border-right-color: var(--fill-color);\n", " }\n", " 80% {\n", " border-color: transparent;\n", " border-right-color: var(--fill-color);\n", " border-bottom-color: var(--fill-color);\n", " }\n", " 90% {\n", " border-color: transparent;\n", " border-bottom-color: var(--fill-color);\n", " }\n", " }\n", "</style>\n", "\n", " <script>\n", " async function quickchart(key) {\n", " const quickchartButtonEl =\n", " document.querySelector('#' + key + ' button');\n", " quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n", " quickchartButtonEl.classList.add('colab-df-spinner');\n", " try {\n", " const charts = await google.colab.kernel.invokeFunction(\n", " 'suggestCharts', [key], {});\n", " } catch (error) {\n", " console.error('Error during call to suggestCharts:', error);\n", " }\n", " quickchartButtonEl.classList.remove('colab-df-spinner');\n", " quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n", " }\n", " (() => {\n", " let quickchartButtonEl =\n", " document.querySelector('#df-8e53e93f-562f-4c0a-9edf-098685085d94 button');\n", " quickchartButtonEl.style.display =\n", " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", " })();\n", " </script>\n", "</div>\n", "\n", " </div>\n", " </div>\n" ], "text/plain": [ " review_date movie_id user_id is_spoiler \\\n", "0 10 February 2006 tt0111161 ur1898687 True \n", "1 6 September 2000 tt0111161 ur0842118 True \n", "2 3 August 2001 tt0111161 ur1285640 True \n", "3 1 September 2002 tt0111161 ur1003471 True \n", "4 20 May 2004 tt0111161 ur0226855 True \n", "\n", " review_text rating \\\n", "0 In its Oscar year, Shawshank Redemption (writt... 10 \n", "1 The Shawshank Redemption is without a doubt on... 10 \n", "2 I believe that this film is the best story eve... 8 \n", "3 **Yes, there are SPOILERS here**This film has ... 10 \n", "4 At the heart of this extraordinary movie is a ... 8 \n", "\n", " review_summary \n", "0 A classic piece of unforgettable film-making. \n", "1 Simply amazing. The best film of the 90's. \n", "2 The best story ever told on film \n", "3 Busy dying or busy living? \n", "4 Great story, wondrously told and acted " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "reviews_df = pd.read_json('IMDB_reviews.json' , lines=True)\n", "reviews_df.head()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "tGnVLhg-N0Me", "outputId": "08cdf747-c2fe-4438-d09e-0bc46f34ddcf" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total number of rows in the dataset: 573913\n" ] } ], "source": [ "print(f\"Total number of rows in the dataset: {reviews_df.shape[0]}\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ma4EVw06eMbK", "outputId": "6c4fcd54-d166-4bb0-b6c6-c6dfc863b8d3" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total reviews: 573913\n", "Number of spoiler reviews: 150924\n", "Number of non-spoiler reviews: 422989\n", "Average review length: 1460.5535246631457\n", "Median review length: 1052.0\n", "is_spoiler\n", "False 0.737026\n", "True 0.262974\n", "Name: proportion, dtype: float64\n" ] } ], "source": [ "import pandas as pd\n", "\n", "print(\"Total reviews:\", len(reviews_df))\n", "print(\"Number of spoiler reviews:\", reviews_df['is_spoiler'].sum())\n", "print(\"Number of non-spoiler reviews:\", len(reviews_df) - reviews_df['is_spoiler'].sum())\n", "\n", "reviews_df['review_length'] = reviews_df['review_text'].apply(len)\n", "print(\"Average review length:\", reviews_df['review_length'].mean())\n", "print(\"Median review length:\", reviews_df['review_length'].median())\n", "\n", "print(reviews_df['is_spoiler'].value_counts(normalize=True))\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "2AtkJ_uGr5o-" }, "outputs": [], "source": [ "reviews_df = reviews_df[:175000]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "XLF5DCd9jdYo", "outputId": "326f551c-d069-4d4a-ab66-f82c9a302eb4" }, "outputs": [ { "data": { "text/plain": [ "428" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(set(reviews_df['movie_id']))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "10Kz-73LrNZM", "outputId": "764c23d4-905d-47aa-92ce-c0c7fdd18cb2" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "<ipython-input-10-ad5e2d5c4829>:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " reviews_df['review_length'] = reviews_df['review_text'].apply(len)\n" ] } ], "source": [ "reviews_df['review_length'] = reviews_df['review_text'].apply(len)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 472 }, "id": "GgxuKkb8e24K", "outputId": "31db9f6d-44f4-4ab3-ec3a-55dfb73f8c08" }, "outputs": [ { "data": { "image/png": "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sWDBAhQUFCAhIaHMumVE1YkTxomIyCr16tULP//8M3Q6HdRqNcLDwzF9+nQGJ7I49jwRERERVQDnPBERERFVAMMTERERUQVwzpOZGAwGXL16FS4uLmZ/rAYRERFVDSEEsrKy4OfnV+bB4nfD8GQmV69eLfPwSyIiIqoZLl26BH9//wdqy/BkJsZHP1y6dAkajcbC1RAREdGDyMzMREBAQIUe4cTwZCbGoTqNRsPwREREVMNUZMoNJ4wTERERVQDDExEREVEFMDwRERERVQDDExEREVEFMDwRERERVQDDExEREVEFMDwRERERVQDDExEREVEFMDwRERERVQDDExEREVEFMDwRERERVQDDExEREVEFMDwRERERVQDDE5k4nZKFlMx8S5dBRERktRieSJKamY+oL3di4Hd7LV0KERGR1WJ4IsmRKxko0gv8cy0HuYXFli6HiIjIKjE8keRsarb050tpeRashIiIyHoxPJHENDzlWrASIiIi68XwRJIzpcPTTYYnIiKi8jA8EQBACIFzpcJTEnueiIiIysXwRACA1KwCZBXcniTOOU9ERETlY3giAMCZlGyT95c5bEdERFQuhicCAJxNzQIANPRyAlAybCeEsGRJREREVonhiQAAZ6+V9Dx1b+INAMgt1CMtp9CSJREREVklhicCcHvYroWfBlqNPQDg0k3OeyIiIroTwxMBAM7d6nkK9nZGgIcDAN5xR0REVB6GJ8LNnEJczy4Zomvo5YwAd0cAXCiTiIioPAxPJM13quvmACe1EgEeJeGJd9wRERGVxfBE+OdWeGpw6047Y3jisB0REVFZDE+E9NwiAICXixoAEOBeMueJC2USERGVxfBEyCnUAwAcVQoAQL06JT1PV9PzUKw3WKwuIiIia8TwRMgrLHksi5NKCQDwcbGHSiFHsUEgOSPfkqURERFZHYYnKtXzVBKe5HIZfFxLhvBSsxieiIiISrNoeFqwYAFatWoFjUYDjUaD8PBw/PXXX9L+7t27QyaTmbyGDx9ucoykpCRERUXB0dER3t7eGDt2LIqLi03abNu2DW3btoVarUZwcDCWLFlSppb58+ejfv36sLe3R4cOHbB///4q+c7WKPfWA4Gd1Appm5uDCgCQkVdkkZqIiIislUXDk7+/Pz799FPEx8fj4MGDePzxx/HMM8/g2LFjUps33ngDycnJ0mvm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8GTDHmjYzq7kn0gBHwxMREQEgOHJplVk2C6/SA8hRLXURUREZM0YnmzYgw3blewTuH13HhERkS1jeLJhxvCkukd4UirkUMhLhvU4aZyIiIjhyaYVFd8atlPefc4TANjbcbkCIiIiI4YnG2YchlPeo+cJKHXHHSeNExERMTzZsuIHGLYDSt1xx54nIiIihidbVmQoGbZTyu8zbCet9cSeJyIiIoYnG1YsDdvdb86TcdiOPU9EREQWDU8LFixAq1atoNFooNFoEB4ejr/++kvan5+fj5EjR6JOnTpwdnZGv379kJKSYnKMpKQkREVFwdHREd7e3hg7diyKi4tN2mzbtg1t27aFWq1GcHAwlixZUqaW+fPno379+rC3t0eHDh2wf//+KvnO1qRY6nl60GE79jwRERFZNDz5+/vj008/RXx8PA4ePIjHH38czzzzDI4dOwYAGD16NP73v/9h9erV2L59O65evYrnnntO+rxer0dUVBQKCwuxZ88eLF26FEuWLMHkyZOlNufPn0dUVBQee+wxJCYmYtSoUXj99dexceNGqc3KlSsxZswYTJkyBX///Tdat26NyMhIpKamVt/FsAD9rfCkeNBhO/Y8ERERWTY8PfXUU+jTpw8aNWqExo0b45NPPoGzszP27t2LjIwM/PDDD5g9ezYef/xxhIWFYfHixdizZw/27t0LANi0aROOHz+OZcuWITQ0FL1798a0adMwf/58FBYWAgAWLlyIoKAgzJo1C82aNUN0dDSef/55zJkzR6pj9uzZeOONNzB06FA0b94cCxcuhKOjIxYtWmSR61Jdih90zhOXKiAiIpJYzZwnvV6PX375BTk5OQgPD0d8fDyKiooQEREhtWnatCnq1auHuLg4AEBcXBxCQkLg4+MjtYmMjERmZqbUexUXF2dyDGMb4zEKCwsRHx9v0kYulyMiIkJqU56CggJkZmaavGqaCs954rAdERGR5cPTkSNH4OzsDLVajeHDh+P3339H8+bNodPpoFKp4ObmZtLex8cHOp0OAKDT6UyCk3G/cd+92mRmZiIvLw/Xr1+HXq8vt43xGOWZMWMGXF1dpVdAQEClvr8l6R90zpPS+HBg9jwRERFZPDw1adIEiYmJ2LdvH0aMGIHBgwfj+PHjli7rviZMmICMjAzpdenSJUuXVGEPPmzHniciIiIjpaULUKlUCA4O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3DkAQLdu3aRhsu3bt2P69Ok4ffo0tm3bhrS0NBQVFaFTp06V+r6HDh3C4cOHsXz5cmmbEAIGgwHnz59Hs2bNAACtWrWS9stkMmi1WqSmpgIo6U1q1aoV7O3tpTbt27d/4BpKHxsAfH19pWMT0cNheCKiKufk5ITg4GAAwKJFi9C6dWv88MMPGDZsGLKzswEA69atQ926dU0+p1arpT8PGjRICk8rVqxAr169UKdOnXLPl52djbCwMJPwYuTl5QXg9t1yZ86cwfHjx9G5c2ecPHkS27Ztw82bN9GuXTs4OjpW6vtmZ2fjrbfewjvvvFNmX7169aQ/29nZmeyTyWQwGAyVOuedqvLYRLaO4YmIqpVcLsfEiRMxZswYvPTSS2jevDnUajWSkpLQrVu3u37upZdewqRJkxAfH49ff/0VCxcuvGvbtm3bYuXKlfD29oZGoym3TUhICNzd3fGf//wHoaGhcHZ2Rvfu3fHZZ5/h5s2blZ7vZDz/8ePHpcBYGU2aNMGyZctQUFAghcgDBw6YtDHOG9Pr9ZU+DxFVHCeME1G169+/PxQKBebPnw8XFxe8//77GD16NJYuXYpz587h77//xldffYWlS5dKn6lfvz46duyIYcOGQa/X4+mnn77r8QcNGgRPT08888wz2LlzJ86fP49t27bhnXfeweXLlwGU9MR07doVy5cvl4JSq1atUFBQgNjY2HsGOaNr164hMTHR5JWSkoLx48djz549iI6ORmJiIs6cOYM//vijzITxe3nppZdgMBjw5ptv4sSJE9i4cSO++OILqXYACAwMhEwmw9q1a3Ht2jWpF4+IqhbDExFVO6VSiejoaMycORM5OTmYNm0a/v3vf2PGjBlo1qwZevXqhXXr1iEoKMjkc4MGDcKhQ4fw7LPPwsHB4a7Hd3R0xI4dO1CvXj0899xzaNasGYYNG4b8/HyTnqhu3bpBr9dL4Ukul6Nr166QyWQPNN9pxYoVaNOmjcnru+++Q6tWrbB9+3acPn0aXbp0QZs2bTB58mT4+fk98DXSaDT43//+h8TERISGhuLDDz/E5MmTAUCaB1W3bl18/PHH+OCDD+Dj41OhcEZElScTQghLF0FERPe3fPlyDB06FBkZGfcMj0RUtTjniYjISv34449o0KAB6tati0OHDmH8+PF44YUXGJyILIzhiYjISul0OkyePBk6nQ6+vr7o378/PvnkE0uXRWTzOGxHREREVAGcME5ERERUAQxPRERERBXA8ERERERUAQxPRERERBXA8ERERERUAQxPRERERBXA8ERERERUAQxPRERERBXA8ERERERUAf8Prq5E606ExAUAAAAASUVORK5CYII=\n", "text/plain": [ "<Figure size 640x480 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from wordcloud import WordCloud\n", "\n", "# Review length distribution\n", "sns.histplot(reviews_df['review_length'], bins=50, kde=True)\n", "plt.title('Distribution of Review Lengths')\n", "plt.xlabel('Review Length')\n", "plt.ylabel('Frequency')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 472 }, "id": "q--A_BllfLkp", "outputId": "7f481aac-5743-4f7e-e17b-73c660570361" }, "outputs": [ { "data": { "image/png": "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eeRBREREZNFMLprq1q2LDh06YPny5bh792555ERERERkcUwumn755Re0adMGM2fOhJubG8LCwrBp0ybk5+eXR35EREREFsHkJQdatGiBFi1a4NNPP0VSUhLWrl2LESNGQK/X47XXXsM333xTHnkSEZEVyMvLQ1ZWlrnTKDcXL140dwom8/T0hJ2dnbnTqBBkgiAI//Ugp06dQmRkJNLT0yvt7DmtVgulUgmNRgMnJydzp0NlrGPHjpJjk5KSyi0PIkt38eJFjBgxwtxpUDHLli1DgwYNzJ2GxTLl8/tfLW4J/H2D3rVr12Lt2rU4e/Ys1Go1YmNj/+3hiIioAvD09MSyZcvMnYZJTCnyrO3cgL//n1DZMLlo+uqrr7B27VocPnwYjRo1QkREBLZu3QovL6/yyI+IiKyInZ2d1fVqjB07FosXL5YUZ23nRmXL5IHgs2fPRtu2bXHy5EmcPXsWkydPZsFERERW67XXXivTOKq4TO5pysrKgkwmK49ciIiIzCIpKempYxc5VpGAf9HTJJPJcPDgQbzxxhtQq9X4888/AQBr1qzBoUOHyjxBIiKiZyEpKQljx4412jd27FgWTCQyuWj64YcfEBISAnt7e6SmporrM2k0Gnz00UdlniAREdGz8tprr4mDvZctW8ZLcmTkX41piouLw/Lly1G1alVxf0BAAE6dOlWmyRERERFZCpOLpgsXLiAoKKjEfqVSidzc3LLIiYiIiMjimFw0qVQqXL58ucT+Q4cOoV69emWSFBEREZGlMbloGj58ON555x0cO3YMMpkM169fR3x8PCZOnIhRo0aVR45EREREZmfykgOTJk2CXq9Hly5d8PDhQwQFBUGhUGDixIl4++23yyNHIiIiIrMzuWiSyWSYMmUK3nvvPVy+fBn3799HkyZNUL16dTx69Aj29vblkScRERGRWZl8ec7A1tYWTZo0QZs2bVC1alXMnz8f3t7eZZkbERERkcWQXDTl5+dj8uTJaN26NV566SVs2bIFALBy5Up4e3tjwYIFGD9+fHnlSURERGRWki/PTZ8+HV999RWCg4Nx5MgRhIeH480338TRo0cxf/58hIeHw8bGpjxzJSIiIjIbyUXTxo0b8e2336JXr144e/Ys/P39UVRUhNOnT/NedERERFThSb48d+3aNbRq1QoA0LRpUygUCowfP54FExEREVUK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\n", "text/plain": [ "<Figure size 640x480 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Box plot for review lengths by spoiler\n", "sns.boxplot(x='is_spoiler', y='review_length', data=reviews_df)\n", "plt.title('Review Length by Spoiler Status')\n", "plt.xlabel('Is Spoiler')\n", "plt.ylabel('Review Length')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 206 }, "id": "DSI6GMmYTwGm", "outputId": "ac155fef-bf01-43db-e57d-fcd909941535" }, "outputs": [ { "data": { "application/vnd.google.colaboratory.intrinsic+json": { "type": "dataframe", "variable_name": "data" }, "text/html": [ "\n", " <div id=\"df-3f8c4880-9af7-4578-a0c6-7e5fe568ffb7\" class=\"colab-df-container\">\n", " <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>review_text</th>\n", " <th>is_spoiler</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>In its Oscar year, Shawshank Redemption (writt...</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>The Shawshank Redemption is without a doubt on...</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>I believe that this film is the best story eve...</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>**Yes, there are SPOILERS here**This film has ...</td>\n", " <td>True</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>At the heart of this extraordinary movie is a ...</td>\n", " <td>True</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>\n", " <div class=\"colab-df-buttons\">\n", "\n", " <div class=\"colab-df-container\">\n", " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-3f8c4880-9af7-4578-a0c6-7e5fe568ffb7')\"\n", " title=\"Convert this dataframe to an interactive table.\"\n", " style=\"display:none;\">\n", "\n", " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n", " <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n", " </svg>\n", " </button>\n", "\n", " <style>\n", " .colab-df-container {\n", " display:flex;\n", " gap: 12px;\n", " }\n", "\n", " .colab-df-convert {\n", " background-color: #E8F0FE;\n", " border: none;\n", " border-radius: 50%;\n", " cursor: pointer;\n", " display: none;\n", " fill: #1967D2;\n", " height: 32px;\n", " padding: 0 0 0 0;\n", " width: 32px;\n", " }\n", "\n", " .colab-df-convert:hover {\n", " background-color: #E2EBFA;\n", " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", " fill: #174EA6;\n", " }\n", "\n", " .colab-df-buttons div {\n", " margin-bottom: 4px;\n", " }\n", "\n", " [theme=dark] .colab-df-convert {\n", " background-color: #3B4455;\n", " fill: #D2E3FC;\n", " }\n", "\n", " [theme=dark] .colab-df-convert:hover {\n", " background-color: #434B5C;\n", " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", " fill: #FFFFFF;\n", " }\n", " </style>\n", "\n", " <script>\n", " const buttonEl =\n", " document.querySelector('#df-3f8c4880-9af7-4578-a0c6-7e5fe568ffb7 button.colab-df-convert');\n", " buttonEl.style.display =\n", " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", "\n", " async function convertToInteractive(key) {\n", " const element = document.querySelector('#df-3f8c4880-9af7-4578-a0c6-7e5fe568ffb7');\n", " const dataTable =\n", " await google.colab.kernel.invokeFunction('convertToInteractive',\n", " [key], {});\n", " if (!dataTable) return;\n", "\n", " const docLinkHtml = 'Like what you see? Visit the ' +\n", " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", " + ' to learn more about interactive tables.';\n", " element.innerHTML = '';\n", " dataTable['output_type'] = 'display_data';\n", " await google.colab.output.renderOutput(dataTable, element);\n", " const docLink = document.createElement('div');\n", " docLink.innerHTML = docLinkHtml;\n", " element.appendChild(docLink);\n", " }\n", " </script>\n", " </div>\n", "\n", "\n", "<div id=\"df-96a3c505-f1bc-4def-9bdb-9f0d844aa333\">\n", " <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-96a3c505-f1bc-4def-9bdb-9f0d844aa333')\"\n", " title=\"Suggest charts\"\n", " style=\"display:none;\">\n", "\n", "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", " width=\"24px\">\n", " <g>\n", " <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n", " </g>\n", "</svg>\n", " </button>\n", "\n", "<style>\n", " .colab-df-quickchart {\n", " --bg-color: #E8F0FE;\n", " --fill-color: #1967D2;\n", " --hover-bg-color: #E2EBFA;\n", " --hover-fill-color: #174EA6;\n", " --disabled-fill-color: #AAA;\n", " --disabled-bg-color: #DDD;\n", " }\n", "\n", " [theme=dark] .colab-df-quickchart {\n", " --bg-color: #3B4455;\n", " --fill-color: #D2E3FC;\n", " --hover-bg-color: #434B5C;\n", " --hover-fill-color: #FFFFFF;\n", " --disabled-bg-color: #3B4455;\n", " --disabled-fill-color: #666;\n", " }\n", "\n", " .colab-df-quickchart {\n", " background-color: var(--bg-color);\n", " border: none;\n", " border-radius: 50%;\n", " cursor: pointer;\n", " display: none;\n", " fill: var(--fill-color);\n", " height: 32px;\n", " padding: 0;\n", " width: 32px;\n", " }\n", "\n", " .colab-df-quickchart:hover {\n", " background-color: var(--hover-bg-color);\n", " box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n", " fill: var(--button-hover-fill-color);\n", " }\n", "\n", " .colab-df-quickchart-complete:disabled,\n", " .colab-df-quickchart-complete:disabled:hover {\n", " background-color: var(--disabled-bg-color);\n", " fill: var(--disabled-fill-color);\n", " box-shadow: none;\n", " }\n", "\n", " .colab-df-spinner {\n", " border: 2px solid var(--fill-color);\n", " border-color: transparent;\n", " border-bottom-color: var(--fill-color);\n", " animation:\n", " spin 1s steps(1) infinite;\n", " }\n", "\n", " @keyframes spin {\n", " 0% {\n", " border-color: transparent;\n", " border-bottom-color: var(--fill-color);\n", " border-left-color: var(--fill-color);\n", " }\n", " 20% {\n", " border-color: transparent;\n", " border-left-color: var(--fill-color);\n", " border-top-color: var(--fill-color);\n", " }\n", " 30% {\n", " border-color: transparent;\n", " border-left-color: var(--fill-color);\n", " border-top-color: var(--fill-color);\n", " border-right-color: var(--fill-color);\n", " }\n", " 40% {\n", " border-color: transparent;\n", " border-right-color: var(--fill-color);\n", " border-top-color: var(--fill-color);\n", " }\n", " 60% {\n", " border-color: transparent;\n", " border-right-color: var(--fill-color);\n", " }\n", " 80% {\n", " border-color: transparent;\n", " border-right-color: var(--fill-color);\n", " border-bottom-color: var(--fill-color);\n", " }\n", " 90% {\n", " border-color: transparent;\n", " border-bottom-color: var(--fill-color);\n", " }\n", " }\n", "</style>\n", "\n", " <script>\n", " async function quickchart(key) {\n", " const quickchartButtonEl =\n", " document.querySelector('#' + key + ' button');\n", " quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n", " quickchartButtonEl.classList.add('colab-df-spinner');\n", " try {\n", " const charts = await google.colab.kernel.invokeFunction(\n", " 'suggestCharts', [key], {});\n", " } catch (error) {\n", " console.error('Error during call to suggestCharts:', error);\n", " }\n", " quickchartButtonEl.classList.remove('colab-df-spinner');\n", " quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n", " }\n", " (() => {\n", " let quickchartButtonEl =\n", " document.querySelector('#df-96a3c505-f1bc-4def-9bdb-9f0d844aa333 button');\n", " quickchartButtonEl.style.display =\n", " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", " })();\n", " </script>\n", "</div>\n", "\n", " </div>\n", " </div>\n" ], "text/plain": [ " review_text is_spoiler\n", "0 In its Oscar year, Shawshank Redemption (writt... True\n", "1 The Shawshank Redemption is without a doubt on... True\n", "2 I believe that this film is the best story eve... True\n", "3 **Yes, there are SPOILERS here**This film has ... True\n", "4 At the heart of this extraordinary movie is a ... True" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = reviews_df[['review_text', 'is_spoiler']]\n", "data.head()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "U8ss94fKF0ng", "outputId": "447aae8d-6038-4295-d0e7-07873814db51" }, "outputs": [ { "data": { "text/plain": [ "175000" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.shape[0]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "etofnLuVbIsH", "outputId": "4fd63613-3ded-46b2-83a3-c2ef2627945b" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "<ipython-input-16-331fbbe8856b>:10: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " data['review_text'] = data['review_text'].apply(clean_text)\n" ] } ], "source": [ "def clean_text(text):\n", " text = text.lower() # Convert to lowercase\n", " text = text.replace('\\n', ' ') # Replace newlines with spaces\n", " text = text.replace('\\r', ' ') # Replace carriage returns with spaces\n", " text = ''.join([c if c.isalnum() or c.isspace() else ' ' for c in text]) # Remove special characters\n", " text = ' '.join(text.split()) # Remove extra spaces\n", " return text\n", "\n", "# Apply text cleaning to the dataset\n", "data['review_text'] = data['review_text'].apply(clean_text)\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "uLA4MoGFWcic", "outputId": "2488249f-6b26-4002-d54a-056b87116a2c" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Training set size: 131250\n", "Validation set size: 21875\n", "Test set size: 21875\n" ] } ], "source": [ "from sklearn.model_selection import train_test_split\n", "train_data, temp_data = train_test_split(data, test_size=0.25, random_state=42)\n", "\n", "# Split the remainder into test and validation sets\n", "test_data, val_data = train_test_split(temp_data, test_size=0.5, random_state=42)\n", "\n", "# Display the sizes of each dataset\n", "print(\"Training set size:\", len(train_data))\n", "print(\"Validation set size:\", len(val_data))\n", "print(\"Test set size:\", len(test_data))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "id": "vFswYX1OYD7W" }, "outputs": [], "source": [ "from datasets import Dataset\n", "import torch\n", "\n", "train_dataset = Dataset.from_pandas(train_data)\n", "val_dataset = Dataset.from_pandas(val_data)\n", "test_dataset = Dataset.from_pandas(test_data)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "PAe4Amsln2MB", "outputId": "17d6ce1d-5e4c-4c55-f5dc-96a62fd176a0" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using device: cuda\n" ] } ], "source": [ "import torch\n", "\n", "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", "print(f\"Using device: {device}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "Jnh68UU4fVNv" }, "source": [ "# Model" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "AMxuCcylYi8E", "outputId": "44c6fa5d-2a02-40ba-ba82-1aaf606ea377" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: tensorflow in /usr/local/lib/python3.10/dist-packages (2.17.0)\n", "Requirement already satisfied: absl-py>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.4.0)\n", "Requirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.6.3)\n", "Requirement already satisfied: flatbuffers>=24.3.25 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (24.3.25)\n", "Requirement already satisfied: gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.6.0)\n", "Requirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.2.0)\n", "Requirement already satisfied: h5py>=3.10.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.11.0)\n", "Requirement already satisfied: libclang>=13.0.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (18.1.1)\n", "Requirement already satisfied: ml-dtypes<0.5.0,>=0.3.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.4.0)\n", "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.3.0)\n", "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from tensorflow) (24.1)\n", "Requirement already satisfied: protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.20.3 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.20.3)\n", "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.32.3)\n", "Requirement already satisfied: setuptools in /usr/local/lib/python3.10/dist-packages (from tensorflow) (71.0.4)\n", "Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.16.0)\n", "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.4.0)\n", "Requirement already satisfied: typing-extensions>=3.6.6 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (4.12.2)\n", "Requirement already satisfied: wrapt>=1.11.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.16.0)\n", "Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.64.1)\n", "Requirement already satisfied: tensorboard<2.18,>=2.17 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.17.0)\n", "Requirement already satisfied: keras>=3.2.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.4.1)\n", "Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.37.1)\n", "Requirement already satisfied: numpy<2.0.0,>=1.23.5 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.26.4)\n", "Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.10/dist-packages (from astunparse>=1.6.0->tensorflow) (0.44.0)\n", "Requirement already satisfied: rich in /usr/local/lib/python3.10/dist-packages (from keras>=3.2.0->tensorflow) (13.7.1)\n", "Requirement already satisfied: namex in /usr/local/lib/python3.10/dist-packages (from keras>=3.2.0->tensorflow) (0.0.8)\n", "Requirement already satisfied: optree in /usr/local/lib/python3.10/dist-packages (from keras>=3.2.0->tensorflow) (0.12.1)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (3.3.2)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (3.7)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (2.0.7)\n", "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (2024.7.4)\n", "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.18,>=2.17->tensorflow) (3.6)\n", "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.18,>=2.17->tensorflow) (0.7.2)\n", "Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.18,>=2.17->tensorflow) (3.0.3)\n", "Requirement already satisfied: MarkupSafe>=2.1.1 in /usr/local/lib/python3.10/dist-packages (from werkzeug>=1.0.1->tensorboard<2.18,>=2.17->tensorflow) (2.1.5)\n", "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras>=3.2.0->tensorflow) (3.0.0)\n", "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras>=3.2.0->tensorflow) (2.16.1)\n", "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich->keras>=3.2.0->tensorflow) (0.1.2)\n", "Requirement already satisfied: keras in /usr/local/lib/python3.10/dist-packages (3.4.1)\n", "Requirement already satisfied: absl-py in /usr/local/lib/python3.10/dist-packages (from keras) (1.4.0)\n", "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from keras) (1.26.4)\n", "Requirement already satisfied: rich in /usr/local/lib/python3.10/dist-packages (from keras) (13.7.1)\n", "Requirement already satisfied: namex in /usr/local/lib/python3.10/dist-packages (from keras) (0.0.8)\n", "Requirement already satisfied: h5py in /usr/local/lib/python3.10/dist-packages (from keras) (3.11.0)\n", "Requirement already satisfied: optree in /usr/local/lib/python3.10/dist-packages (from keras) (0.12.1)\n", "Requirement already satisfied: ml-dtypes in /usr/local/lib/python3.10/dist-packages (from keras) (0.4.0)\n", "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from keras) (24.1)\n", "Requirement already satisfied: typing-extensions>=4.5.0 in /usr/local/lib/python3.10/dist-packages (from optree->keras) (4.12.2)\n", "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras) (3.0.0)\n", "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras) (2.16.1)\n", "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich->keras) (0.1.2)\n" ] } ], "source": [ "!pip install tensorflow\n", "!pip install keras" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "id": "MjJX0nS0YnPu" }, "outputs": [], "source": [ "import pandas as pd\n", "from tensorflow.keras.preprocessing.text import Tokenizer\n", "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", "from tensorflow.keras.models import Sequential\n", "from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout\n", "\n", "vocab_size = 8000\n", "max_length = 2000 # Maximum review length\n", "oov_tok = \"<OOV>\"\n", "\n", "tokenizer = Tokenizer(num_words=vocab_size, oov_token=oov_tok)\n", "tokenizer.fit_on_texts(train_data['review_text'])" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "id": "-zSdWsUdZXbz" }, "outputs": [], "source": [ "def tokenize_and_pad(texts):\n", " sequences = tokenizer.texts_to_sequences(texts)\n", " padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post')\n", " return padded_sequences" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "id": "idHc4gFMZWK2" }, "outputs": [], "source": [ "X_train = tokenize_and_pad(train_data['review_text'])\n", "X_val = tokenize_and_pad(val_data['review_text'])\n", "X_test = tokenize_and_pad(test_data['review_text'])\n", "\n", "y_train = train_data['is_spoiler']\n", "y_val = val_data['is_spoiler']\n", "y_test = test_data['is_spoiler']" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Z_e8WL6IZgHq", "outputId": "231e57cc-5f26-4dd7-cd15-522328e43b18" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.10/dist-packages/keras/src/layers/core/embedding.py:90: UserWarning: Argument `input_length` is deprecated. Just remove it.\n", " warnings.warn(\n" ] } ], "source": [ "from tensorflow.keras.models import Sequential\n", "from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout\n", "\n", "from tensorflow.keras.layers import Bidirectional\n", "\n", "model = Sequential([\n", " Embedding(vocab_size, 32, input_length=max_length),\n", " Bidirectional(LSTM(64, return_sequences=True)), # Using a bidirectional LSTM\n", " Dropout(0.5),\n", " Bidirectional(LSTM(64)),\n", " Dropout(0.5),\n", " Dense(1, activation='sigmoid')\n", "])" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "id": "VoQMMtlcb1kS" }, "outputs": [], "source": [ "model.build(input_shape=(None, max_length))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 323 }, "id": "dd-3mlCWZj9I", "outputId": "938cd928-8d2b-4e6e-8aa2-e61efd302386" }, "outputs": [ { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential\"</span>\n", "</pre>\n" ], "text/plain": [ "\u001b[1mModel: \"sequential\"\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n", "┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n", "│ embedding (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">256,000</span> │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ bidirectional (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">49,664</span> │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ dropout (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ bidirectional_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">98,816</span> │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ dropout_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">129</span> │\n", "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n", "</pre>\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n", "│ embedding (\u001b[38;5;33mEmbedding\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2000\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m256,000\u001b[0m │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ bidirectional (\u001b[38;5;33mBidirectional\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2000\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m49,664\u001b[0m │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2000\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ bidirectional_1 (\u001b[38;5;33mBidirectional\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m98,816\u001b[0m │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n", "│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m129\u001b[0m │\n", "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">404,609</span> (1.54 MB)\n", "</pre>\n" ], "text/plain": [ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m404,609\u001b[0m (1.54 MB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">404,609</span> (1.54 MB)\n", "</pre>\n" ], "text/plain": [ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m404,609\u001b[0m (1.54 MB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n", "</pre>\n" ], "text/plain": [ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n", "model.summary()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "sKMQE1YGZlyW", "outputId": "5048b049-a722-4d30-99f4-68f82684db51" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1000s\u001b[0m 242ms/step - accuracy: 0.7216 - loss: 0.5929 - val_accuracy: 0.7301 - val_loss: 0.5770\n", "Epoch 2/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1042s\u001b[0m 243ms/step - accuracy: 0.7339 - loss: 0.5535 - val_accuracy: 0.7552 - val_loss: 0.5142\n", "Epoch 3/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1053s\u001b[0m 245ms/step - accuracy: 0.7586 - loss: 0.5097 - val_accuracy: 0.7632 - val_loss: 0.5039\n", "Epoch 4/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1036s\u001b[0m 244ms/step - accuracy: 0.7700 - loss: 0.4951 - val_accuracy: 0.7632 - val_loss: 0.5038\n", "Epoch 5/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1051s\u001b[0m 246ms/step - accuracy: 0.7813 - loss: 0.4803 - val_accuracy: 0.7639 - val_loss: 0.5083\n", "Epoch 6/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1042s\u001b[0m 246ms/step - accuracy: 0.7862 - loss: 0.4705 - val_accuracy: 0.7631 - val_loss: 0.5041\n", "Epoch 7/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1043s\u001b[0m 246ms/step - accuracy: 0.7963 - loss: 0.4563 - val_accuracy: 0.7644 - val_loss: 0.5167\n", "Epoch 8/8\n", "\u001b[1m4102/4102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1043s\u001b[0m 247ms/step - accuracy: 0.8045 - loss: 0.4437 - val_accuracy: 0.7601 - val_loss: 0.5149\n" ] } ], "source": [ "history = model.fit(X_train, y_train, epochs=8, batch_size=32, validation_data=(X_val, y_val))\n" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "UnGyGSeo4K4H", "outputId": "b7e5ee3f-938a-41ad-ce94-5cb6ebec26b7" }, "outputs": [ { "metadata": { "tags": null }, "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "# Save the model in HDF5 forma\n", "model.save('my_fine_tuned_model.h5')\n" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "WeZv_N194s8z", "outputId": "722c0f6a-edc8-462e-ce05-c20618833fc3" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Mounted at /content/drive\n" ] } ], "source": [ "from google.colab import drive\n", "drive.mount('/content/drive')\n" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "id": "TmLn0V0D452u" }, "outputs": [], "source": [ "import os\n", "\n", "model_path = '/content/drive/MyDrive/LSTMModel'\n", "os.makedirs(model_path, exist_ok=True)\n" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "-J6G6pG35DmR", "outputId": "cd1e3364-1e0b-45c6-a1f6-65cdc71711e2" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "# Save the model in HDF5 format\n", "model.save(os.path.join(model_path, 'my_fine_tuned_model.h5'))\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "etkORlK83kd-" }, "outputs": [], "source": [ "!nvidia-smi\n" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "id": "MOlCZi49dw9l" }, "outputs": [], "source": [ "import gc\n", "gc.collect()\n", "torch.cuda.empty_cache()" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "VPW3AaGFnAk4", "outputId": "eddb477d-8a13-44fe-df8a-5bd0c5d70398" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m684/684\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m71s\u001b[0m 104ms/step - accuracy: 0.7551 - loss: 0.5165\n", "Test Loss: 0.5159615874290466\n", "Test Accuracy: 0.7574856877326965\n" ] } ], "source": [ "# Evaluate the model on the test set\n", "loss, accuracy = model.evaluate(X_test, y_test)\n", "print(f\"Test Loss: {loss}\")\n", "print(f\"Test Accuracy: {accuracy}\")" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "hRSvT5cB5QMp", "outputId": "64462d92-b4e0-4b03-be6b-42379bf65ca9" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (1.26.4)\n", "Requirement already satisfied: scikit-learn in /usr/local/lib/python3.10/dist-packages (1.3.2)\n", "Requirement already satisfied: tensorflow in /usr/local/lib/python3.10/dist-packages (2.17.0)\n", "Requirement already satisfied: scipy>=1.5.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (1.13.1)\n", "Requirement already satisfied: joblib>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (1.4.2)\n", "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (3.5.0)\n", "Requirement already satisfied: absl-py>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.4.0)\n", "Requirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.6.3)\n", "Requirement already satisfied: flatbuffers>=24.3.25 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (24.3.25)\n", "Requirement already satisfied: gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.6.0)\n", "Requirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.2.0)\n", "Requirement already satisfied: h5py>=3.10.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.11.0)\n", "Requirement already satisfied: libclang>=13.0.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (18.1.1)\n", "Requirement already satisfied: ml-dtypes<0.5.0,>=0.3.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.4.0)\n", "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.3.0)\n", "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from tensorflow) (24.1)\n", "Requirement already satisfied: protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.20.3 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.20.3)\n", "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.32.3)\n", "Requirement already satisfied: setuptools in /usr/local/lib/python3.10/dist-packages (from tensorflow) (71.0.4)\n", "Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.16.0)\n", "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.4.0)\n", "Requirement already satisfied: typing-extensions>=3.6.6 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (4.12.2)\n", "Requirement already satisfied: wrapt>=1.11.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.16.0)\n", "Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.64.1)\n", "Requirement already satisfied: tensorboard<2.18,>=2.17 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.17.0)\n", "Requirement already satisfied: keras>=3.2.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.4.1)\n", "Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.37.1)\n", "Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.10/dist-packages (from astunparse>=1.6.0->tensorflow) (0.44.0)\n", "Requirement already satisfied: rich in /usr/local/lib/python3.10/dist-packages (from keras>=3.2.0->tensorflow) (13.7.1)\n", "Requirement already satisfied: namex in /usr/local/lib/python3.10/dist-packages (from keras>=3.2.0->tensorflow) (0.0.8)\n", "Requirement already satisfied: optree in /usr/local/lib/python3.10/dist-packages (from keras>=3.2.0->tensorflow) (0.12.1)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (3.3.2)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (3.7)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (2.0.7)\n", "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorflow) (2024.7.4)\n", "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.18,>=2.17->tensorflow) (3.6)\n", "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.18,>=2.17->tensorflow) (0.7.2)\n", "Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.18,>=2.17->tensorflow) (3.0.3)\n", "Requirement already satisfied: MarkupSafe>=2.1.1 in /usr/local/lib/python3.10/dist-packages (from werkzeug>=1.0.1->tensorboard<2.18,>=2.17->tensorflow) (2.1.5)\n", "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras>=3.2.0->tensorflow) (3.0.0)\n", "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras>=3.2.0->tensorflow) (2.16.1)\n", "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich->keras>=3.2.0->tensorflow) (0.1.2)\n" ] } ], "source": [ "!pip install numpy scikit-learn tensorflow\n" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "T6uO6ZVX50JF", "outputId": "dd48288d-9706-4e15-acd6-542171bafae4" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n" ] } ], "source": [ "from tensorflow.keras.models import load_model\n", "model = load_model('my_fine_tuned_model.h5')\n" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "id": "E-YKdjrE6I34" }, "outputs": [], "source": [ "from sklearn.metrics import classification_report\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "XVxaRfFB6XVo", "outputId": "a3f35aa5-225d-47a7-97f2-3ef3ed3b97ad" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m684/684\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m80s\u001b[0m 117ms/step\n" ] } ], "source": [ "predictions = model.predict(X_test)\n", "predictions = (predictions > 0.5).astype(int) # Threshold predictions for binary classification\n" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Vy-eg8JG6e1j", "outputId": "69cb6c8e-4837-417a-81f2-6a8aec773ef1" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " Non-Spoiler 0.79 0.91 0.84 15695\n", " Spoiler 0.62 0.38 0.47 6180\n", "\n", " accuracy 0.76 21875\n", " macro avg 0.70 0.64 0.66 21875\n", "weighted avg 0.74 0.76 0.74 21875\n", "\n" ] } ], "source": [ "report = classification_report(y_test, predictions, target_names=['Non-Spoiler', 'Spoiler'])\n", "print(report)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "4sHnLnuQ7BNS", "outputId": "f053ae15-8842-42f0-b7df-ef63914f85f9" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: scikit-learn in /usr/local/lib/python3.10/dist-packages (1.3.2)\n", "Requirement already satisfied: numpy<2.0,>=1.17.3 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (1.26.4)\n", "Requirement already satisfied: scipy>=1.5.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (1.13.1)\n", "Requirement already satisfied: joblib>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (1.4.2)\n", "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn) (3.5.0)\n" ] } ], "source": [ "!pip install scikit-learn" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "id": "5-c0qcYn8GqF" }, "outputs": [], "source": [ "def prepare_input(text, tokenizer, max_length):\n", " sequences = tokenizer.texts_to_sequences([text])\n", " padded = pad_sequences(sequences, maxlen=max_length, padding='post')\n", " return padded\n", "\n", "def predict_spoiler(text, tokenizer, model, max_length=1500):\n", " prepared_text = prepare_input(text, tokenizer, max_length)\n", " prediction = model.predict(prepared_text)\n", " is_spoiler = (prediction > 0.5).astype(int) # Threshold the prediction\n", " return bool(is_spoiler)\n", "\n" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Unh_FyLx8Ith", "outputId": "4d7b676f-bcb3-4ffb-f9f9-97d6e54f9a44" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 966ms/step\n", "The text is a non-spoiler.\n" ] } ], "source": [ "# Test the function\n", "input_text = \"Jack Ryan is on a working vacation in London with his family. He has retired from the CIA and is a Professor at the US Naval Academy. He is seen delivering a lecture at the Royal Naval Academy in London.Meanwhile, Ryan's wife Cathy and daughter Sally are sightseeing near Buckingham Palace. Sally and Cathy come upon a British Royal Guard, and Sally tries to get the guard to react by doing an improvised tap dance in front of him. She's impressed when the guard, trained to ignore distraction, doesn't react at all, and they leave.\"\n", "is_spoiler = predict_spoiler(input_text, tokenizer, model)\n", "print(f\"The text is a {'spoiler' if is_spoiler else 'non-spoiler'}.\")" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "2bjajseSZpce", "outputId": "fd4681b2-a612-4453-bbc3-2e3552e67942" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 406ms/step\n", "The text is a non-spoiler.\n" ] } ], "source": [ "# Test the function\n", "input_text = \"Three years have passed since John Brennan (Russel Crowe) and his wife Lara (Elizabeth Banks) lost their son Luke (Tyler Simpkins) in a car accident. Three years later, John is a community college teacher who is teaching English. He tries to manage his job and raising Luke.\"\n", "is_spoiler = predict_spoiler(input_text, tokenizer, model)\n", "print(f\"The text is a {'spoiler' if is_spoiler else 'non-spoiler'}.\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "26-LoGDzZ6P1" }, "outputs": [], "source": [ "# Test the function\n", "input_text = \"Three years have passed since John Brennan (Russel Crowe) and his wife Lara (Elizabeth Banks) lost their son Luke (Tyler Simpkins) in a car accident. Three years later, John is a community college teacher who is teaching English. He tries to manage his job and raising Luke.\"\n", "is_spoiler = predict_spoiler(input_text, tokenizer, model)\n", "print(f\"The text is a {'spoiler' if is_spoiler else 'non-spoiler'}.\")" ] } ], "metadata": { "accelerator": "GPU", "colab": { "gpuType": "T4", "provenance": [] }, "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.11.4" } }, "nbformat": 4, "nbformat_minor": 4 }