{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":53666,"databundleVersionId":6589269,"sourceType":"competition"},{"sourceId":6507308,"sourceType":"datasetVersion","datasetId":3706667}],"dockerImageVersionId":30558,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np  # numerical operations\nimport pandas as pd  # data manipulation\nfrom itertools import groupby  # grouping operations\nimport gc  # gc (garbage collector) for memory management\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-28T07:23:15.038865Z","iopub.execute_input":"2023-11-28T07:23:15.039287Z","iopub.status.idle":"2023-11-28T07:23:15.486018Z","shell.execute_reply.started":"2023-11-28T07:23:15.039255Z","shell.execute_reply":"2023-11-28T07:23:15.484446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Zzzs_train.parquet is a lightweight training dataset + binary target (awake). It consists of 35 series selected from the original 277 series. This dataset was created using the notebook.\nThe dataset Zzzs_train_multi.parquet also has an extra 8 non_wear series assigned the awake=2 class.","metadata":{}},{"cell_type":"code","source":"# Load dataset for training (multiclass data) and testing\n\ntrain = pd.read_parquet(\"/kaggle/input/zzzs-lightweight-training-dataset-target/Zzzs_train_multi.parquet\")\ntest = pd.read_parquet(\"/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet\")\n","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:23:17.798086Z","iopub.execute_input":"2023-11-28T07:23:17.799746Z","iopub.status.idle":"2023-11-28T07:23:29.347067Z","shell.execute_reply.started":"2023-11-28T07:23:17.799687Z","shell.execute_reply":"2023-11-28T07:23:29.345400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Feature engineering","metadata":{}},{"cell_type":"code","source":"# Iterate over 'train' and 'test' DataFrames to perform data preprocessing and feature engineering\n\nfor df in (train, test):\n    # parse the 'timestamp' column to remove time zone information and extract the 'hour' feature\n    df['timestamp'] = pd.to_datetime(df['timestamp']).apply(lambda t: t.tz_localize(None))\n    df[\"hour\"] = df[\"timestamp\"].dt.hour\n\n    # Define the number of periods for rolling calculations\n    periods = 20\n    \n    # Calculate the differences and rolling statistics(mean, max, std) for 'anglez' and 'enmo' using grouping by 'series_id' for the differences.\n    df[\"anglez_diff\"] = df.groupby('series_id')['anglez'].diff(periods=periods).fillna(method=\"bfill\").astype('float16')\n    df[\"enmo_diff\"] = df.groupby('series_id')['enmo'].diff(periods=periods).fillna(method=\"bfill\").astype('float16')\n    df[\"anglez_rolling_mean\"] = df[\"anglez\"].rolling(periods, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"enmo_rolling_mean\"] = df[\"enmo\"].rolling(periods, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"anglez_rolling_max\"] = df[\"anglez\"].rolling(periods, center=True).max().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"enmo_rolling_max\"] = df[\"enmo\"].rolling(periods, center=True).max().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"anglez_rolling_std\"] = df[\"anglez\"].rolling(periods, center=True).std().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"enmo_rolling_std\"] = df[\"enmo\"].rolling(periods, center=True).std().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"anglez_diff_rolling_mean\"] = df[\"anglez_diff\"].rolling(periods, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"enmo_diff_rolling_mean\"] = df[\"enmo_diff\"].rolling(periods, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"anglez_diff_rolling_max\"] = df[\"anglez_diff\"].rolling(periods, center=True).max().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n    df[\"enmo_diff_rolling_max\"] = df[\"enmo_diff\"].rolling(periods, center=True).max().fillna(method=\"bfill\").fillna(method=\"ffill\").astype('float16')\n\n# Define a list of selected features\nfeatures = [\n    \"hour\",\n    \"anglez\",\n    \"anglez_diff\",\n    \"anglez_rolling_mean\",\n    \"anglez_rolling_max\",\n    \"anglez_rolling_std\",\n    \"anglez_diff_rolling_mean\",\n    \"anglez_diff_rolling_max\",\n    \"enmo\",\n    \"enmo_diff\",\n    \"enmo_rolling_mean\",\n    \"enmo_rolling_max\",\n    \"enmo_rolling_std\",\n    \"enmo_diff_rolling_mean\",\n    \"enmo_diff_rolling_max\",\n]","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:30:10.144464Z","iopub.execute_input":"2023-11-28T07:30:10.144916Z","iopub.status.idle":"2023-11-28T07:32:48.817629Z","shell.execute_reply.started":"2023-11-28T07:30:10.144881Z","shell.execute_reply":"2023-11-28T07:32:48.816097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:32:48.819461Z","iopub.execute_input":"2023-11-28T07:32:48.820245Z","iopub.status.idle":"2023-11-28T07:32:48.843632Z","shell.execute_reply.started":"2023-11-28T07:32:48.820211Z","shell.execute_reply":"2023-11-28T07:32:48.842131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(test)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:55:08.525301Z","iopub.execute_input":"2023-11-28T07:55:08.526116Z","iopub.status.idle":"2023-11-28T07:55:08.551993Z","shell.execute_reply.started":"2023-11-28T07:55:08.526073Z","shell.execute_reply":"2023-11-28T07:55:08.551015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"best_model = compare_models()","metadata":{"execution":{"iopub.status.busy":"2023-11-28T08:12:47.861803Z","iopub.status.idle":"2023-11-28T08:12:47.862296Z","shell.execute_reply.started":"2023-11-28T08:12:47.862061Z","shell.execute_reply":"2023-11-28T08:12:47.862084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Select features for training data and target variable\nX_train = train[features]  # Features for training data\ny_train = train[\"awake\"]  # Target variable\n\n# Delete the 'train' DataFrame to save memory\ndel train\ngc.collect()  # Trigger garbage collection to release memory","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:32:48.846658Z","iopub.execute_input":"2023-11-28T07:32:48.847119Z","iopub.status.idle":"2023-11-28T07:32:51.212156Z","shell.execute_reply.started":"2023-11-28T07:32:48.847089Z","shell.execute_reply":"2023-11-28T07:32:51.210599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n# Measure the execution time of the following code block\n\nfrom sklearn.ensemble import RandomForestClassifier\n\n# Initialize the RandomForestClassifier with specified hyperparameters\nclassifier = RandomForestClassifier(n_estimators=100,\n                                    max_depth=6,\n                                    min_samples_leaf=150,\n                                    random_state=42,\n                                    n_jobs=-1)\n\n#Fit the classifier to the training data\nclassifier.fit(X_train, y_train)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:32:51.213968Z","iopub.execute_input":"2023-11-28T07:32:51.214445Z","iopub.status.idle":"2023-11-28T07:55:08.211926Z","shell.execute_reply.started":"2023-11-28T07:32:51.214405Z","shell.execute_reply":"2023-11-28T07:55:08.210137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Delete the 'X_train' and 'y_train' DataFrames to save memory\ndel X_train, y_train\ngc.collect()  # Trigger garbage collection to release memory","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:55:08.213736Z","iopub.execute_input":"2023-11-28T07:55:08.214213Z","iopub.status.idle":"2023-11-28T07:55:08.315858Z","shell.execute_reply.started":"2023-11-28T07:55:08.214155Z","shell.execute_reply":"2023-11-28T07:55:08.314537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Select features for the test data\nX_test = test[features]\n\n# Predict probabilities for the \"not_awake\" and \"awake\" classes using the trained classifier\ntest[\"not_awake\"] = classifier.predict_proba(X_test)[:, 0]  # Probability of not being awake\ntest[\"awake\"] = classifier.predict_proba(X_test)[:, 1]      # Probability of being awake","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:55:08.317487Z","iopub.execute_input":"2023-11-28T07:55:08.317961Z","iopub.status.idle":"2023-11-28T07:55:08.433371Z","shell.execute_reply.started":"2023-11-28T07:55:08.317923Z","shell.execute_reply":"2023-11-28T07:55:08.431809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Apply smoothing to the predictions\nsmoothing_length = 2 * 230\n\n# Calculate the smoothed scores for being \"awake\" and \"not_awake\"\ntest[\"score\"] = test[\"awake\"].rolling(smoothing_length, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\ntest[\"smooth\"] = test[\"not_awake\"].rolling(smoothing_length, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n\n# Re-binarize the \"smooth\" column by rounding to the nearest integer\ntest[\"smooth\"] = test[\"smooth\"].round()\n\n# Define a function to extract events based on smoothing results\ndef get_event(df):\n    lstCV = zip(df.series_id, df.smooth)\n    lstPOI = []\n    for (c, v), g in groupby(lstCV, lambda cv: \n                            (cv[0], cv[1] != 0 and not pd.isnull(cv[1]))):\n        llg = sum(1 for item in g)\n        if v is False: \n            lstPOI.extend([0] * llg)\n        else: \n            lstPOI.extend(['onset'] + (llg - 2) * [0] + ['wakeup'] if llg > 1 else [0])\n    return lstPOI\n\n# Apply the function to generate the \"event\" column\ntest[\"event\"] = get_event(test)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:55:08.434931Z","iopub.execute_input":"2023-11-28T07:55:08.436667Z","iopub.status.idle":"2023-11-28T07:55:08.454943Z","shell.execute_reply.started":"2023-11-28T07:55:08.436626Z","shell.execute_reply":"2023-11-28T07:55:08.452950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a sample_submission DataFrame\nsample_submission = test.loc[test[\"event\"] != 0][[\"series_id\", \"step\", \"event\", \"score\"]].copy().reset_index(drop=True).reset_index(names=\"row_id\")\n\n# Save the sample_submission DataFrame to a CSV file named 'submission.csv'\nsample_submission.to_csv('submission.csv', index=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-28T07:55:08.507465Z","iopub.execute_input":"2023-11-28T07:55:08.508220Z","iopub.status.idle":"2023-11-28T07:55:08.523269Z","shell.execute_reply.started":"2023-11-28T07:55:08.508179Z","shell.execute_reply":"2023-11-28T07:55:08.521862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}