{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":82611,"databundleVersionId":9553358,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport pandas.api.types as ptypes\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler, LabelEncoder\nfrom sklearn.impute import SimpleImputer\nimport optuna\nimport xgboost as xgb\nfrom xgboost import XGBRegressor\nfrom sklearn.metrics import mean_squared_error\nfrom datetime import datetime\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-11-09T16:26:47.402025Z","iopub.execute_input":"2024-11-09T16:26:47.402345Z","iopub.status.idle":"2024-11-09T16:26:49.642895Z","shell.execute_reply.started":"2024-11-09T16:26:47.402308Z","shell.execute_reply":"2024-11-09T16:26:49.641913Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# activity key, value pair\n\nactivitis_dict = {\"Indoor climbing\" : 1, \"Run\" : 2, \"Strength training\" : 3, \"Swim\" : 4, \"Bike\" : 5, \"Dancing\" : 6, \n             \"Stairclimber\" : 7, \"Spinning\" : 8, \"Walking\" : 9, \"HIIT\" : 10, \"Outdoor Bike\" : 11, \"Walk\" : 12, \"Aerobic Workout\" : 13,\n             \"Tennis\" : 14, \"Workout\" : 15, \"Hike\" : 16, \"Zumba\": 17, \"Sport\" : 18, \"Yoga\" : 19, \"Swimming\" : 20, \"Weights\" : 21,\n             \"Running\" : 22, \"Cycling\" : 23, \"CoreTraining\" : 24, \"-1\" : -1}","metadata":{"execution":{"iopub.status.busy":"2024-11-09T16:26:54.228330Z","iopub.execute_input":"2024-11-09T16:26:54.229597Z","iopub.status.idle":"2024-11-09T16:26:54.235228Z","shell.execute_reply.started":"2024-11-09T16:26:54.229553Z","shell.execute_reply":"2024-11-09T16:26:54.234264Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dataset Processing and some explotation","metadata":{}},{"cell_type":"code","source":"#%%writefile dataset_preprocessing.py\nclass Explore_Dataset_and_Post_Processing:\n    def __init__(self, train_csv_path):\n        assert train_csv_path is not None, \"train_csv_path cannot be none\"\n        self.train_csv_path = train_csv_path\n        self.train_df = pd.read_csv(self.train_csv_path)\n        self.column_prefixes = ['bg', 'insulin', 'carbs', 'hr', 'steps', 'cals', 'activity']\n    \n    # some general functions\n    def get_shape(self):\n        return self.train_df.shape\n    \n    def get_df_description(self):\n        return self.train_df.describe()\n    \n    def get_column_wise_null(self):\n        \"\"\"\n        return the number of values that are null\n        \"\"\"\n        return self.train_df.isnull().sum()\n    \n    def get_percentage_of_missing_values(self): \n        \"\"\"\n        returns the pecentage of missing values\n        \"\"\"\n        # getting the percentage of missing values\n        missing_values = self.train_df.isnull().sum()\n        total_rows = self.train_df.shape[0]\n        missing_percentage = (missing_values / total_rows) * 100\n\n        results_df = pd.DataFrame({'Column': missing_values.index,\n                                  'Missing Values': missing_values.values,\n                                  'Missing Percentage (%)': missing_percentage.values})\n\n        results_df = results_df.sort_values(by='Missing Percentage (%)', ascending=False)\n        return results_df\n    \n    def pp_convert_datetime(self):\n        \"\"\"\n        converts the time column to date and time\n        \"\"\"\n        assert ptypes.is_datetime64_any_dtype(self.train_df[\"time\"]) is not True, \"DateTime is already converted\" \n        self.train_df.time = pd.to_datetime(self.train_df.time, format='%H:%M:%S')\n        return self\n        \n    def pp_replace_null_values(self):\n        \"\"\"\n        replace all null values with 0\n        \"\"\"\n        # check if nan values are present\n        has_nan = self.train_df.isnull().values.any()\n        if not has_nan:\n            print(\"No existing null values in the dataframe.\")\n        else:\n            self.train_df = self.train_df.fillna(0)\n        return self\n    \n    def pp_replace_null_with_fill_forward(self):\n        \"\"\"\n        Replacing the Nan with values with fill forward for bg, insulin and heartrate columns\n        Reference : https://www.kaggle.com/code/vineetgupta2023/key-insights-from-xgboost-score-2-200\n        \"\"\"\n        # blood glucose\n        bg_columns = [col for col in self.train_df.columns if col.startswith('bg-')]\n        self.train_df[bg_columns] = self.train_df[bg_columns].fillna(method='ffill', axis=1)\n        self.train_df[bg_columns] = self.train_df[bg_columns].fillna(method='bfill', axis=1)\n        \n        # insulin\n        insulin_columns = [col for col in self.train_df.columns if col.startswith('insulin-')]\n        self.train_df[insulin_columns] = self.train_df[insulin_columns].fillna(method='ffill', axis=1)\n        self.train_df[insulin_columns] = self.train_df[insulin_columns].fillna(method='bfill', axis=1)\n        \n        # heart rate\n        hr_columns = [col for col in self.train_df if col.startswith('hr-')]\n        self.train_df[hr_columns] = self.train_df[hr_columns].fillna(method='ffill', axis=1)\n        self.train_df[hr_columns] = self.train_df[hr_columns].fillna(method='bfill', axis=1)\n        return self\n\n    def pp_fill_Nan_with_negative_one(self):\n        \"\"\"\n        function to fill the \n        \"\"\"\n        self.train_df = self.train_df.fillna(-1)\n        return self\n    \n    def pp_drop_id_pnum_column(self):\n        self.train_df = self.train_df.drop([\"id\", \"p_num\", \"time\"], axis=1)\n        return self\n        \n    def pp_map_activities_to_number(self, activity_dict):\n        \"\"\"\n        Fuction to map the activity names to integers\n        \"\"\"\n        # get all the columns with name activity\n        try:\n            activity_columns = list(self.train_df.filter(like='activity').columns)\n            #self.train_df[activity_columns] = self.train_df[activity_columns].replace(activitis_dict)\n            for col in activity_columns:\n                self.train_df[col] = self.train_df[col].apply(lambda x: activitis_dict.get(x, -1) if x != '' else -1)\n        except AssertionError as e:\n            print(f\"AssertionError caught: {e}\")\n        return self\n            \n    def pp_replace_nan_with_mean(self):\n        \"\"\"\n        Function to replace the nan values with mean\n        \"\"\"\n        # get the numerical columns in the dataset\n        numerical_columns = self.train_df.select_dtypes(include = ['number']).columns\n        \n        # now replace for every column with nan values the  mean of that column\n        self.train_df[numerical_columns] = self.train_df[numerical_columns].apply(lambda col: col.fillna(col.mean()))\n        return self\n        \n    def pp_normalize_numerical_values(self):\n        \"\"\"\n        Normlaize the numerical values. Here we do min ma normalization\n        \"\"\"\n        # get the numerical columns in the dataset\n        numerical_columns = list(self.train_df.select_dtypes(include = ['number']).columns)\n        for column in numerical_columns:\n            self.train_df[column] = (self.train_df[column] - self.train_df[column].min()) / (self.train_df[column].max() - self.train_df[column].min())\n            \n        return self\n        \n    def pp_impute_numeical_columns(self):\n        numerical_columns = list(self.train_df.select_dtypes(include = ['number']).columns)\n        try:\n            numerical_columns.remove('bg+1:00')\n        except:\n            pass\n        imputer = SimpleImputer(strategy='mean')\n        self.train_df[numerical_columns] = imputer.fit_transform(self.train_df[numerical_columns])\n        scaler = StandardScaler()\n        self.train_df[numerical_columns] = scaler.fit_transform(self.train_df[numerical_columns])\n        return self\n        \n    def pp_encode_categorical_columns(self):\n        categorical_cols = [col for col in self.train_df.columns if 'activity' in col]\n        for col in categorical_cols:\n            self.train_df[col] = self.train_df[col].fillna('None')\n            le = LabelEncoder()\n            self.train_df[col] = le.fit_transform(self.train_df[col])\n        return self\n\n    def pp_drop_columns_with_missing_values(self, missing_df,pecentage):\n        \"\"\"\n        missing_value_df : o/p of the function obtained from \"get_percentage_of_missing_values\"\n        percentage : column with missing values >= pecentage is dropped for training and testing\n        \"\"\"\n        # list of columns with missing values  > 90\n        filtered_columns = missing_df[missing_df['Missing Percentage (%)'] > pecentage]['Column'].tolist()\n        # now drop all these columns\n        self.train_df = self.train_df.drop(filtered_columns, axis = 1)\n        return self\n\n    def pp_carbs_by_doing_hourly_average(self):\n        \"\"\"\n        In this we do the average of the carbs columns.\n        -We average the value of carbs every hour\n        -Hence instead of 12 columns per hour (5 mins interval column), we get 1 column\n        -As we know there is an enormous amount of NaN values in the carbs column, this will atleast help in\n        reducing the number of NaN values\n        \"\"\"\n        # get all the carbs columns \n        carbs_columns = [col for col in self.train_df.columns if col.startswith('carbs-')]\n        hours = ['5', '4', '3', '2', '1', '0']\n        for h in hours:\n             carb_hour_columns = [name for name in carbs_columns if name.startswith(\"carbs-\" + h)]\n             self.train_df[\"average-\"+h+\"-carbs\"] = self.train_df[carb_hour_columns].mean(axis=1)\n        return self\n\n    def pp_steps_by_doing_hourly_average(self):\n        \"\"\"\n        Here we tahe the average of the steps column\n        from my EDA, I have seen second biggest missing value column is steps\n        Hence averaging steps can be also used to reduce dimensionality\n        \"\"\"\n        # get all the steps columns\n        steps_columns = [col for col in self.train_df.columns if col.startswith('steps-')] \n        hours = ['5', '4', '3', '2', '1', '0']\n        for h in hours:\n             step_hour_column = [name for name in steps_columns if name.startswith(\"steps-\" + h)]\n             self.train_df[\"average-\"+h+\"-steps\"] = self.train_df[step_hour_column].mean(axis=1)\n        return self\n\n    def pp_drop_a_list_of_columns_if_needed(self, prefix):\n        \"\"\"\n        This function will help in dropping a list of columns  \n        which we might not be interested in pitting into our training data.\n        It will drop all the columns with that specific prefix\n        \"\"\"\n        assert prefix in self.column_prefixes, \"Please provide the right prefix. The right prefixes are {}\".format(self.column_prefixes)\n        columns_to_drop = [col for col in self.train_df.columns if col.startswith(prefix + '-')]\n        self.train_df = self.train_df.drop(columns_to_drop, axis = 1)\n        return self\n    \n    def get_final_df(self):\n        return self.train_df\n            ","metadata":{"execution":{"iopub.status.busy":"2024-11-09T16:26:56.103570Z","iopub.execute_input":"2024-11-09T16:26:56.103930Z","iopub.status.idle":"2024-11-09T16:26:56.139292Z","shell.execute_reply.started":"2024-11-09T16:26:56.103893Z","shell.execute_reply":"2024-11-09T16:26:56.138434Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Unit Tests if needed ","metadata":{}},{"cell_type":"code","source":"class Unit_Tests:\n    def __init__(self, df):\n        self.df = df\n        \n    def check_nan_replaced_with_mean(self):\n        # first check no Nan values\n        numerical_columns = self.df.select_dtypes(include = ['number']).columns\n        for col in numerical_columns:\n            if self.df[col].isna().sum() == 0:\n                return True\n            else:\n                return False\n\n        \n    def check_values_are_normalized(self):\n        # check if values are normalized\n        numerical_columns = self.df.select_dtypes(include = ['number']).columns\n        for col in numerical_columns:\n            has_greater_than_one = (self.df[col] > 1).any()\n            if has_greater_than_one:\n                return False\n            \n        return True","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## This part will be the Unit tests column\ntrain_csv_path = \"/kaggle/input/brist1d/train.csv\"\nobj_ex = Explore_Dataset_and_Post_Processing(train_csv_path)\nobj_ex.pp_steps_by_doing_hourly_average()\n#obj_ex.pp_normalize_numerical_values()\n\n#obj_utest = Unit_Tests(df = obj_ex.train_df)\n#obj_utest.check_values_are_normalized()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"obj_ex.train_df.columns","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"obj_ex.train_df['average-5-steps'].isna().sum()/len(obj_ex.train_df)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dataset Creation","metadata":{}},{"cell_type":"code","source":"class DatasetCreation:\n    def __init__(self, train_df, activities_dict, train_ratio, test_ratio):\n        self.actvities_dict = activities_dict\n        \"\"\"\n        few assertions and checks needed to be done\n        \"\"\"\n        # check if all nun values are non eistent\n        if train_df.isnull().values.any():\n            raise ValueError(\"There should not be NaN in training data\")\n        \n        # assert that id and p_num is dropped\n        columns = list(train_df.columns)\n        assert \"id\" not in columns, \"There should not be the id column\"\n        assert \"p_num\" not in columns, \"There should not be the p_num column\"\n        \n        # check that all the activities column have dtype float64\n        activity_columns = list(train_df.filter(like='activity').columns)\n        for col in activity_columns:\n            for value in train_df[col]:\n                if value == 0:\n                    pass\n                elif value not in self.actvities_dict.values():\n                    raise AssertionError(f\"Value {value} in column {col} was not correctly mapped!\")\n        \n        # check if train and test ratio is float\n        assert isinstance(train_ratio, float), f\"Expected float, but got {type(x).__name__}\"\n        assert isinstance(test_ratio, float), f\"Expected float, but got {type(x).__name__}\"\n        \n        self.train_df = train_df\n        self.train_ratio = train_ratio\n        self.test_ratio = test_ratio\n        \n    def return_dataset(self):\n        train_X = self.train_df.drop(['bg+1:00'], axis = 1)\n        train_Y = self.train_df['bg+1:00']\n        X_train_split, X_val_split, y_train_split, y_val_split = train_test_split(train_X, train_Y, test_size=self.test_ratio, random_state=42)\n        \n        return X_train_split, X_val_split, y_train_split, y_val_split","metadata":{"execution":{"iopub.status.busy":"2024-11-09T16:27:07.245856Z","iopub.execute_input":"2024-11-09T16:27:07.246728Z","iopub.status.idle":"2024-11-09T16:27:07.256360Z","shell.execute_reply.started":"2024-11-09T16:27:07.246682Z","shell.execute_reply":"2024-11-09T16:27:07.255466Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Defining some setups for post_procecssing","metadata":{}},{"cell_type":"code","source":"train_csv_path = \"/kaggle/input/brist1d/train.csv\"\nobj_data_pipeline = Explore_Dataset_and_Post_Processing(train_csv_path)\n\n# Simple training Data creation pipeline\n\"\"\"\nHere the order of preprocessing is very important\n\"\"\"\n# get the percentage of missing values df\nmissing_values_df = obj_data_pipeline.get_percentage_of_missing_values()\nprint(missing_values_df.head())\n# preporcessing data\nprocessed_train_df = (obj_data_pipeline\n                     .pp_drop_id_pnum_column()\n                      # take the avergae of the carbs \n                     .pp_carbs_by_doing_hourly_average()\n                     # drop the other carb columns \n                     .pp_drop_a_list_of_columns_if_needed(prefix='carbs')\n                     #.pp_replace_null_with_fill_forward()\n                     .pp_map_activities_to_number(activitis_dict)\n                     .pp_fill_Nan_with_negative_one() \n                     .get_final_df())\n\nprint(\"[!] Number of columns in processed df : \", len(processed_train_df.columns))\nobj_data_create = DatasetCreation(processed_train_df, activities_dict=activitis_dict, train_ratio=0.8, test_ratio=0.2)\nx_train, x_val, y_train, y_val  = obj_data_create.return_dataset()\n\nprint(\"Type of X_train : \", type(x_train))","metadata":{"execution":{"iopub.status.busy":"2024-11-09T16:27:18.703731Z","iopub.execute_input":"2024-11-09T16:27:18.704552Z","iopub.status.idle":"2024-11-09T16:27:53.483724Z","shell.execute_reply.started":"2024-11-09T16:27:18.704508Z","shell.execute_reply":"2024-11-09T16:27:53.482674Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# XGBOOST ","metadata":{}},{"cell_type":"markdown","source":"## Using Optuna to do hyper parameter Tuning","metadata":{}},{"cell_type":"code","source":"\"\"\"\nUsing optuna for hyperparameter tuning\n## Refrence : https://www.kaggle.com/code/danishyousuf19/blood-glucose-prediction\n\"\"\"\ndef objective(trial):\n    # Suggest hyperparameters for tuning\n    params = {\n        'objective': 'reg:squarederror',\n        'eval_metric': 'rmse',\n        'booster': 'gbtree',\n        'n_estimators': trial.suggest_int('n_estimators', 50, 1500),\n        'eta': trial.suggest_loguniform('eta', 0.0005, 0.3),  # learning rate\n        'max_depth': trial.suggest_int('max_depth', 3, 15),\n        'min_child_weight': trial.suggest_loguniform('min_child_weight', 1e-4, 10),\n        'subsample': trial.suggest_uniform('subsample', 0.3, 1.0),\n        'colsample_bytree': trial.suggest_uniform('colsample_bytree', 0.09, 1.0),\n        'lambda': trial.suggest_loguniform('lambda', 3, 10),\n        'alpha': trial.suggest_loguniform('alpha', 1e-4, 10),\n        'tree_method': 'hist',  \n        'device':'cuda'\n    }\n    dtrain = xgb.DMatrix(x_train, label=y_train)\n    dvalid = xgb.DMatrix(x_val, label=y_val)\n    \n    # Train the model\n    model = xgb.train(params, dtrain, evals=[(dvalid, 'validation')], num_boost_round=1500, early_stopping_rounds=35, verbose_eval=False)\n    \n    # Predict on the validation set\n    y_pred_valid = model.predict(dvalid)\n    \n    # Calculate RMSE on the validation set\n    rmse = mean_squared_error(y_val, y_pred_valid, squared=False)\n    print(\"RMSE = \",rmse)\n    return rmse","metadata":{"execution":{"iopub.status.busy":"2024-11-09T00:11:31.157118Z","iopub.execute_input":"2024-11-09T00:11:31.157518Z","iopub.status.idle":"2024-11-09T00:11:31.166824Z","shell.execute_reply.started":"2024-11-09T00:11:31.157482Z","shell.execute_reply":"2024-11-09T00:11:31.165888Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"study = optuna.create_study(direction='minimize')\nstudy.optimize(objective, n_trials=10)\nbest_params = study.best_params\nprint(f\"Best hyperparameters: {best_params}\")\n\n","metadata":{"execution":{"iopub.status.busy":"2024-11-09T00:11:35.866474Z","iopub.execute_input":"2024-11-09T00:11:35.867326Z","iopub.status.idle":"2024-11-09T00:37:18.304515Z","shell.execute_reply.started":"2024-11-09T00:11:35.867265Z","shell.execute_reply":"2024-11-09T00:37:18.303408Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## Defining the best params obtained from the previous step\nbest_params = {\n    'n_estimators': 972,\n    'eta': 0.015888055762315247,\n    'max_depth': 13,\n    'min_child_weight': 0.6586914412574061,\n    'subsample': 0.87314071695458,\n    'colsample_bytree': 0.9724644883144354,\n    'lambda': 9.107231966732611, \n    'alpha': 0.040115926843499385\n}","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Class creating the XGBoost Model\n### Depending on the best params received above","metadata":{}},{"cell_type":"code","source":"class Model_XGBoost:\n    def __init__(self, X, Y, random_state,\n                 n_estimators,\n                 objective = 'reg:squarederror', \n                 device = 'cuda'):\n        \"\"\"\n        X : training data X\n        Y : training data Y\n        params : dictionary of paramteres that were predicted above\n        \"\"\"\n        # Train an XGBoost model\n        #params[\"objective\"] = objective\n        #params[\"eval_metric\"] = eval_metric\n        #params[\"device\"] = device\n        #params[\"tree_method\"] = tree_method\n        #params[\"booster\"] = booster\n        self.objective = objective\n        self.n_estimators = n_estimators\n        self.random_state = random_state\n        self.device = device\n        self.X = X\n        self.Y = Y\n    \n    def get_xgb_model(self, params):\n        \"\"\"\n        Using the XGBoost model directly with paramteres we got from optuna\n        \"\"\"\n        dtrain = xgb.DMatrix(self.X, label=self.Y)\n        model = xgb.train(params, dtrain, num_boost_round=1500)\n        return model\n        \n    def get_Regressor_model(self):\n        xgb_model = XGBRegressor(objective = self.objective,\n                                      n_estimators = self.n_estimators, \n                                      random_state = self.random_state,\n                                      device = self.device)\n        return xgb_model\n    \n    def fit(self):\n        self.xgb_model.fit(self.X, self.Y)\n\n    def xgb_predictions(self, model, x_val = None):\n        assert x_val is not None, \"Validation data cannot be None\"\n        xgb_predictions = model.predict(x_val)\n        return xgb_predictions\n    \n    def xgb_rmse(self, y_val, predictions):\n        xgb_rmse = np.sqrt(mean_squared_error(y_val, predictions))\n        return xgb_rmse","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T16:29:27.881921Z","iopub.execute_input":"2024-11-09T16:29:27.882871Z","iopub.status.idle":"2024-11-09T16:29:27.892231Z","shell.execute_reply.started":"2024-11-09T16:29:27.882828Z","shell.execute_reply":"2024-11-09T16:29:27.891112Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\nClass to implement cross validation incase it is needed\n\"\"\"\nfrom sklearn.model_selection import cross_val_score, KFold\nclass CrossValidation:\n    def __init__(self, num_of_splits):\n        self.kf = KFold(n_splits=num_of_splits, shuffle=True, random_state=42)\n    def get_cv(self):\n        return self.kf","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T16:29:30.334127Z","iopub.execute_input":"2024-11-09T16:29:30.334511Z","iopub.status.idle":"2024-11-09T16:29:30.340292Z","shell.execute_reply.started":"2024-11-09T16:29:30.334472Z","shell.execute_reply":"2024-11-09T16:29:30.339116Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training and prediction","metadata":{}},{"cell_type":"code","source":"# here is the experiment to see how number of estimators effect the RMSE\nn_estimators = [100]\nrmse = []\ntime_taken = []\nimplement_cross_validation = True\n\nif implement_cross_validation == False:\n    print(\"[*] Going for Normal XGBOOST\")\n    #for i in n_estimators:\n    start_time = datetime.now()\n    obj_xgb_model = Model_XGBoost(best_params,\n                             random_state= 42,\n                             X = x_train,\n                             Y = y_train)\n\n    #xgb_model.fit()\n    model = obj_xgb_model.get_xgb_model()\n    d_val = xgb.DMatrix(x_val)\n    predictions = model.predict(d_val)\n    #rmse.append(obj_xgb_model.xgb_rmse(y_val, predictions))\n    rmse = obj_xgb_model.xgb_rmse(y_val, predictions)\n    print(\"RMSE : \", rmse)\n    end_time = datetime.now()\n    #time_taken.append(end_time - start_time)\n    print(\"Total time taken : \", end_time - start_time)\nelse:\n    print(\"[*] Going fo Cross validation\")\n    start_time = datetime.now()\n    obj_xg = Model_XGBoost(objective= 'reg:squarederror',\n                             n_estimators= 500,\n                             random_state= 42,\n                             X = x_train,\n                             Y = x_train)\n\n    boost_model = obj_xg.get_Regressor_model()\n\n    obj_cv = CrossValidation(num_of_splits=5)\n    kf = obj_cv.get_cv()\n    \n    for train_index, validation_index in kf.split(x_train):\n        X_train, X_val = x_train.iloc[train_index], x_train.iloc[validation_index]\n        Y_train, Y_val = y_train.iloc[train_index], y_train.iloc[validation_index]\n        boost_model.fit(X_train, Y_train)\n        #models.append(boost_model)\n        predictions = boost_model.predict(x_val)\n        rmse = obj_xg.xgb_rmse(y_val, predictions)\n        #val_predictions_rmse.append(rmse)\n        print(\"Prediction : \", rmse)\n    end_time = datetime.now()\n    time_taken.append(end_time - start_time)\n\n    # saveing the model\n    boost_model.save_model(\"/kaggle/working/xgb_best_model_09_11_2024.bin\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T16:42:41.917682Z","iopub.execute_input":"2024-11-09T16:42:41.918284Z","iopub.status.idle":"2024-11-09T16:43:44.282693Z","shell.execute_reply.started":"2024-11-09T16:42:41.918241Z","shell.execute_reply":"2024-11-09T16:43:44.281749Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\nThis part of the code is only valid when we plot how rmse and n_estimators \n\"\"\"\n\n# some utility stuff for plotting\nimport matplotlib.pyplot as plt\n# Plotting RMSE vs n_estimators\nplt.figure(figsize=(14, 6))\n\n# First subplot for RMSE vs n_estimators\nplt.subplot(1, 2, 1)\nplt.plot(n_estimators, rmse, marker='o', color='b')\nplt.title('RMSE vs Number of Estimators')\nplt.xlabel('Number of Estimators')\nplt.ylabel('RMSE')\nplt.grid(True)\n\n# Second subplot for Time taken vs n_estimators\ntime_taken_in_seconds = [t.total_seconds() for t in time_taken]\nplt.subplot(1, 2, 2)\nplt.plot(n_estimators, time_taken_in_seconds, marker='o', color='r')\nplt.title('Time Taken vs Number of Estimators')\nplt.xlabel('Number of Estimators')\nplt.ylabel('Time Taken (seconds)')\nplt.grid(True)\n\n# Show the plots\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### From the above graph we can observe the following\n1. RMSE decreases non-linearly with the increase in the number of estimators\n2. Time increases linearly with the number of estimators","metadata":{}},{"cell_type":"markdown","source":"# Test And Submission ","metadata":{}},{"cell_type":"markdown","source":"Here this is just for my test and finalizing which model will I be using.\n\nI am using a separate notebook for submission","metadata":{}},{"cell_type":"code","source":"final_xgb_model = Model_XGBoost(objective= 'reg:squarederror',\n                             n_estimators= 700,\n                             random_state= 42,\n                             X = x_train,\n                             Y = y_train)\nfinal_xgb_model.fit()\nfinal_xgb_model.xgb_model.save_model(\"/kaggle/working/xgb_est_700_20_10_2024.bin\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load_submission_df\nsubmission_df = pd.read_csv(\"/kaggle/input/brist1d/sample_submission.csv\")\n\n# load test_csv\ntest_csv_path = \"/kaggle/input/brist1d/test.csv\"\nobj_ex_test = Explore_Dataset_and_Post_Processing(test_csv_path)\n\n# Simple training Data creation pipeline\nobj_ex_test.pp_convert_datetime()\nobj_ex_test.pp_drop_id_pnum_column()\n#obj_ex.pp_replace_nan_with_mean()\n#obj_ex.pp_normalize_numerical_values()\n#obj_ex.pp_replace_null_values()\n#obj_ex.pp_map_activities_to_number(activitis_dict)\nobj_ex_test.pp_impute_numeical_columns()\nobj_ex_test.pp_encode_categorical_columns()\nobj_ex_test.pp_replace_null_values()\n\n# Choose the best model based on validation performance and make predictions on the test set\n\ntest_predictions = xgb_model.predict(obj_ex_test.train_df)\n\n# Create a submission DataFrame\nsubmission_df['bg+1:00'] = test_predictions\n\n# Save the submission file\nsubmission_df.to_csv('submission.csv', index=False)\n\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## The 700 model  is not helping at all","metadata":{}}]}