diff --git a/Stock_Price_Prediction (Updated).ipynb b/Stock_Price_Prediction (Updated).ipynb new file mode 100644 index 0000000..50ab7cc --- /dev/null +++ b/Stock_Price_Prediction (Updated).ipynb @@ -0,0 +1,5695 @@ +{ + "cells": [ + { + "cell_type": "code", + "source": [ + "!git clone https://github.com/rohitinu6/Stock-Price-Prediction.git\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "PxjHbzFWBL_c", + "outputId": "260e8a7f-58d5-44c2-91d4-5ee8f4aed24a" + }, + "execution_count": 16, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Cloning into 'Stock-Price-Prediction'...\n", + "remote: Enumerating objects: 48, done.\u001b[K\n", + "remote: Counting objects: 100% (48/48), done.\u001b[K\n", + "remote: Compressing objects: 100% (41/41), done.\u001b[K\n", + "remote: Total 48 (delta 16), reused 12 (delta 6), pack-reused 0 (from 0)\u001b[K\n", + "Receiving objects: 100% (48/48), 434.02 KiB | 2.52 MiB/s, done.\n", + "Resolving deltas: 100% (16/16), done.\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "%cd Stock-Price-Prediction\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "RQmmRj3zBPV-", + "outputId": "c170454e-957f-4019-c1af-de6d86270a0d" + }, + "execution_count": 17, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "/content/Stock-Price-Prediction/Stock-Price-Prediction\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "!ls\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "txUZNpPzBRRb", + "outputId": "90f7d8f1-3b83-4277-911b-475eba16f9e3" + }, + "execution_count": 10, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " code-of-conduct.md Data\t README.md\t Stock_Price_Prediction.ipynb\n", + " Contributing.md 'Python File' SBIN.csv\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "!pwd\n", + "\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fzbuUxboAdmK", + "outputId": "d39213e6-7b04-4e66-ba05-9b5d0456da06" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "/content\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "!ls\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "_hKmY0cJAujy", + "outputId": "dad95fbd-e587-4ae2-cde6-28bc93852598" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " code-of-conduct.md Data\t README.md\t Stock_Price_Prediction.ipynb\n", + " Contributing.md 'Python File' SBIN.csv\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "%cd Stock-Price-Prediction\n", + "\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZhZDwGzNBDsL", + "outputId": "b71d86e5-208e-4a4f-d628-01306c6740d2" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[Errno 2] No such file or directory: 'Stock-Price-Prediction'\n", + "/content/Stock-Price-Prediction\n" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "id": "qCDSjVhXLr_Z" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.impute import SimpleImputer\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.svm import SVR\n", + "from sklearn.ensemble import RandomForestRegressor, AdaBoostRegressor, GradientBoostingRegressor\n", + "from sklearn.tree import DecisionTreeRegressor # Corrected import for DecisionTreeRegressor\n", + "from sklearn.metrics import mean_squared_error, mean_absolute_error, mean_absolute_percentage_error\n", + "from sklearn.neighbors import KNeighborsRegressor\n", + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Dense, LSTM\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "id": "SOQbXSiB-g5G" + }, + "outputs": [], + "source": [ + "\n", + "df = pd.read_csv('/content/Stock-Price-Prediction/SBIN.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "Sc4id6VxL8BS", + "outputId": "e517425b-b414-4ded-c078-d56c479a583f" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " Date Open High Low Close Adj Close \\\n", + "0 01-01-1996 18.691147 18.978922 18.540184 18.823240 12.409931 \n", + "1 02-01-1996 18.894005 18.964767 17.738192 18.224106 12.014931 \n", + "2 03-01-1996 18.327892 18.568489 17.643839 17.738192 11.694577 \n", + "3 04-01-1996 17.502312 17.832542 17.223972 17.676863 11.654142 \n", + "4 05-01-1996 17.738192 17.785366 17.459852 17.577793 11.588827 \n", + "\n", + " Volume \n", + "0 43733533.0 \n", + "1 56167280.0 \n", + "2 68296318.0 \n", + "3 86073880.0 \n", + "4 76613039.0 " + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DateOpenHighLowCloseAdj CloseVolume
001-01-199618.69114718.97892218.54018418.82324012.40993143733533.0
102-01-199618.89400518.96476717.73819218.22410612.01493156167280.0
203-01-199618.32789218.56848917.64383917.73819211.69457768296318.0
304-01-199617.50231217.83254217.22397217.67686311.65414286073880.0
405-01-199617.73819217.78536617.45985217.57779311.58882776613039.0
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "dataframe", + "variable_name": "df", + "summary": "{\n \"name\": \"df\",\n \"rows\": 7074,\n \"fields\": [\n {\n \"column\": \"Date\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 7074,\n \"samples\": [\n \"11-08-2016\",\n \"30-10-2007\",\n \"17-01-2017\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Open\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 154.7732294451065,\n \"min\": 13.478195,\n \"max\": 703.650024,\n \"num_unique_values\": 4758,\n \"samples\": [\n 174.399994,\n 31.0324,\n 187.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"High\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 156.34507839355788,\n \"min\": 13.935802,\n \"max\": 728.349976,\n \"num_unique_values\": 5403,\n \"samples\": [\n 473.0,\n 495.450012,\n 78.321663\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Low\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 152.98051601861624,\n \"min\": 13.214009,\n \"max\": 694.200012,\n \"num_unique_values\": 5488,\n \"samples\": [\n 60.2957,\n 22.677523,\n 16.983376\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Close\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 154.63054905628158,\n \"min\": 13.346102,\n \"max\": 725.25,\n \"num_unique_values\": 5975,\n \"samples\": [\n 633.599976,\n 241.100006,\n 107.834999\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Adj Close\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 152.90324918554683,\n \"min\": 9.53141,\n \"max\": 725.25,\n \"num_unique_values\": 6575,\n \"samples\": [\n 12.345289,\n 223.836212,\n 16.758821\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Volume\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 34627439.399630256,\n \"min\": 0.0,\n \"max\": 446948261.0,\n \"num_unique_values\": 6948,\n \"samples\": [\n 29959130.0,\n 1648453.0,\n 14077470.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" + } + }, + "metadata": {}, + "execution_count": 20 + } + ], + "source": [ + "# Load the dataset\n", + "#df = pd.read_csv('/content/SBIN.NS.csv')\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "id": "7LaYGXsfN-8y" + }, + "outputs": [], + "source": [ + "# Drop the 'Date' and 'Adj Close' columns\n", + "df.drop(['Date', 'Adj Close'], axis=1, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "pqbTBdnBOKJc", + "outputId": "27cb25c1-fbf9-4e9b-de67-c69f4beb62a6" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " Open High Low Close Volume\n", + "0 18.691147 18.978922 18.540184 18.823240 43733533.0\n", + "1 18.894005 18.964767 17.738192 18.224106 56167280.0\n", + "2 18.327892 18.568489 17.643839 17.738192 68296318.0\n", + "3 17.502312 17.832542 17.223972 17.676863 86073880.0\n", + "4 17.738192 17.785366 17.459852 17.577793 76613039.0" + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OpenHighLowCloseVolume
018.69114718.97892218.54018418.82324043733533.0
118.89400518.96476717.73819218.22410656167280.0
218.32789218.56848917.64383917.73819268296318.0
317.50231217.83254217.22397217.67686386073880.0
417.73819217.78536617.45985217.57779376613039.0
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "dataframe", + "variable_name": "df", + "summary": "{\n \"name\": \"df\",\n \"rows\": 7074,\n \"fields\": [\n {\n \"column\": \"Open\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 154.7732294451065,\n \"min\": 13.478195,\n \"max\": 703.650024,\n \"num_unique_values\": 4758,\n \"samples\": [\n 174.399994,\n 31.0324,\n 187.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"High\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 156.34507839355788,\n \"min\": 13.935802,\n \"max\": 728.349976,\n \"num_unique_values\": 5403,\n \"samples\": [\n 473.0,\n 495.450012,\n 78.321663\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Low\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 152.98051601861624,\n \"min\": 13.214009,\n \"max\": 694.200012,\n \"num_unique_values\": 5488,\n \"samples\": [\n 60.2957,\n 22.677523,\n 16.983376\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Close\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 154.63054905628158,\n \"min\": 13.346102,\n \"max\": 725.25,\n \"num_unique_values\": 5975,\n \"samples\": [\n 633.599976,\n 241.100006,\n 107.834999\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Volume\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 34627439.399630256,\n \"min\": 0.0,\n \"max\": 446948261.0,\n \"num_unique_values\": 6948,\n \"samples\": [\n 29959130.0,\n 1648453.0,\n 14077470.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" + } + }, + "metadata": {}, + "execution_count": 22 + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "id": "dydEPoNeM6eN" + }, + "outputs": [], + "source": [ + "# Handle missing values\n", + "imputer = SimpleImputer(strategy='mean')\n", + "df = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "OQ3cGqgTMBwt" + }, + "outputs": [], + "source": [ + "# Select features and target variable\n", + "X = df[['Open', 'High', 'Low', 'Volume']]\n", + "y = df['Close']" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "id": "9Oz-bwJOMEWD" + }, + "outputs": [], + "source": [ + "# Split the data into training and testing sets\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "id": "ugapDyXODtn3" + }, + "outputs": [], + "source": [ + "# Scale the features using Min-Max scaling\n", + "scaler = MinMaxScaler()\n", + "X_train_scaled = scaler.fit_transform(X_train)\n", + "X_test_scaled = scaler.transform(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "997ZEgibCZIO", + "outputId": "b2fe66e9-0691-4cf2-f8bb-17a51bd937bf" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(5659, 4)" + ] + }, + "metadata": {}, + "execution_count": 27 + } + ], + "source": [ + "X_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "bmtt76RuCeyG", + "outputId": "27215164-cd4c-4a35-ad30-baf8cb256f50" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1415, 4)" + ] + }, + "metadata": {}, + "execution_count": 28 + } + ], + "source": [ + "X_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "CeJkUJ92Ciqd", + "outputId": "0f833a49-8888-4117-9e57-de16af669a46" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(5659,)" + ] + }, + "metadata": {}, + "execution_count": 29 + } + ], + "source": [ + "y_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "7HGC7VuTCjWc", + "outputId": "bacea1b8-9a4c-4141-c19b-088412c859ef" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1415,)" + ] + }, + "metadata": {}, + "execution_count": 30 + } + ], + "source": [ + "y_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "id": "JtwR1D2T_jws" + }, + "outputs": [], + "source": [ + "# Function to evaluate and print RMSE, MAE, and MAPE\n", + "def evaluate_model(model, X_test, y_test):\n", + " predictions = model.predict(X_test)\n", + " rmse = np.sqrt(mean_squared_error(y_test, predictions))\n", + " mae = mean_absolute_error(y_test, predictions)\n", + " mape = mean_absolute_percentage_error(y_test, predictions)\n", + "\n", + " print(f\"RMSE: {rmse}\")\n", + " print(f\"MAE: {mae}\")\n", + " print(f\"MAPE: {mape}\\n\")\n", + "\n", + " return rmse, mae, mape\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "id": "5Ff0f7w9_jws" + }, + "outputs": [], + "source": [ + "metrics = {\n", + " \"Model\": [],\n", + " \"RMSE\": [],\n", + " \"MAE\": [],\n", + " \"MAPE\": []\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c6Ek8jRlO2_I" + }, + "source": [ + "## 1. LINEAR REGRESSION" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "id": "RdZ1SpzdMHAJ" + }, + "outputs": [], + "source": [ + "# Create a linear regression model\n", + "model1 = LinearRegression()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 241 + }, + "id": "mPM035IzMY04", + "outputId": "a4e7fe39-8597-4464-d6a0-bb791ab4a0d4" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "5286 257.350006\n", + "3408 129.464996\n", + "5477 279.350006\n", + "6906 588.500000\n", + "530 21.644367\n", + "Name: Close, dtype: float64" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Close
5286257.350006
3408129.464996
5477279.350006
6906588.500000
53021.644367
\n", + "

" + ] + }, + "metadata": {}, + "execution_count": 34 + } + ], + "source": [ + "y_train.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "qBhQ9HbYMI3d", + "outputId": "5d4d1a7f-1fdb-4ef3-bbd9-8f7941402804" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression()" + ], + "text/html": [ + "
LinearRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 35 + } + ], + "source": [ + "# Train the model\n", + "model1.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "id": "X269co2kMS4z", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "f0e15ace-2bbc-4a19-c298-d0edc8f5dc96" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 234.77989480270563\n", + "MAE: 176.52560636631733\n", + "MAPE: 0.9999434459009082\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but LinearRegression was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model1, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"Linear Regressor\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GxtMzlg-gR2P" + }, + "source": [ + "## 2. SVR" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "id": "0xQewd7QWTtq" + }, + "outputs": [], + "source": [ + "# Create an SVR model\n", + "model2 = SVR()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "22SaCsQmfhgP", + "outputId": "3f53ece1-78c9-47c3-d986-d92868c246c0" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SVR()" + ], + "text/html": [ + "
SVR()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 38 + } + ], + "source": [ + "# Train the model\n", + "model2.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "id": "OQ1nL4oYfkAC", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "dc5233e1-ea2b-4d75-eaef-6c97a8a20373" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but SVR was fitted with feature names\n", + " warnings.warn(\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 155.09208188200955\n", + "MAE: 124.0643357754677\n", + "MAPE: 2.471521622294383\n", + "\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model2, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"SVR\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hcIfVMWdgcKt" + }, + "source": [ + "## 3. Random Forest" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "id": "f7raXT_hf2ij" + }, + "outputs": [], + "source": [ + "model3 = RandomForestRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "fF002Yepgk55", + "outputId": "1cb8105b-f474-42c8-c071-a6f75ff27c64" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestRegressor()" + ], + "text/html": [ + "
RandomForestRegressor()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 41 + } + ], + "source": [ + "# Train the model\n", + "model3.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "id": "8nRU_pzEgnCt", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "ed6c5292-0413-472c-cb69-121110809706" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 224.91059485704434\n", + "MAE: 162.96050630804314\n", + "MAPE: 0.7503071829574962\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but RandomForestRegressor was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model3, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"Random Forest\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZsLwLivhLGH" + }, + "source": [ + "## 4. Gradient Boosting Models (GBM)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "id": "TI8idoxOg6jF" + }, + "outputs": [], + "source": [ + "model4 = GradientBoostingRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "2gpbDxshhexj", + "outputId": "ab69dc0b-68ff-48fb-850f-3d2ab331b1b5" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "GradientBoostingRegressor()" + ], + "text/html": [ + "
GradientBoostingRegressor()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 44 + } + ], + "source": [ + "# Train the model\n", + "model4.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "id": "Jj9DXdUPhh9V", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "50374f0b-48ff-4d33-8c3b-1f0b4931acb6" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 224.41069433522418\n", + "MAE: 162.27122816197573\n", + "MAPE: 0.7378541693598378\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but GradientBoostingRegressor was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model4, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"GBM\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d8nSGoyuh9dx" + }, + "source": [ + "## 5. Extreme Gradient Boosting (XGBoost)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "id": "DyhhdlZAhx94" + }, + "outputs": [], + "source": [ + "import xgboost as xgb\n", + "# Create an XGBoost model\n", + "model5 = xgb.XGBRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 253 + }, + "id": "RAIwxIp5iH9Z", + "outputId": "5ebf857b-aab1-424e-c1ff-de451830d25f" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "XGBRegressor(base_score=None, booster=None, callbacks=None,\n", + " colsample_bylevel=None, colsample_bynode=None,\n", + " colsample_bytree=None, device=None, early_stopping_rounds=None,\n", + " enable_categorical=False, eval_metric=None, feature_types=None,\n", + " gamma=None, grow_policy=None, importance_type=None,\n", + " interaction_constraints=None, learning_rate=None, max_bin=None,\n", + " max_cat_threshold=None, max_cat_to_onehot=None,\n", + " max_delta_step=None, max_depth=None, max_leaves=None,\n", + " min_child_weight=None, missing=nan, monotone_constraints=None,\n", + " multi_strategy=None, n_estimators=None, n_jobs=None,\n", + " num_parallel_tree=None, random_state=None, ...)" + ], + "text/html": [ + "
XGBRegressor(base_score=None, booster=None, callbacks=None,\n",
+              "             colsample_bylevel=None, colsample_bynode=None,\n",
+              "             colsample_bytree=None, device=None, early_stopping_rounds=None,\n",
+              "             enable_categorical=False, eval_metric=None, feature_types=None,\n",
+              "             gamma=None, grow_policy=None, importance_type=None,\n",
+              "             interaction_constraints=None, learning_rate=None, max_bin=None,\n",
+              "             max_cat_threshold=None, max_cat_to_onehot=None,\n",
+              "             max_delta_step=None, max_depth=None, max_leaves=None,\n",
+              "             min_child_weight=None, missing=nan, monotone_constraints=None,\n",
+              "             multi_strategy=None, n_estimators=None, n_jobs=None,\n",
+              "             num_parallel_tree=None, random_state=None, ...)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 47 + } + ], + "source": [ + "# Train the model\n", + "model5.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "bnYw1a5c_jwx", + "outputId": "bda19c24-daa6-40bb-e48f-660fee73a52e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 224.66436370022384\n", + "MAE: 162.62070643817412\n", + "MAPE: 0.7441437311249671\n", + "\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model5, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"XGBoost\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A_J776rtiovq" + }, + "source": [ + "## 6. AdaBoostRegressor" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "id": "HNq66cXRiYPJ" + }, + "outputs": [], + "source": [ + "model6 = AdaBoostRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "P0oB5wjQivBr", + "outputId": "b8e7393d-5138-4b3c-833b-640672a4beb6" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "AdaBoostRegressor()" + ], + "text/html": [ + "
AdaBoostRegressor()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 50 + } + ], + "source": [ + "# Train the model\n", + "model6.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "id": "Bf1m5ukOi2VM", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "41fc806f-3c12-423b-ae9b-ba9874fefe9e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 211.36161901329982\n", + "MAE: 149.9890662222131\n", + "MAPE: 0.7121386513977549\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but AdaBoostRegressor was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model6, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"AdaBoost Regressor\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q9DzOt3CkWFX" + }, + "source": [ + "## 7. Decision Tree" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "id": "23DZ2biSjF9a" + }, + "outputs": [], + "source": [ + "model7 = DecisionTreeRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "6mQEQf-ykc9F", + "outputId": "dc88b808-8e16-4aee-f8ce-ad0b85b24454" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeRegressor()" + ], + "text/html": [ + "
DecisionTreeRegressor()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 55 + } + ], + "source": [ + "# Train the model\n", + "model7.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "id": "BFJ9q_tvkgRC", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "e82ed0dc-b355-49b2-bd2a-72f2981fdeab" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 225.19713405326468\n", + "MAE: 163.35574713804317\n", + "MAPE: 0.7574890717636951\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but DecisionTreeRegressor was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model7, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"Decision Tree\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LH-B-Xd6k5UD" + }, + "source": [ + "## 8. KNeighborsRegressor(KNN)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "id": "JVDSed7yktFY" + }, + "outputs": [], + "source": [ + "# Create a KNN model\n", + "model8 = KNeighborsRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 80 + }, + "id": "9fn64o-ZlBka", + "outputId": "9ba9909b-2806-45d8-8da9-70ac96bd56cd" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "KNeighborsRegressor()" + ], + "text/html": [ + "
KNeighborsRegressor()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ] + }, + "metadata": {}, + "execution_count": 58 + } + ], + "source": [ + "# Train the model\n", + "model8.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "id": "hbfbbjcSlDn7", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "8cca4954-9613-4f60-d170-4a408b488315" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "RMSE: 224.35603706259303\n", + "MAE: 162.1962430618594\n", + "MAPE: 0.7365233640314862\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/sklearn/base.py:493: UserWarning: X does not have valid feature names, but KNeighborsRegressor was fitted with feature names\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model8, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"KNN\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X5XtlzMXljps" + }, + "source": [ + "## 9. Artificial Neural Networks (ANN)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "id": "vd1fDjQiltP4", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "5c456ea1-3547-466b-ccce-feecfbfa0f3a" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/keras/src/layers/core/dense.py:87: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n" + ] + } + ], + "source": [ + "# Create an ANN model\n", + "model9 = Sequential()\n", + "model9.add(Dense(32, activation='relu', input_shape=(X_train.shape[1],)))\n", + "model9.add(Dense(16, activation='relu'))\n", + "model9.add(Dense(1, activation='linear'))" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "id": "ZIf94WLMlv04" + }, + "outputs": [], + "source": [ + "# Compile the model\n", + "model9.compile(loss='mean_squared_error', optimizer='adam')" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "FX5DTKqslxWf", + "outputId": "a5970819-9228-43d2-f8d7-bf65e9d1d8e6" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 62 + } + ], + "source": [ + "# Train the model\n", + "model9.fit(X_train_scaled, y_train, epochs=100, batch_size=32, verbose=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "OVW2qpNsmGVq", + "outputId": "943f6965-6f55-4809-c5a6-f283f2747302" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m45/45\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step\n", + "RMSE: 2.7036599647041113\n", + "MAE: 1.7039873959709564\n", + "MAPE: 0.011998266947406744\n", + "\n" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model9, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"ANN\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vjSMQNcOnFPJ" + }, + "source": [ + "## 10. LSTM(Long Short term Memory)" + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import LSTM, Dense\n", + "from sklearn.metrics import mean_squared_error, mean_absolute_error, mean_absolute_percentage_error" + ], + "metadata": { + "id": "erKkl-ObHQxB" + }, + "execution_count": 95, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": { + "id": "uACvajfImrbB" + }, + "outputs": [], + "source": [ + "# Reshape the input data for LSTM\n", + "n_features = X_train_scaled.shape[1]\n", + "n_steps = 10\n", + "n_samples_train = X_train_scaled.shape[0] - n_steps + 1\n", + "n_samples_test = X_test_scaled.shape[0] - n_steps + 1\n", + "\n", + "# Reshape the input data\n", + "X_train_reshaped = np.array([X_train_scaled[i:i+n_steps, :] for i in range(n_samples_train)])\n", + "X_test_reshaped = np.array([X_test_scaled[i:i+n_steps, :] for i in range(n_samples_test)])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": { + "id": "r066pVYpnXH5", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "5d3737c9-0d2b-4b99-8440-0509f85de320" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/keras/src/layers/rnn/rnn.py:204: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(**kwargs)\n" + ] + } + ], + "source": [ + "# Create an LSTM model\n", + "model = Sequential()\n", + "model.add(LSTM(64, activation='relu', input_shape=(n_steps, n_features)))\n", + "model.add(Dense(1))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": { + "id": "YpSfHu6gov35" + }, + "outputs": [], + "source": [ + "# Compile the model\n", + "model.compile(loss='mean_squared_error', optimizer='adam')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0vHjcluaoxzP", + "outputId": "141e355b-db00-4797-ea35-1b2e35a89674" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 100 + } + ], + "source": [ + "# Train the model\n", + "model.fit(X_train_reshaped, y_train[n_steps-1:], epochs=100, batch_size=32, verbose=0)" + ] + }, + { + "cell_type": "code", + "source": [ + "#Error correction :\n", + "# Assuming your X_test_scaled has 4 features\n", + "n_steps = 10 # Define your time steps\n", + "\n", + "# Function to create sequences\n", + "def create_sequences(data, n_steps):\n", + " X = []\n", + " for i in range(len(data) - n_steps):\n", + " X.append(data[i:i+n_steps])\n", + " return np.array(X)\n", + "\n", + "# Reshape X_test_scaled\n", + "X_test_reshaped = create_sequences(X_test_scaled, n_steps)\n", + "\n", + "# Now X_test_reshaped should be of shape (samples, 10, 4)\n", + "predictions = model.predict(X_test_reshaped)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Y93w73L5Gn4k", + "outputId": "a635e24f-4697-4bb2-bc72-1d5fb2d03271" + }, + "execution_count": 107, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m44/44\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 6ms/step\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_train_reshaped = create_sequences(X_train_scaled, n_steps)\n", + "y_train_reshaped = y_train[n_steps:]\n", + "X_test_reshaped = create_sequences(X_test_scaled, n_steps)\n", + "y_test_reshaped = y_test[n_steps:]" + ], + "metadata": { + "id": "U-ofR-95J4Gc" + }, + "execution_count": 105, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 211 + }, + "id": "gEE06_TjozYv", + "outputId": "565e3304-3007-498b-c098-a268333a6ec6" + }, + "outputs": [ + { + "output_type": "error", + "ename": "TypeError", + "evalue": "evaluate_model() takes 2 positional arguments but 3 were given", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrmse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmae\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmape\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mevaluate_model\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_test_scaled\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_test\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Model\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"LSTM\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"RMSE\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrmse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"MAE\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmae\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"MAPE\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: evaluate_model() takes 2 positional arguments but 3 were given" + ] + } + ], + "source": [ + "rmse, mae, mape = evaluate_model(model, X_test_scaled, y_test)\n", + "metrics[\"Model\"].append(\"LSTM\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "#1\n", + "# Generate predictions\n", + "# Assuming your X_test_scaled has 4 features\n", + "n_steps = 10 # Define your time steps\n", + "\n", + "# Function to create sequences\n", + "def create_sequences(data, n_steps):\n", + " X = []\n", + " for i in range(len(data) - n_steps):\n", + " X.append(data[i:i+n_steps])\n", + " return np.array(X)\n", + "\n", + "# Reshape X_test_scaled using the create_sequences function\n", + "X_test_reshaped = create_sequences(X_test_scaled, n_steps)\n", + "\n", + "predictions = model.predict(X_test_reshaped) #Use the reshaped X_test_scaled\n", + "\n", + "#Evaluate the model with the predictions and actual values\n", + "rmse, mae, mape = evaluate_model(predictions, y_test[n_steps:]) # Make sure to use the same number of steps for y_test\n", + "\n", + "metrics[\"Model\"].append(\"LSTM\")\n", + "metrics[\"RMSE\"].append(rmse)\n", + "metrics[\"MAE\"].append(mae)\n", + "metrics[\"MAPE\"].append(mape)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "7E-_u_xVKiB9", + "outputId": "5424821d-47be-4b77-e636-e22aaafd51b1" + }, + "execution_count": 114, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m44/44\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 264ms/step\n" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 507 + }, + "id": "P2Jk8F7R_jw4", + "outputId": "bee3b0c8-2a8a-4318-f89a-238d97ca2f2e" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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3JXA0L59ex07dkzDhw9XcnKy7r//fi1atCjDQEgAAPDPcNcGPfbv3z/LSxD3MqfTqdjY2AyXUP6J7qVapXurXmq9c+6leu+lWqV7q15q/fs5zK3cSwEAAP6n8eNTAADAFoEBAADY+kcFBofDofnz59/tMpCDOKZ3z4gRI3T//fff7TLuWREREZo4cWKOtwXuVX9rYOjevbv13QuZSUpKUpMmTf6+grLJ4XBYU0BAgCpVqqQvv/zybpfl4tixY3ryySdVpEgROZ1O+fj4uNQdFBSkIUOG6NKlSy6PGz16tPLnz6/U1FTFx8db7d3c3FSgQAG1b99eBw8evEtblX3du3d32e70affu3be1vuTkZD3zzDOKioqSt7e38ufPrxo1aujdd9/VhQsXJF1700h/Hnd3d4WFhalXr146efKkVVPNmjXlcDiUJ0+eDMdgw4YN1uOrV6+uVq1auSxfsmSJHA6HoqKirHlz5sxRvXr1lCdPHvn4+KhEiRLq2bOnNm/ebLW5/ng6HA75+/urQoUKmjt3bobttNuGv6JOnTp69tlnbdutXLlSDodDp06dyrDs+uPq4eHhsl158+ZV06ZNtW3btr9cq3TtePTp0yfH296OrF7P6VNERESmj7nxfPvFF1/I29tb48ePt9b52muvubSZP3++yxfipR+P0qVL6+rVqy5tc+fOrfj4+JzaTCUkJMjd3V3NmjVzmb9//345HA6FhITo7FnXr2m+//77NWLECOvvOnXqyOFw6JNPPnFpN3HixEz306242XvX1q1b9eijjyokJETe3t6KiIhQ+/btdfToUY0YMeKmxy19P6cfi759+2ZYf79+/eRwONS9e/fbqj0n/aN6GEJDQ+/6KFJjjK5cuZLl8ri4OCUlJWnjxo2qUaOG2rRpk2MnqKxcvnz5ltu2bt1amzdv1vTp07Vz507Vr19fxYsXV3x8vHr27CkfHx+99957io2NtR5jjFF8fLy6desmT09PSde+YCQpKUl//PGH5syZo8TERLVt29Z6TGpqas5t4B3SuHFjJSUluUxFixbN9nr27t2rBx54QN99951effVVbd68WQkJCRoyZIgWLFigpUuXWm1HjRqlpKQkHTx4UDNnztSqVav09NNPZ1hnrly5NG/ePJd5U6dOVZEiRSRde5NftGiRZs6caS1/6qmnlDdvXh05ckSHDx/W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\n" + }, + "metadata": {} + } + ], + "source": [ + "# Create a DataFrame for metrics\n", + "metrics_df = pd.DataFrame(metrics)\n", + "\n", + "# Plot RMSE, MAE, and MAPE for each model\n", + "plt.figure(figsize=(15, 5))\n", + "\n", + "# RMSE Plot\n", + "plt.subplot(1, 3, 1)\n", + "plt.bar(metrics_df['Model'], metrics_df['RMSE'], color='lightblue')\n", + "plt.xlabel('RMSE')\n", + "plt.title('RMSE for Different Models')\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 487 + }, + "id": "RW1-bwnT_jw4", + "outputId": "f54134c1-1bd5-40d4-cd06-a8e02c994eb7" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": {} + } + ], + "source": [ + "# MAE Plot\n", + "plt.subplot(1, 3, 2)\n", + "plt.bar(metrics_df['Model'], metrics_df['MAE'], color='lightgreen')\n", + "plt.xlabel('MAE')\n", + "plt.title('MAE for Different Models')\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 487 + }, + "id": "LoKadLzp_jw4", + "outputId": "8ec481bd-24a6-42e1-840a-9ce417ea159a" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": {} + } + ], + "source": [ + "# MAPE Plot\n", + "plt.subplot(1, 3, 3)\n", + "plt.bar(metrics_df['Model'], metrics_df['MAPE'], color='salmon')\n", + "plt.xlabel('MAPE')\n", + "plt.title('MAPE for Different Models')\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "source": [ + "#Incorporate feature engineering for enhanced model performance\n", + "issue #16\n" + ], + "metadata": { + "id": "u_nHHAZ0MP4u" + } + }, + { + "cell_type": "code", + "source": [ + "def calculate_sma(data, window):\n", + " \"\"\"Calculate Simple Moving Average.\"\"\"\n", + " return data['Close'].rolling(window=window).mean()\n", + "\n", + "def calculate_ema(data, window):\n", + " \"\"\"Calculate Exponential Moving Average.\"\"\"\n", + " return data['Close'].ewm(span=window, adjust=False).mean()\n", + "\n", + "# Define the windows for SMA and EMA\n", + "sma_window = 14 # For example, 14-day SMA\n", + "ema_window = 14 # For example, 14-day EMA\n", + "\n", + "# Calculate SMA and EMA\n", + "df['SMA'] = calculate_sma(df, sma_window)\n", + "df['EMA'] = calculate_ema(df, ema_window)\n", + "\n", + "# Display the updated DataFrame\n", + "print(df[['Close', 'SMA', 'EMA']].tail()) # Check the last few rows\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "oR-K9Uo1L2Xs", + "outputId": "4c223987-eff4-4c8e-c278-a010b158083c" + }, + "execution_count": 118, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " Close SMA EMA\n", + "7069 642.950012 629.521432 633.617826\n", + "7070 650.250000 630.475002 635.835449\n", + "7071 675.250000 633.992859 641.090723\n", + "7072 699.549988 639.082145 648.885291\n", + "7073 725.250000 646.046430 659.067253\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "The stock is showing a closing price of 725.25, with both the SMA and EMA being lower, suggesting a potential upward trend" + ], + "metadata": { + "id": "ZxUKlrMxMJql" + } + }, + { + "cell_type": "code", + "source": [ + "# Define features and target variable\n", + "features = df[['Open', 'High', 'Low', 'Close', 'SMA', 'EMA']].dropna() # Drop rows with NaN values\n", + "target = df['Close'][features.index] # Align the target variable\n", + "\n", + "# Split the data into training and testing sets\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2, random_state=42)\n" + ], + "metadata": { + "id": "fdA2RvjGL4x0" + }, + "execution_count": 119, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Scale (as a precaution)\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "scaler = MinMaxScaler()\n", + "X_train_scaled = scaler.fit_transform(X_train)\n", + "X_test_scaled = scaler.transform(X_test)\n", + "\n", + "# Reshape for LSTM (if applicable)\n", + "n_steps = 10 # Define your time steps\n", + "n_features = X_train_scaled.shape[1]\n", + "\n", + "# Reshape the input data for LSTM\n", + "X_train_reshaped = np.array([X_train_scaled[i:i+n_steps, :] for i in range(X_train_scaled.shape[0] - n_steps)])\n", + "X_test_reshaped = np.array([X_test_scaled[i:i+n_steps, :] for i in range(X_test_scaled.shape[0] - n_steps)])\n", + "\n", + "#Train the model again!!!\n" + ], + "metadata": { + "id": "Lj5tdQZ1L8BG" + }, + "execution_count": 120, + "outputs": [] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "EuwyRiIUL-xd" + }, + "execution_count": null, + "outputs": [] + } + ], + "metadata": { + "colab": { + "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.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file