{"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":"none","dataSources":[{"sourceId":82611,"databundleVersionId":9553358,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Import necessary libraries\nimport pandas as pd\nimport logging\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport xgboost as xgb\nimport lightgbm as lgb\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.impute import SimpleImputer\nfrom xgboost import XGBRegressor\nfrom sklearn.ensemble import RandomForestRegressor\nfrom sklearn.metrics import mean_squared_error\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:08:51.788127Z","iopub.execute_input":"2024-11-29T20:08:51.788848Z","iopub.status.idle":"2024-11-29T20:08:51.799355Z","shell.execute_reply.started":"2024-11-29T20:08:51.788805Z","shell.execute_reply":"2024-11-29T20:08:51.798455Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import logging\nimport sys\n\n# Create a custom logger\nlogger = logging.getLogger()\n\n# Set the logging level\nlogger.setLevel(logging.DEBUG)\n\n# Clear any existing handlers\nif logger.hasHandlers():\n    logger.handlers.clear()\n\n# Create a handler to output to console\nstream_handler = logging.StreamHandler(sys.stdout)\nstream_handler.setLevel(logging.DEBUG)\n\n# Create a formatter and add it to the handler\nformatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\nstream_handler.setFormatter(formatter)\n\n# Add the handler to the logger\nlogger.addHandler(stream_handler)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:11:12.906563Z","iopub.execute_input":"2024-11-29T20:11:12.906999Z","iopub.status.idle":"2024-11-29T20:11:12.913304Z","shell.execute_reply.started":"2024-11-29T20:11:12.906964Z","shell.execute_reply":"2024-11-29T20:11:12.912303Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"logging.info(\"This is an info message.\")\nlogging.debug(\"This is a debug message.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:11:25.127465Z","iopub.execute_input":"2024-11-29T20:11:25.127861Z","iopub.status.idle":"2024-11-29T20:11:25.135364Z","shell.execute_reply.started":"2024-11-29T20:11:25.127827Z","shell.execute_reply":"2024-11-29T20:11:25.134395Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Loading dataset\ntrain = pd.read_csv(\"/kaggle/input/brist1d/train.csv\", low_memory=False)\ntest = pd.read_csv(\"/kaggle/input/brist1d/test.csv\", low_memory=False)","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:11:25.677925Z","iopub.execute_input":"2024-11-29T20:11:25.678332Z","iopub.status.idle":"2024-11-29T20:11:44.003687Z","shell.execute_reply.started":"2024-11-29T20:11:25.678297Z","shell.execute_reply":"2024-11-29T20:11:44.002610Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Data Preprocessing: `time_cycling(df)`\r\n\r\nThe `time_cycling` function takes a DataFrame `df` with a column called `'time'` (in the format `HH:MM:SS`) and performs the following steps:\r\n\r\n1. **Converts the 'time' column to datetime format**:\r\n   - The `time` column in the DataFrame is converted to a pandas `datetime` object using `pd.to_datetime()`. The format of the time is specified as `%H:%M:%S`.\r\n\r\n2. **Extracts hours and minutes**:\r\n   - The hours are extracted from the `time` column using `.dt.hour`, and the minutes are extracted using `.dt.minute`.\r\n\r\n3. **Applies cyclic transformations (sin and cos)**:\r\n   - **Hour transformation**:\r\n     - The function computes the cyclic representations of the hour using sine (`hour_sin`) and cosine (`hour_cos`).\r\n     - The formulas are:\r\n       - `hour_sin = np.sin(2 * np.pi * hour / 24)`\r\n       - `hour_cos = np.cos(2 * np.pi * hour / 24)`\r\n     - These transformations map hours onto a continuous circular scale, where the values repeat every 24 hours.\r\n\r\n   - **Minute transformation**:\r\n     - Similarly, the sine and cosine transformations for the minutes are calculated using the same cyclic formulas:\r\n       - `minute_sin = np.sin(2 * np.pi * minute / 60)`\r\n       - `minute_cos = np.cos(2 * np.pi * minute / 60)`\r\n     - These transformations map minutes onto a continuous circular scale, where values repeat every 60 minutes.\r\n\r\n4. **Drops the original 'time' column**:\r\n   - The original `'time'` column is removed from the DataFrame using `df.drop(columns=['time'], inplace=True)` as it is no longer needed.\r\n\r\n5. **Returns the modified DataFrame**:\r\n   - The DataFrame with the added cyclic features (`hour_sin`, `hour_cos`, `minute_sin`, and `minute_cos`) is returned.\r\n\r\n### Use Case\r\n\r\nThis function is useful when you want to represent cyclical time features (like hours and minutes) in a machine learning model, ensuring that the model understands the periodic nature of time (e.g., midnight is close to 23:59).\r\n","metadata":{}},{"cell_type":"code","source":"def time_cycling(df):\n    time_col = pd.to_datetime(df['time'], format='%H:%M:%S')\n    hours = time_col.dt.hour\n    minutes = time_col.dt.minute\n    df['hour_sin'] = np.sin(2 * np.pi * hours / 24)\n    df['hour_cos'] = np.cos(2 * np.pi * hours / 24)\n    df['minute_sin'] = np.sin(2 * np.pi * minutes / 60)\n    df['minute_cos'] = np.cos(2 * np.pi * minutes / 60)\n    df.drop(columns=['time'], inplace=True)\n    return df","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:11:44.005774Z","iopub.execute_input":"2024-11-29T20:11:44.006562Z","iopub.status.idle":"2024-11-29T20:11:44.012759Z","shell.execute_reply.started":"2024-11-29T20:11:44.006515Z","shell.execute_reply":"2024-11-29T20:11:44.011916Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = time_cycling(train)\ntest = time_cycling(test)","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:11:44.014231Z","iopub.execute_input":"2024-11-29T20:11:44.014936Z","iopub.status.idle":"2024-11-29T20:11:44.438546Z","shell.execute_reply.started":"2024-11-29T20:11:44.014891Z","shell.execute_reply":"2024-11-29T20:11:44.437770Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Code Explanation: Data Preprocessing\n\nThe provided code performs several preprocessing steps on the `train` DataFrame, including mapping and column dropping. Below is the explanation of each step:\n**Mapping 'p_num' to Numeric Values**:\n**Dropping the 'id' Column (if it exists)** \n\n### Purpose\n\n- The primary purpose of this code is to map categorical `p_num` values to numeric values for machine learning models, as most models perform better with numeric features.\n- It also ensures that any unnecessary columns like `id` (which may be used as an identifier) are removed from the dataset, preparing it for further analysis or modeling.","metadata":{}},{"cell_type":"code","source":"\n# Assuming train is a DataFrame\nmapping_dict = {p: idx for idx, p in enumerate(train['p_num'].unique())}\n\n# Map p_num and process time directly\ntrain['p_num'] = train['p_num'].map(mapping_dict)\n\n\n# Drop the 'id' column if it exists\nif 'id' in train.columns:\n    train.drop(columns=['id'], inplace=True)\n\n# Output the processed DataFrame for verification\ntrain.head()\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:11:56.779758Z","iopub.execute_input":"2024-11-29T20:11:56.780488Z","iopub.status.idle":"2024-11-29T20:11:57.187192Z","shell.execute_reply.started":"2024-11-29T20:11:56.780456Z","shell.execute_reply":"2024-11-29T20:11:57.186158Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\n# Assuming train is a DataFrame\nmapping_dict = {p: idx for idx, p in enumerate(test['p_num'].unique())}\n\n# Map p_num and process time directly\ntest['p_num'] = test['p_num'].map(mapping_dict)\n\n# Output the processed DataFrame for verification\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:11:59.424402Z","iopub.execute_input":"2024-11-29T20:11:59.425316Z","iopub.status.idle":"2024-11-29T20:11:59.450986Z","shell.execute_reply.started":"2024-11-29T20:11:59.425279Z","shell.execute_reply":"2024-11-29T20:11:59.450048Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.sample(5)","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:12:00.436583Z","iopub.execute_input":"2024-11-29T20:12:00.436988Z","iopub.status.idle":"2024-11-29T20:12:00.469358Z","shell.execute_reply.started":"2024-11-29T20:12:00.436956Z","shell.execute_reply":"2024-11-29T20:12:00.468380Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Code Overview: Activity Column Processing\r\n\r\n1. **Identifying Activity Columns**:\r\n   - The code identifies columns in the `train` DataFrame that start with the prefix `'activity'` and stores them in the `activity_columns` list.\r\n\r\n2. **Calculating Dominant Activity**:\r\n   - The most frequent activity for each row is calculated using the `mode()` function across the `activity_columns`, and the result is stored in a new column `dominant_activity`.\r\n\r\n3. **Replacing Activity Labels**:\r\n   - The `dominant_activity` values are standardized using a replacement dictionary (`activity_replace`), which maps abbreviations (e.g., `'Walk'`) to full names (e.g., `'Walking'`).\r\n\r\n4. **Dropping Original Activity Columns**:\r\n   - The original activity columns are removed from the DataFrame, leaving only the `dominant_activity` column.\r\n\r\n5. **Logging**:\r\n   - Log messages are used to track the creation and updating of the DataFrame throughout the process.\r\n\r\n### Purpose\r\nThe goal of this code is to summarize and standardize activity data, creating a single column with the dominant activity for each row and removing the redundant activity columns.\r\n","metadata":{}},{"cell_type":"code","source":"activity_columns = [col for col in train.columns if col.startswith('activity')]\ntrain['dominant_activity'] = train[activity_columns].mode(axis=1)[0]\n\nlogging.info(f\"Created summarized DataFrame with dominant activity\")\n\ntrain['dominant_activity'] = train[activity_columns].mode(axis=1)[0]\n\nactivity_replace = {\n    'Walk': 'Walking',\n    'Run': 'Running',\n    'Swim': 'Swimming',\n}\ntrain['dominant_activity'].replace(activity_replace, inplace=True)\ntrain.drop(columns=activity_columns, inplace=True)\nlogging.info(f\"Updated DataFrame after summarization of activity_columns\")","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:12:02.787258Z","iopub.execute_input":"2024-11-29T20:12:02.787636Z","iopub.status.idle":"2024-11-29T20:13:32.660558Z","shell.execute_reply.started":"2024-11-29T20:12:02.787603Z","shell.execute_reply":"2024-11-29T20:13:32.659556Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"activity_columns = [col for col in test.columns if col.startswith('activity')]\ntest['dominant_activity'] = test[activity_columns].mode(axis=1)[0]\nlogging.info(f\"adding dominant activity starting with activity using mode\")\n\ntest['dominant_activity'] = test[activity_columns].mode(axis=1)[0]\n\nactivity_replace = {\n    'Walk': 'Walking',\n    'Run': 'Running',\n    'Swim': 'Swimming',\n}\n\ntest['dominant_activity'].replace(activity_replace, inplace=True)\ntest.drop(columns=activity_columns, inplace=True)\nlogging.info(f\"Updated DataFrame after summarization of activity_columns\")","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:17.597440Z","iopub.execute_input":"2024-11-29T20:15:17.597891Z","iopub.status.idle":"2024-11-29T20:15:19.375026Z","shell.execute_reply.started":"2024-11-29T20:15:17.597855Z","shell.execute_reply":"2024-11-29T20:15:19.373846Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Code Overview: Visualizing Top 10 Dominant Activities\r\n\r\n1. **Counting Activity Frequencies**:\r\n   - The `value_counts()` function is used to count the occurrences of each unique value in the `dominant_activity` column:\r\n    ```\r\n\r\n2. **Selecting the Top 10 Activities**:\r\n   - The `head(10)` method is applied to `activity_counts` to get the top 10 most frequent ac0)\r\n     ```\r\n\r\n3. **Plotting the Data**:\r\n   - A bar chart is created using `matplotlib`, with the following parameters:\r\n     - The size of the figure is set to `(8, 4)`.\r\n     - The `plot()` function creates a bar chart with the `kind='bar'` argument, and the bars are colored green.\r\n     - The plot is labeled with a title, and the x-axis and y-axis are appro     plt.show()\r\n     ```\r\n\r\n### Purpose\r\nThe code visualizes the top 10 most frequent activities in the `dominant_activity` column of the `train` DataFrame as a bar chart, which helps in understanding the distribution of activities in the dataset.\r\n","metadata":{}},{"cell_type":"code","source":"activity_counts = train['dominant_activity'].value_counts()\ntop_5_activities = activity_counts.head(10)\n\nplt.figure(figsize=(8, 4))\ntop_5_activities.plot(kind='bar', color='green')\nplt.title('Top 10 Dominant Activities')\nplt.xlabel('Count')\nplt.ylabel('Activity')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:22.967507Z","iopub.execute_input":"2024-11-29T20:15:22.967935Z","iopub.status.idle":"2024-11-29T20:15:23.279212Z","shell.execute_reply.started":"2024-11-29T20:15:22.967901Z","shell.execute_reply":"2024-11-29T20:15:23.277809Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Function 1: Summarize Columns with rolling Mean\r\n\r\nThe `summarize_columns_rolling_mean` function computes the rolling mean for a set of columns in the `train` DataFrame based on a specified prefix and window size.\r\n\r\n1. **Logging Setup**:\r\n   - The logging configuration is set to display debug-level messages with timestamps and severity levels.\r\n\r\n2. **Function Definition**: `summarize_columns_rolling_mean(df, column_prefix, window_size=12)`\r\n   - **Parameters**:\r\n     - `df`: The input DataFrame containing the data.\r\n     - `column_prefix`: The prefix of the columns to include for summarization (e.g., `'bg'`).\r\n     - `window_size`: The number of columns to group together for calculating the rolling mean (default is 12).\r\n\r\n3. **Logging the Summarization Process**:\r\n   - The function logs the start of the summarization process, indicating which columns will be summarized using the rolling mean.\r\n\r\n4. **Identifying Columns to Summarize**:\r\n   - It identifies columns in the DataFrame that start with the specified `column_prefix`.\r\n\r\n5. **Computing the Rolling Mean**:\r\n   - The function processes columns in groups of size `window_size`.\r\n   - For each group of columns, the rolling mean is calculated along axis 1 (i.e., row-wise), using the `mean(axis=1)` function.\r\n   - The new column is named after the last column in the group (i.e., `cols_to_mean[-1]`).\r\n\r\n6. **Creating the Summarized DataFrame**:\r\n   - A new DataFrame (`summarized_df`) is created with the rolling mean values, and the columns that were processed are dropped from the original DataFrame.\r\n\r\n7. **Concatenating the Results**:\r\n   - The summarized DataFrame is concatenated to the original DataFrame, and the resulting DataFrame is returned.\r\n\r\n8. **Logging the Completion**:\r\n   - The function logs that the summarization is complete and the DataFrame has been updated.\r\n\r\n### Purpose\r\n\r\nThis function is useful for summarizing a set of related columns (e.g., sensor readings or time series data) by calculating a rolling mean over a specified window size, making it easier to detect trends and patterns in the data.\r\n\r\n### Example Output\r\n\r\nThe result of the function will be a DataFrame where the original columns (starting with `column_prefix`) have been replaced with new columns representing their rolling mean values, and any unnecessary columns have been dropped.\r\n","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport logging\n\n# Set up logging configuration\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef summarize_columns_rolling_mean(df, column_prefix, window_size=12):\n    \"\"\"\n    Summarizes columns by computing the rolling mean over specified intervals.\n    \n    Parameters:\n    - df: DataFrame containing the data.\n    - column_prefix: Prefix of the columns to summarize (e.g., 'bg').\n    - window_size: Number of columns to group together for mean calculation.\n    \n    Returns:\n    - DataFrame with summarized columns by rolling mean.\n    \"\"\"\n    logging.info(f\"Summarizing columns starting with {column_prefix} using rolling mean (window size: {window_size})\")\n    \n    # Find all columns starting with the specified prefix\n    columns = [col for col in df.columns if col.startswith(column_prefix)]\n    \n    new_column_data = {}\n    \n    for i in range(len(columns) // window_size):\n        cols_to_mean = columns[i * window_size:(i + 1) * window_size]\n        \n        mean_value = df[cols_to_mean].mean(axis=1)\n        new_column_name = f\"{cols_to_mean[-1]}\"\n        new_column_data[new_column_name] = mean_value\n    \n    summarized_df = pd.DataFrame(new_column_data)\n    logging.info(f\"Created summarized DataFrame with rolling mean columns\")\n    \n    df = df.drop(columns=columns, errors='ignore')\n    df = pd.concat([df, summarized_df], axis=1)\n    \n    logging.info(f\"Updated DataFrame after summarization of {column_prefix}\")\n    return df\n\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:29.840649Z","iopub.execute_input":"2024-11-29T20:15:29.841074Z","iopub.status.idle":"2024-11-29T20:15:29.849408Z","shell.execute_reply.started":"2024-11-29T20:15:29.841043Z","shell.execute_reply":"2024-11-29T20:15:29.848247Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Function 2: Summarize Columns with Sum\n\n\r\nThe `summarize_columns_sum` function computes the sum for a set of columns in the `train` DataFrame based on a specified prefix and window size.\r\n\r\n1. **Logging Setup**:\r\n   - The logging configuration is set to display debug-level messages, including timestamps and severity levels.\r\n\r\n2. **Function Definition**: `summarize_columns_sum(df, column_prefix, window_size=12)`\r\n   - **Parameters**:\r\n     - `df`: The input DataFrame containing the data.\r\n     - `column_prefix`: The prefix of the columns to include for summarization (e.g., `'insulin'`).\r\n     - `window_size`: The number of columns to group together for calculating the sum (default is 12).\r\n\r\n3. **Logging the Summarization Process**:\r\n   - The function logs the start of the summarization process, specifying which columns will be summarized using the sum.\r\n\r\n4. **Identifying Columns to Summarize**:\r\n   - It identifies columns in the DataFrame that start with the specified `column_prefix`.\r\n\r\n5. **Computing the Sum**:\r\n   - The function processes columns in groups of size `window_size`.\r\n   - For each group of columns, the sum is calculated row-wise (i.e., summing across columns for each row) using the `sum(axis=1)` function.\r\n   - The new column is named after the last column in the group (i.e., `cols_to_sum[-1]`).\r\n\r\n6. **Creating the Summarized DataFrame**:\r\n   - A new DataFrame (`summarized_df`) is created with the sum values, and the columns that were processed are dropped from the original DataFrame.\r\n\r\n7. **Concatenating the Results**:\r\n   - The summarized DataFrame is concatenated with the original DataFrame, and the resulting DataFrame is returned.\r\n\r\n8. **Logging the Completion**:\r\n   - The function logs that the summarization is complete and the DataFrame has been updated.\r\n\r\n### Purpose\r\n\r\nThis function is useful for summari columns (e.g., sensor readings or time-series data) by calculating their sum over a specified window size. This can help aggregate data over intervals, making it ea and the original columns are dropped.\r\n","metadata":{}},{"cell_type":"code","source":"def summarize_columns_sum(df, column_prefix, window_size=12):\n    \"\"\"\n    Summarizes columns by computing the sum over specified intervals.\n    \n    Parameters:\n    - df: DataFrame containing the data.\n    - column_prefix: Prefix of the columns to summarize (e.g., 'insulin').\n    - window_size: Number of columns to group together for sum calculation.\n    \n    Returns:\n    - DataFrame with summarized columns by sum.\n    \"\"\"\n    logging.info(f\"Summarizing columns starting with {column_prefix} using sum (window size: {window_size})\")\n    \n    columns = [col for col in df.columns if col.startswith(column_prefix)]\n    \n    new_column_data = {}\n    \n    for i in range(len(columns) // window_size):\n        cols_to_sum = columns[i * window_size:(i + 1) * window_size]\n        \n        sum_value = df[cols_to_sum].sum(axis=1)\n        new_column_name = f\"{cols_to_sum[-1]}\"\n        new_column_data[new_column_name] = sum_value\n    \n    summarized_df = pd.DataFrame(new_column_data)\n    logging.info(f\"Created summarized DataFrame with sum columns\")\n    \n    df = df.drop(columns=columns, errors='ignore')\n    df = pd.concat([df, summarized_df], axis=1)\n    \n    logging.info(f\"Updated DataFrame after summarization of {column_prefix}\")\n    return df\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:30.760158Z","iopub.execute_input":"2024-11-29T20:15:30.760503Z","iopub.status.idle":"2024-11-29T20:15:30.768282Z","shell.execute_reply.started":"2024-11-29T20:15:30.760475Z","shell.execute_reply":"2024-11-29T20:15:30.766957Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def summarize_all_columns(df):\n    logging.info(\"Starting summarization of all columns\")\n    \n    df = summarize_columns_rolling_mean(df, column_prefix='bg-', window_size=12)\n    df = summarize_columns_sum(df, column_prefix='insulin', window_size=12)\n    df = summarize_columns_sum(df, column_prefix='carbs', window_size=12)\n    df = summarize_columns_rolling_mean(df, column_prefix='hr', window_size=12)\n    df = summarize_columns_sum(df, column_prefix='steps', window_size=12)\n    df = summarize_columns_sum(df, column_prefix='cals', window_size=12)\n    \n    logging.info(\"Completed summarization of all columns\")\n    return df\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:32.072304Z","iopub.execute_input":"2024-11-29T20:15:32.073278Z","iopub.status.idle":"2024-11-29T20:15:32.079157Z","shell.execute_reply.started":"2024-11-29T20:15:32.073239Z","shell.execute_reply":"2024-11-29T20:15:32.078031Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ntrain_df = summarize_all_columns(train)\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:33.644019Z","iopub.execute_input":"2024-11-29T20:15:33.644410Z","iopub.status.idle":"2024-11-29T20:15:37.834874Z","shell.execute_reply.started":"2024-11-29T20:15:33.644376Z","shell.execute_reply":"2024-11-29T20:15:37.833775Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.info()","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:15:40.826214Z","iopub.execute_input":"2024-11-29T20:15:40.827272Z","iopub.status.idle":"2024-11-29T20:15:40.864027Z","shell.execute_reply.started":"2024-11-29T20:15:40.827233Z","shell.execute_reply":"2024-11-29T20:15:40.862607Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = summarize_all_columns(test)","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:16:02.694443Z","iopub.execute_input":"2024-11-29T20:16:02.694854Z","iopub.status.idle":"2024-11-29T20:16:02.838336Z","shell.execute_reply.started":"2024-11-29T20:16:02.694821Z","shell.execute_reply":"2024-11-29T20:16:02.837266Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.info()","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:16:03.198599Z","iopub.execute_input":"2024-11-29T20:16:03.198986Z","iopub.status.idle":"2024-11-29T20:16:03.214427Z","shell.execute_reply.started":"2024-11-29T20:16:03.198957Z","shell.execute_reply":"2024-11-29T20:16:03.213365Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:16:04.608777Z","iopub.execute_input":"2024-11-29T20:16:04.609137Z","iopub.status.idle":"2024-11-29T20:16:04.633902Z","shell.execute_reply.started":"2024-11-29T20:16:04.609109Z","shell.execute_reply":"2024-11-29T20:16:04.632922Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Data Preprocessing Summary\n\n### 1. Handling Missing Values for Different Columns\nThe preprocessing pipeline addresses missing values based on the type and characteristics of the columns, ensuring data consistency and logical integrity. Different methods are applied depending on the nature of the data and the assumptions about missing values.\n\n---\n\n### 2. Functionality Breakdown\n\n#### **For Blood Glucose (`bg-`) and Heart Rate (`hr`) Columns:**\n- **Method**: Missing values are filled using **linear interpolation**.\n- **Purpose**: \n  - Estimates missing values based on neighboring observations within a row.\n  - Ensures a smooth and consistent representation of trends, preserving logical continuity.\n  - Reflects the assumption that heart rate (`hr`) and blood glucose (`bg-`) remain within a realistic range and are relatively stable throughout the period, rather than dropping to zero.\n- **Implementation**:\n  - Interpolation is applied across rows (`axis=1`), meaning values are calculated horizontally for each individual data entry.\n  - This approach ensures the physiological data remains accurate and avoids abrupt or unrealistic drops to zero.\n\n---\n\n#### **For Insulin, Calories, Steps, and Carbs Columns (`insulin`, `cals`, `steps`, `carbs`):**\n- **Method**: Missing values are replaced with `0`.\n- **Purpose**:\n  - Reflects the assumption that:\n    - **Insulin**: Missing data indicates no insulin was administered during that period.\n    - **Calories**: Missing data indicates no calorie intake was recorded.\n    - **Steps**: Missing data indicates no steps were taken.\n    - **Carbs**: Missing data indicates no carbohydrate intake occurred.\n  - This approach avoids introducing artificial trends or patterns while maintaining logical consistency in activity or intake-related data.\n\n------------\n\n### Advantages of the Approach\n- **Realistic Assumptions**: Each column is handled in a way that reflects its nature:\n  - `bg-` and `hr`: Interpolated to maintain realistic and continuous physiological trends.\n  - `insulin`, `cals`, `steps`, and `carbs`: Filled with `0` to indicate inactivity or absence of measurements.\n- **Accuracy**: Interpolation ensures logical trends in physiological data, while `0` replacements simplify categorical and activity-related data.\n- **Consistency**: Ensures the dataset is complete and ready for downstream analysis or modeling.\n","metadata":{}},{"cell_type":"code","source":"# Define related column sets (bg_cols, insulin_cols, cals_cols, steps_cols, carbs_cols, hr_cols)\nbg_cols = [col for col in train_df.columns if col.startswith('bg-')]\nhr_cols = [col for col in train_df.columns if col.startswith('hr')]\n\ncarbs_cols = [col for col in test_df.columns if col.startswith('carbs')]\ninsulin_cols = [col for col in test_df.columns if col.startswith('insulin')]\nsteps_cols = [col for col in test_df.columns if col.startswith('steps')]\ncals_cols = [col for col in test_df.columns if col.startswith('cals')]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:19:11.197802Z","iopub.execute_input":"2024-11-29T20:19:11.198178Z","iopub.status.idle":"2024-11-29T20:19:11.204973Z","shell.execute_reply.started":"2024-11-29T20:19:11.198146Z","shell.execute_reply":"2024-11-29T20:19:11.203666Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Replace NaN with a placeholder string like 'Unknown' or any desired value\ntrain_df = train_df.drop('dominant_activity'.fillna('Unknown')\ntest_df['dominant_activity'] = test_df['dominant_activity'].fillna('Unknown')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:25:19.476948Z","iopub.execute_input":"2024-11-29T20:25:19.477319Z","iopub.status.idle":"2024-11-29T20:25:19.496451Z","shell.execute_reply.started":"2024-11-29T20:25:19.477285Z","shell.execute_reply":"2024-11-29T20:25:19.495338Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Combine all relevant columns\nfill_zero_cols = carbs_cols + insulin_cols + steps_cols + cals_cols\n\n# Fill missing values with 0 for these columns\ntrain_df[fill_zero_cols] = train_df[fill_zero_cols].fillna(0)\ntest_df[fill_zero_cols] = test_df[fill_zero_cols].fillna(0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:25:20.553957Z","iopub.execute_input":"2024-11-29T20:25:20.554627Z","iopub.status.idle":"2024-11-29T20:25:20.657954Z","shell.execute_reply.started":"2024-11-29T20:25:20.554582Z","shell.execute_reply":"2024-11-29T20:25:20.656860Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"time_series_cols = bg_cols + hr_cols\n\n\n\n# Step 1: Linear interpolation for missing values in bg_cols and hr_cols\ntrain_df[time_series_cols] = train_df[time_series_cols].interpolate(\n    method='linear', axis=1, limit_direction='both')\ntest_df[time_series_cols] = test_df[time_series_cols].interpolate(\n    method='linear', axis=1, limit_direction='both')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:25:21.492394Z","iopub.execute_input":"2024-11-29T20:25:21.493301Z","iopub.status.idle":"2024-11-29T20:25:23.431060Z","shell.execute_reply.started":"2024-11-29T20:25:21.493258Z","shell.execute_reply":"2024-11-29T20:25:23.430237Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Checking for Remaining Missing Values\r\n\r\nAfter applying the missing value imputation strategies, we verify if there are any remaining missing values in the `train_cleaned` and `test_cleaned` datasets.\r\n\r\n---\r#\n\r\n### **Purpose of the Check**\r\n#### **Objective**:\r\n- Ensure that all missing values have been effectively handled during the preprocessing steps.\r\n\r\n#### **Expected Result**:\r\n- Both outputs should print `False`, indicating that there are no missing values in the dates in test_cleaned\r\n","metadata":{}},{"cell_type":"code","source":"print(train_df.isnull().sum().any())\n\nprint(test_df.isnull().sum().any())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:25:23.432474Z","iopub.execute_input":"2024-11-29T20:25:23.432811Z","iopub.status.idle":"2024-11-29T20:25:23.466010Z","shell.execute_reply.started":"2024-11-29T20:25:23.432782Z","shell.execute_reply":"2024-11-29T20:25:23.464303Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Distribution Analysis and Skewness Transformation\r\n\r\n#### 1. **Initial Distribution Check**\r\n- **Objective**: Visualize the distribution of the target variable (`bg+1:00`) and calculate its skewness.\r\n- **Steps**:\r\n  - A histogram with kernel density estimation (KDE) was plotted.\r\n  - Skewness was calculated to assess the asymmetry of the distribution.#\r\n\r\n#### **Result**:\r\n- Initial skewne7ss: **1.0** (indicating a right-skewed distribution).\r#\n\r\n---\r\n\r\n### 2. **Log Transformation**\r\n- **Objective**: Reduce skewness and normalize the distribution.\r\n- **Steps**:\r\n  - Applied a `log1p` transformation (`log(1 + x)`) to the target variable.\r\n  - Plotted the transformed distribution and recalculat#ed skewness.\r\n\r\n#### **Result**:\r\n- Transformed skewness: **0.21** (indicating a nearly symmetrical dist#ribution).\r\n\r\n---\r\n\r\n### 3. **Why Transform?**\r\n- Reducing skewness improves the normality of data, which benefits many machine learning models that assume normally distributed inputs or outputs.\r\n","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\nfrom scipy.stats import skew \n\n# Plot histogram\nplt.figure(figsize=(8, 6))\nsns.histplot(train_df['bg+1:00'], kde=True, color='blue')\nplt.title('Distribution of Target Variable (y)')\nplt.xlabel('Target Variable (y)')\nplt.ylabel('Frequency')\nplt.show()\n\n# Calculate skewness\nskewness_value = skew(train_df['bg+1:00'])\nprint(f\"Skewness of Target Variable (y) before transformation: {skewness_value:.2f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:25:23.467752Z","iopub.execute_input":"2024-11-29T20:25:23.468257Z","iopub.status.idle":"2024-11-29T20:25:25.257936Z","shell.execute_reply.started":"2024-11-29T20:25:23.468200Z","shell.execute_reply":"2024-11-29T20:25:25.256922Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Log transformation\ntrain_df['bg+1:00'] = np.log1p(train_df['bg+1:00'])\n\n# Plot histogram of transformed target\nsns.histplot(train_df['bg+1:00'], kde=True, color='green')\nplt.title('Distribution of Log-Transformed Target Variable (y_log)')\nplt.show()\n\n# Check skewness after transformation\nlog_skewness_value = skew(train_df['bg+1:00'])\nprint(f\"Skewness after Log Transformation: {log_skewness_value:.2f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:25:29.170053Z","iopub.execute_input":"2024-11-29T20:25:29.171105Z","iopub.status.idle":"2024-11-29T20:25:30.361393Z","shell.execute_reply.started":"2024-11-29T20:25:29.171065Z","shell.execute_reply":"2024-11-29T20:25:30.360373Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Checking for Missing Values in Train and Test DataFrames\r\n\r\n---\r\n\r\n### **Purpose**\r\n- Verify the presence of missing values in both the training and test datasets before proceeding with model training.\r\n- Ensure data quality, as missing values can negatively impact model performance and lead to biased results.{test_missing}\")\r\n","metadata":{}},{"cell_type":"code","source":"# Check for missing values in train_filtered\nmissing_train = train_df.isnull().sum()\nprint(\"Missing values in train:\")\nprint(missing_train[missing_train > 0])\n\n# Check for missing values in test_df\nmissing_test = test_df.isnull().sum()\nprint(\"Missing values in test_df:\")\nprint(missing_test[missing_test > 0])\n\n# Summary\nif missing_train.sum() == 0 and missing_test.sum() == 0:\n    print(\"Both datasets are complete: No missing values.\")\nelse:\n    print(\"Missing values found. Please address them.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:27:06.115867Z","iopub.execute_input":"2024-11-29T20:27:06.116286Z","iopub.status.idle":"2024-11-29T20:27:06.150937Z","shell.execute_reply.started":"2024-11-29T20:27:06.116254Z","shell.execute_reply":"2024-11-29T20:27:06.149638Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Splitting Data into Features and Targetirget:**\r\n\r\n- **`X`**: The feature matrix created by dropping the target column (`bg+1:00`) and the participant number column (`p_num`) from the DataFrame.\r\n- **`y`**: The target vector, which contains the values from the `bg+1:00` column.\r\n\r\n---\r\n\r\n#### **Splitting the Data into Training and Validation Sets:**\r\n\r\n- The dataset is split into training and validation sets using `train_test_split` from `sklearn.model_selection`.\r\n- The `test_size=0.2` argument indicates that **20%** of the data will be used for validation, while the remaining **80%** will be used for training.\r\n- `random_state=42` ensures reproducibit_size=0.2, random_state=42)\r\n","metadata":{}},{"cell_type":"code","source":"target_column = 'bg+1:00'  \nX = train_df.drop(columns=[target_column, 'p_num'])\ny = train_df[target_column]\n\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:27:11.482207Z","iopub.execute_input":"2024-11-29T20:27:11.483354Z","iopub.status.idle":"2024-11-29T20:27:11.607096Z","shell.execute_reply.started":"2024-11-29T20:27:11.483301Z","shell.execute_reply":"2024-11-29T20:27:11.606159Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:27:12.543689Z","iopub.execute_input":"2024-11-29T20:27:12.544477Z","iopub.status.idle":"2024-11-29T20:27:12.552894Z","shell.execute_reply.started":"2024-11-29T20:27:12.544440Z","shell.execute_reply":"2024-11-29T20:27:12.551775Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Preprocessing Numeric and Categorical Features\r\n\r\n#### 1. **Feature Identification**\r\n- **Numeric Features**: Identified columns with numeric data types (`int64`, `int32`, `float64`).\r\n- **Categorical Features**: Identified columns with object/string data type#### **2. Preprocessing Steps**\n##### **For Numeric Features**:\n- Applied `RobustScaler` to scale numeric columns.\n- Scales data by removing the **median** and scaling using the **interquartile range**, making it robust to outliers.\n\n##### **For Categorical Features**:\n- Applied `OrdinalEncoder` to encode categorical columns into numeric format.\n\n---\n\n#### **3. ColumnTransformer**\n- Combined numeric and categorical transformations using `ColumnTransformer` for streamlined preprocessing.\n\n---\n\n#### **4. Fit and Transform**\n- **Training Data**: \n  - `preprocessor.fit_transform(X_train)` applies transformations to the training data.\n- **Validation Data**: \n  - `preprocessor.transform(X_test)` applies the same transformations to the validation data.\n\n---\n\n#### **Why This Approach?**\n- Handles numeric and categorical features efficiently in a single pipeline.\n- Scales numeric features while preserving the robustness against outliers.\n- Encodes categorical features for compatibility with machine learning models.l_features)\r\n","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import OrdinalEncoder, RobustScaler\nfrom sklearn.compose import ColumnTransformer\n\n# Identify numeric columns in training data\nnumeric_features = X.select_dtypes(include=['int64', 'int32', 'float64']).columns.tolist()\n\n# Identify categorical columns in training data\ncategorical_features = X.select_dtypes(include=['object']).columns.tolist()\n\n# Display numeric and categorical columns\nprint(\"Numeric Columns:\", numeric_features)\nprint(\"Categorical Columns:\", categorical_features)\n\n# Apply the scaler to the numeric columns and ordinal encoding to categorical columns\nnumeric_transformer = RobustScaler()\ncategorical_transformer = OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1)\n\n# Combine both transformers into a ColumnTransformer\npreprocessor = ColumnTransformer(\n    transformers=[\n        ('num', numeric_transformer, numeric_features),  # Apply RobustScaler to numeric columns\n        ('cat', categorical_transformer, categorical_features)  # Apply OrdinalEncoder to categorical columns\n    ]\n)\n\n# Fit and transform the training data\nX_train_processed = preprocessor.fit_transform(X_train)\n\n# Transform the test data using the fitted preprocessor\nX_test_processed = preprocessor.transform(X_test)  # Works without issues for unseen categories\n\n# Verify processed data\nprint(X_train_processed)\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T21:48:28.039229Z","iopub.execute_input":"2024-11-29T21:48:28.039690Z","iopub.status.idle":"2024-11-29T21:48:28.481920Z","shell.execute_reply.started":"2024-11-29T21:48:28.039653Z","shell.execute_reply":"2024-11-29T21:48:28.481082Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Shapes: {X_train_processed.shape}, {y_train.shape}\")\nprint(f\"Missing values in X: {np.isnan(X_train_processed).sum()}\")\nprint(f\"Missing values in y: {np.isnan(y_train).sum()}\")\n","metadata":{"execution":{"iopub.status.busy":"2024-11-29T20:34:31.161723Z","iopub.execute_input":"2024-11-29T20:34:31.162116Z","iopub.status.idle":"2024-11-29T20:34:31.176644Z","shell.execute_reply.started":"2024-11-29T20:34:31.162084Z","shell.execute_reply":"2024-11-29T20:34:31.175500Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training Ensemble Models (XGBoost, LightGBM, RandomForest)\n\nThis section demonstrates the training process of three popular machine learning models: **XGBoost**, **LightGBM**, and **RandomForest**. These models are trained using **5-fold cross-validation** to evaluate their performance and identify the best-performing model for each algorithm.\n\n### 1. **XGBoost (XGB)**\n\n**XGBoost** is a powerful gradient boosting algorithm that excels in both classification and regression tasks. In this step, we train the XGBoost model using the training data and validate it on each fold of the cross-validation process.\n\n- **Evaluation Metric**: We use **RMSE (Root Mean Squared Error)**, **MAE (Mean Absolute Error)**, and **R² (R-squared)** to evaluate the model's performance.\n- **Training Process**: For each fold, we fit the model on the training set, predict on the validation set, and calculate the performance metrics.\n- **Model Saving**:After training on each fold, the XGBoost model is saved as a `.pkl` file for future use.\n\n--------\n### 2. **LightGBM (LGB)**\r\n\r\n**LightGBM** is a gradient boosting framework that is optimized for speed and efficiency, especially when working with large datasets. It is trained using a **5-fold cross-validation** process, similar to XGBoost.\r\n\r\n- **Evaluation Metric**: We use **RMSE (Root Mean Squared Error)**, **MAE (Mean Absolute Error)**, and **R² (R-squared)** to evaluate the model's performance.\r\n- **Training Process**: The model is trained on the training set in each fold, and its performance is evaluated using the validation set.\r\n- **Model Saving**: After each fold, the trained model is saved for later use, similar to how the XGBoost model is handled.\r\n##\r\n---\r\n\r\n# 3. **RandomForest (RF)**\r\n\r\n**RandomForest** is an ensemble learning method that builds multiple decision trees and combines them to enhance accuracy and prevent overfitting. This model is trained using the same **5-fold cross-validation** process as XGBoost and LightGBM.\r\n\r\n- **Evaluation Metric**: The same performance metrics (**RMSE**, **MAE**, and **R²**) are used to evaluate the model's performance.\r\n- **Training Process**: The RandomForest model is trained on the training data for each fold, and its performance is evaluated using the validation set.\r\n- **Model Saving**: After training, the RandomForest model is saved after each fold to ensure it can be used later for predictions or further ##analysis.\r\n\r\n---\r\n\r\n# 4. **Model Performance Evaluation**\r\n\r\nAfter training each of the three models (XGBoost, LightGBM, RandomForest), we evaluate their performance using the following metrics:\r\n\r\n- **RMSE (Root Mean Squared Error)**: Measures the average magnitude of the errors in predictions.\r\n- **MAE (Mean Absolute Error)**: Measures the average absolute error between predicted and actual values.\r\n- **R² (R-squared)**: Indicates how well the model explains the variance in the target variable.\r\n\r\nWe track these metrics for each model and each fold, storing the best-performing mode##l for each algorithm.\r\n\r\n---\r\n\r\n# 5. **Model Saving**\r\n\r\nAfter training and evaluating each model, the best models are saved based on their RMSE scores. These models are serialized using **pickle** and saved as `.pkl` files for future use ini### Conclusion\r\n\r\nThis process enables the training, evaluation, and saving of three different models—**XGBoost**, **LightGBM**, and **RandomForest**—using a **5-fold cross-validation** approa totalling 15 models.h. The performance of each model is closely monitorede.\r\nle:\r\n    pickle.dump(best_model, file)\r\n","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\nimport numpy as np\nimport xgboost as xgb\nimport lightgbm as lgb\nfrom sklearn.ensemble import RandomForestRegressor\nfrom catboost import CatBoostRegressor\nimport pickle\n# Set up K-Fold Cross Validation\n\nkf = KFold(n_splits=5, shuffle=True)\n\n# Initialize lists to store metrics for each fold\nrmse_scores = {'XGBoost': [], 'LightGBM': [], 'RandomForest': []}\nmae_scores = {'XGBoost': [], 'LightGBM': [], 'RandomForest': []}\nr2_scores = {'XGBoost': [], 'LightGBM': [], 'RandomForest': []}\nall_residuals = []\n\n# Initialize lists to store predictions from all models for ensemble calculation\nensemble_predictions = []\n\n# Initialize variable to store the best model\nbest_model_dict = {'XGBoost': None, 'LightGBM': None, 'RandomForest': None, 'CatBoost': None}\nbest_rmse_dict = {'XGBoost': float('inf'), 'LightGBM': float('inf'), 'RandomForest': float('inf')}\n\n# Initialize models\nmodels = {\n    'XGBoost': xgb.XGBRegressor(tree_method='hist', objective='reg:squarederror', n_estimators=3000),\n    'LightGBM': lgb.LGBMRegressor(n_estimators=3000, verbose=-1),\n    'RandomForest': RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)\n}\n\n# Training Loop with K-Fold Cross-Validation\nfold = 1\nplt.figure(figsize=(10, 6))\n\n# Perform k-fold cross-validation\nfor train_index, val_index in kf.split(X_train_processed):\n    # Split data into train and validation sets for the current fold\n    X_train_fold, X_val_fold = X_train_processed[train_index], X_train_processed[val_index]\n    y_train_fold, y_val_fold = y_train.iloc[train_index], y_train.iloc[val_index]\n\n    # Loop through all models\n    for name, model in models.items():\n        print(f\"Training {name} on Fold {fold}...\")\n        \n        if name == 'XGBoost':\n            # Create eval set for XGBoost\n            evals = [(X_train_fold, y_train_fold), (X_val_fold, y_val_fold)]\n            model.fit(X_train_fold, y_train_fold, eval_metric=\"rmse\")\n        else:\n            # Train the model on the current fold’s data (other models)\n            model.fit(X_train_fold, y_train_fold)\n\n        # Predictions\n        y_pred_log = model.predict(X_val_fold)\n        y_pred = np.expm1(y_pred_log)  # Reverse log1p for predictions\n        y_val_actual = np.expm1(y_val_fold)  # Reverse log1p for the actual values\n        \n        # Calculate metrics\n        rmse = np.sqrt(mean_squared_error(y_val_actual, y_pred))\n        mae = mean_absolute_error(y_val_actual, y_pred)\n        r2 = r2_score(y_val_actual, y_pred)\n        \n        # Calculate residuals\n        residuals = y_val_actual - y_pred\n        all_residuals.extend(residuals)\n\n        # Store metrics\n        rmse_scores[name].append(rmse)\n        mae_scores[name].append(mae)\n        r2_scores[name].append(r2)\n        \n        # Track the best model based on RMSE\n        if rmse < best_rmse_dict[name]:\n            best_rmse_dict[name] = rmse\n            best_model_dict[name] = model  # Save the best model\n\n        # Print model metrics for the current fold\n        print(f\"{name} - Fold {fold} - RMSE: {rmse:.4f}, MAE: {mae:.4f}, R²: {r2:.4f}\")\n\n        \n        # Save the model for the current fold\n        with open(f\"{name}_model_fold{fold}.pkl\", \"wb\") as file:\n            pickle.dump(model, file)\n        print(f\"Saved {name} model for Fold {fold}.\")\n    \n\n    fold += 1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T20:35:53.755759Z","iopub.execute_input":"2024-11-29T20:35:53.756766Z","iopub.status.idle":"2024-11-29T21:21:46.193407Z","shell.execute_reply.started":"2024-11-29T20:35:53.756688Z","shell.execute_reply":"2024-11-29T21:21:46.191779Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pickle\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\n\nmodel_names = ['XGBoost', 'LightGBM', 'RandomForest'] \nnum_folds = 5  \n\n# Initialize lists to store metrics for each fold\nrmse_scores = []\nmae_scores = []\nr2_scores = []\nall_residuals = []  \n\n# Loop through each fold\nfor fold in range(1, num_folds + 1):\n    print(f\"Evaluating Ensemble for Fold {fold}...\")\n    \n    # Initialize a list to store predictions for the current fold\n    fold_predictions = []\n    \n    # Load models for the current fold and make predictions\n    for model_name in model_names:\n        model_file = f'/kaggle/working/{model_name}_model_fold{fold}.pkl'\n        \n        # Load the model for the current fold\n        with open(model_file, 'rb') as f:\n            model = pickle.load(f)\n        \n        # Predict using the model for this fold \n        y_pred_log = model.predict(X_test_processed)  \n        y_pred = np.expm1(y_pred_log) \n        \n        fold_predictions.append(y_pred)\n    \n    # Ensemble the predictions (taking the average across models)\n    ensemble_predictions = np.mean(fold_predictions, axis=0)\n\n    # Reverse log1p transformation for actual values if applicable\n    y_val_actual = np.expm1(y_test)  # Reverse log1p for actual values\n\n    # Calculate metrics for the ensemble\n    rmse = np.sqrt(mean_squared_error(y_val_actual, ensemble_predictions))\n    mae = mean_absolute_error(y_val_actual, ensemble_predictions)\n    r2 = r2_score(y_val_actual, ensemble_predictions)\n\n    # Store metrics for the fold\n    rmse_scores.append(rmse)\n    mae_scores.append(mae)\n    r2_scores.append(r2)\n\n     #Calculate residuals (errors) for the fold and store them\n    residuals = y_val_actual - ensemble_predictions\n    all_residuals.extend(residuals)\n\n    # Print metrics for the fold\n    print(f\"Fold {fold} - RMSE: {rmse:.4f}, MAE: {mae:.4f}, R²: {r2:.4f}\")\n\n# Calculate average metrics across all folds\navg_rmse = np.mean(rmse_scores)\navg_mae = np.mean(mae_scores)\navg_r2 = np.mean(r2_scores)\n\n# Print the average ensemble metrics across all folds\nprint(f\"Average Ensemble Metrics Across Folds - RMSE: {avg_rmse:.4f}, MAE: {avg_mae:.4f}, R²: {avg_r2:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T21:39:30.613519Z","iopub.execute_input":"2024-11-29T21:39:30.613958Z","iopub.status.idle":"2024-11-29T21:40:39.904814Z","shell.execute_reply.started":"2024-11-29T21:39:30.613925Z","shell.execute_reply":"2024-11-29T21:40:39.903679Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport scipy.stats as stats\n\n# Plot RMSE across all folds\nplt.figure(figsize=(6, 4))\nplt.plot(range(1, num_folds + 1), rmse_scores, marker='o', label='RMSE', color='blue')\nplt.title(\"RMSE across Folds\")\nplt.xlabel(\"Fold\")\nplt.ylabel(\"RMSE\")\nplt.xticks(range(1, num_folds + 1))\nplt.legend()\nplt.grid(True)\nplt.show()\n\n# Plot R² across all folds\nplt.figure(figsize=(6, 4))\nplt.plot(range(1, num_folds + 1), r2_scores, marker='o', label='R²', color='green')\nplt.title(\"R² across Folds\")\nplt.xlabel(\"Fold\")\nplt.ylabel(\"R²\")\nplt.xticks(range(1, num_folds + 1))\nplt.legend()\nplt.grid(True)\nplt.show()\n\n# Optionally, plot combined residuals across all folds\nplt.figure(figsize=(6, 4))\nplt.scatter(range(len(all_residuals)), all_residuals, alpha=0.5)\nplt.axhline(0, color='red', linestyle='--')\nplt.title(\"Combined Residuals Plot Across All Folds\")\nplt.xlabel(\"Sample Index\")\nplt.ylabel(\"Residuals\")\nplt.show()\n\n# QQ plot for combined residuals across all folds\nplt.figure(figsize=(6, 4))\nstats.probplot(all_residuals, dist=\"norm\", plot=plt)\nplt.title(\"QQ Plot of Residuals Across All Folds\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T21:40:59.426301Z","iopub.execute_input":"2024-11-29T21:40:59.426730Z","iopub.status.idle":"2024-11-29T21:41:02.372498Z","shell.execute_reply.started":"2024-11-29T21:40:59.426674Z","shell.execute_reply":"2024-11-29T21:41:02.371680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\n\n# Assuming y_val_actual and ensemble_predictions are already available\n# Calculate absolute error between actual and predicted glucose levels\nabsolute_error = np.abs(y_val_actual.values - ensemble_predictions)\n\n# Define a threshold for highlighting large errors (adjust as necessary)\nerror_threshold = np.percentile(absolute_error, 90)  # Highlight the top 10% largest errors\n\n# Create a mask for where the error is above the threshold\nhighlight_mask = absolute_error > error_threshold\n\n# Plotting the Actual and Predicted Glucose Levels\nplt.figure(figsize=(12, 6))\n\n# Plot Actual Glucose Levels\nplt.plot(y_val_actual.values, label='Actual Glucose Levels', color='blue', linestyle='-', linewidth=1)\n\n# Plot Predicted Glucose Levels\nplt.plot(ensemble_predictions, label='Predicted Glucose Levels', color='green', linestyle='--', linewidth=2)\n\n# Highlight the regions where the error is large\nplt.scatter(np.where(highlight_mask)[0], ensemble_predictions[highlight_mask], color='red', alpha=0.5, label='High Error Regions')\n\n# Labels and title\nplt.xlabel('Samples')\nplt.ylabel('Glucose Level')\nplt.title('Predicted vs Actual Glucose Levels with Highlighted Errors')\n\n# Displaying legend and grid\nplt.legend()\nplt.grid(alpha=0.3)\n\n# Show the plot\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T21:45:28.640242Z","iopub.execute_input":"2024-11-29T21:45:28.641023Z","iopub.status.idle":"2024-11-29T21:45:29.914845Z","shell.execute_reply.started":"2024-11-29T21:45:28.640983Z","shell.execute_reply":"2024-11-29T21:45:29.913907Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## interference\n","metadata":{}},{"cell_type":"code","source":"# Identify numeric columns\ntest_numeric_columns = test_df.select_dtypes(include=['int64', 'int32', 'float64']).columns.tolist()\n\n# Identify categorical columns\ntest_categorical_columns = test_df.select_dtypes(include=['object']).columns.tolist()\n\n# Display the results\nprint(\"Numeric Columns:\", test_numeric_columns)\nprint(\"Categorical Columns:\", test_categorical_columns)\ntest_processed = preprocessor.transform(test_df)","metadata":{"execution":{"iopub.status.busy":"2024-11-29T21:48:38.113962Z","iopub.execute_input":"2024-11-29T21:48:38.114365Z","iopub.status.idle":"2024-11-29T21:48:38.137638Z","shell.execute_reply.started":"2024-11-29T21:48:38.114330Z","shell.execute_reply":"2024-11-29T21:48:38.136567Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pickle\nimport pandas as pd\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\n\nmodel_names = ['XGBoost', 'LightGBM', 'RandomForest'] \nnum_folds = 5  # Number of folds (you can adjust this depending on your setup)\n\n\n# Initialize list to store ensemble predictions for each fold\nensemble_predictions_all_folds = []\n\n# Loop through each fold\nfor fold in range(1, num_folds + 1):\n    print(f\"Making Predictions Ensemble for Fold {fold}...\")\n    \n    # Initialize a list to store individual model predictions for this fold\n    fold_predictions = []\n    \n    # Loop over each model to make predictions for this fold\n    for model_name in model_names:\n        model_file = f'/kaggle/working/{model_name}_model_fold{fold}.pkl'  # Path to the model file\n        \n        # Load the model for the current fold\n        with open(model_file, 'rb') as f:\n            model = pickle.load(f)\n        \n        # Predict using the model for this fold\n        y_pred_log = model.predict(test_processed)  # test_df is your test dataset\n        \n        # Reverse the log1p transformation\n        y_pred = np.expm1(y_pred_log)  # Apply expm1 to reverse log1p transformation\n        \n        fold_predictions.append(y_pred)\n    \n    # Ensemble the predictions (taking the average across models for this fold)\n    fold_ensemble_predictions = np.mean(fold_predictions, axis=0)\n    \n    # Store the ensemble predictions for this fold\n    ensemble_predictions_all_folds.append(fold_ensemble_predictions)\n\n# Combine all fold ensemble predictions by averaging them\nfinal_ensemble_predictions = np.mean(ensemble_predictions_all_folds, axis=0)\n\n# Prepare the submission DataFrame\n# Assuming 'id' column exists in test_df to uniquely identify each sample\nsubmission_df = pd.DataFrame({\n    'id': test_df['id'],  # Replace 'id' with the actual column name if different\n    'bg+1:00': final_ensemble_predictions  # Replace 'bg+1:00' with the desired output column name\n})\n\n# Display the first few rows of the submission DataFrame\nprint(submission_df.head())\n\n# Save the final predictions to a CSV file\nsubmission_df.to_csv('submission.csv', index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-29T21:57:06.992316Z","iopub.execute_input":"2024-11-29T21:57:06.992872Z","iopub.status.idle":"2024-11-29T21:57:18.283460Z","shell.execute_reply.started":"2024-11-29T21:57:06.992804Z","shell.execute_reply":"2024-11-29T21:57:18.282500Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null}]}