{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# ML exploration","metadata":{}},{"cell_type":"markdown","source":"#inspired by https://www.kaggle.com/code/zulqarnainali/explained-baseline-solution","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport polars as pl\nimport datetime \nfrom tqdm import tqdm\nimport seaborn as sns\nfrom joblib import Parallel, delayed\nimport plotly.express as px\nfrom plotly.subplots import make_subplots\nimport plotly.graph_objects as go\nimport gc\nfrom metric import score # Import event detection ap score function\n\n# These are variables to be used by the score function\ncolumn_names = {\n    'series_id_column_name': 'series_id',\n    'time_column_name': 'step',\n    'event_column_name': 'event',\n    'score_column_name': 'score',\n}\n\ntolerances = {\n    'onset': [12, 36, 60, 90, 120, 150, 180, 240, 300, 360], \n    'wakeup': [12, 36, 60, 90, 120, 150, 180, 240, 300, 360]\n}\n\npd.set_option('display.max_columns', None)\n\nimport warnings\nwarnings.filterwarnings(\"ignore\", category=UserWarning)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-11-03T06:38:33.545270Z","iopub.execute_input":"2023-11-03T06:38:33.546598Z","iopub.status.idle":"2023-11-03T06:38:33.556826Z","shell.execute_reply.started":"2023-11-03T06:38:33.546540Z","shell.execute_reply":"2023-11-03T06:38:33.555483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Importing data","metadata":{}},{"cell_type":"code","source":"# Importing data \n\n# Column transformations\n\ndt_transforms = [\n      pl.col('timestamp').str.to_datetime(), \n    (pl.col('timestamp').str.to_datetime().dt.date()).alias('date'), \n    pl.col('timestamp').str.to_datetime().dt.time().alias('time')\n    ]\n\ntrain_series = (pl.scan_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/train_series.parquet')\n                .with_columns(\n    (dt_transforms)\n    )\n                .collect()\n                .to_pandas()\n               )\n\ntrain_events = (pl.scan_csv('/kaggle/input/child-mind-institute-detect-sleep-states/train_events.csv')\n                .with_columns(\n                    (dt_transforms)\n                    )\n                .collect()\n                .to_pandas()\n               )\n\ntest_series = (pl.scan_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet')\n                .with_columns(\n                    (dt_transforms)\n                    )\n                .collect()\n                .to_pandas()\n               )","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:38:36.724829Z","iopub.execute_input":"2023-11-03T06:38:36.725264Z","iopub.status.idle":"2023-11-03T06:41:36.526426Z","shell.execute_reply.started":"2023-11-03T06:38:36.725231Z","shell.execute_reply":"2023-11-03T06:41:36.525267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Memory reduction for train_series\n#The following function has been taken from the notebook\n# https://www.kaggle.com/code/renatoreggiani/zzzs-feat-eng-ideas-60-memory-reduction?scriptVersionId=143987308\n\nfrom pandas.api.types import is_datetime64_ns_dtype\nimport gc\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\ndef reduce_mem_usage(df):\n    \n    \"\"\" \n    Iterate through all numeric columns of a dataframe and modify the data type\n    to reduce memory usage.        \n    \"\"\"\n    \n    start_mem = df.memory_usage().sum() / 1024**2\n    print(f'Memory usage of dataframe is {start_mem:.2f} MB')\n    \n    for col in df.columns:\n        col_type = df[col].dtype\n\n        if col_type != object and not is_datetime64_ns_dtype(df[col]):\n            c_min = df[col].min()\n            c_max = df[col].max()\n            if str(col_type)[:3] == 'int':\n                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n                    df[col] = df[col].astype(np.int8)\n                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                    df[col] = df[col].astype(np.int16)\n                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                    df[col] = df[col].astype(np.int32)\n                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                    df[col] = df[col].astype(np.int64)  \n            else:\n                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                    df[col] = df[col].astype(np.float32)\n                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                    df[col] = df[col].astype(np.float32)\n                else:\n                    df[col] = df[col].astype(np.float64)\n        \n\n    df['series_id'] = df['series_id'].astype('category')\n\n    end_mem = df.memory_usage().sum() / 1024**2\n    print(f'Memory usage after optimization is: {end_mem:.2f} MB')\n    decrease = 100 * (start_mem - end_mem) / start_mem\n    print(f'Decreased by {decrease:.2f}%')\n    \n    return df","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:06:00.331780Z","iopub.execute_input":"2023-11-03T05:06:00.332190Z","iopub.status.idle":"2023-11-03T05:06:00.350809Z","shell.execute_reply.started":"2023-11-03T05:06:00.332156Z","shell.execute_reply":"2023-11-03T05:06:00.349401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reduce_mem_usage(train_series)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:06:00.352168Z","iopub.execute_input":"2023-11-03T05:06:00.352533Z","iopub.status.idle":"2023-11-03T05:06:19.440663Z","shell.execute_reply.started":"2023-11-03T05:06:00.352505Z","shell.execute_reply":"2023-11-03T05:06:19.439260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sh = train_series.shape\nprint(f'The shape of train_series is: {sh}')\ntrain_series.head()\ntrain_series.info()\ntrain_series.nunique()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:06:19.444754Z","iopub.execute_input":"2023-11-03T05:06:19.445214Z","iopub.status.idle":"2023-11-03T05:07:03.471138Z","shell.execute_reply.started":"2023-11-03T05:06:19.445180Z","shell.execute_reply":"2023-11-03T05:07:03.469890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sh = test_series.shape\nprint(f'The shape of train_series is: {sh}')\ntest_series.head()\ntest_series.info()\ntest_series.nunique()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:07:03.473183Z","iopub.execute_input":"2023-11-03T05:07:03.474037Z","iopub.status.idle":"2023-11-03T05:07:03.494381Z","shell.execute_reply.started":"2023-11-03T05:07:03.473991Z","shell.execute_reply":"2023-11-03T05:07:03.493113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"enmo_mxs = train_series.enmo.max()\nenmo_mns = train_series.enmo.min()\nenmo_means = train_series.enmo.mean()\nenmo_sts = train_series.enmo.std()\nenmo_mds = train_series.enmo.median()\nenmo_perc25s = train_series.enmo.quantile(0.25)\nenmo_perc75s = train_series.enmo.quantile(0.75)\n\nprint(f'step max is {enmo_mxs}')\nprint(f'step min is {enmo_mns}')\nprint(f'step mean is {enmo_means}')\nprint(f'step standard deviation is {enmo_sts}')\nprint(f'step median is {enmo_mds}')\nprint(f'step first quantile is {enmo_perc25s}')\nprint(f'step third quantile is {enmo_perc75s}')","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:07:03.496474Z","iopub.execute_input":"2023-11-03T05:07:03.496931Z","iopub.status.idle":"2023-11-03T05:07:10.223565Z","shell.execute_reply.started":"2023-11-03T05:07:03.496890Z","shell.execute_reply":"2023-11-03T05:07:10.222112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 6))\nax = sns.distplot(train_series.enmo)\nplt.title('Distribution of ENMO values in train_series')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:07:10.224935Z","iopub.execute_input":"2023-11-03T05:07:10.225669Z","iopub.status.idle":"2023-11-03T05:16:15.286830Z","shell.execute_reply.started":"2023-11-03T05:07:10.225636Z","shell.execute_reply":"2023-11-03T05:16:15.285304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"enmo_mxs = train_series.enmo.max()\nenmo_outlier = train_series.loc[train_series['enmo'] == enmo_mxs]\nprint(enmo_outlier)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:16:15.289473Z","iopub.execute_input":"2023-11-03T05:16:15.289989Z","iopub.status.idle":"2023-11-03T05:16:15.982404Z","shell.execute_reply.started":"2023-11-03T05:16:15.289946Z","shell.execute_reply":"2023-11-03T05:16:15.980548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"enmo_perc99s = train_series.enmo.quantile(0.99)\nprint(f'step 99% is {enmo_perc99s}')\n\nhuge_enmo99 = train_series[train_series['enmo'] > enmo_perc99s]\nhuge_enmo99","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:16:15.984842Z","iopub.execute_input":"2023-11-03T05:16:15.985936Z","iopub.status.idle":"2023-11-03T05:16:18.267216Z","shell.execute_reply.started":"2023-11-03T05:16:15.985876Z","shell.execute_reply":"2023-11-03T05:16:18.265622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"huge_enmo1 = train_series[train_series['enmo'] > 1]\nprint(huge_enmo1.shape)\nhuge_enmo2 = train_series[train_series['enmo'] > 2]\nprint(huge_enmo2.shape)\nhuge_enmo3 = train_series[train_series['enmo'] > 3]\nprint(huge_enmo3.shape)\nhuge_enmo4 = train_series[train_series['enmo'] > 4]\nprint(huge_enmo4.shape)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:16:18.273977Z","iopub.execute_input":"2023-11-03T05:16:18.274550Z","iopub.status.idle":"2023-11-03T05:16:18.977776Z","shell.execute_reply.started":"2023-11-03T05:16:18.274501Z","shell.execute_reply":"2023-11-03T05:16:18.976260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_series.loc[train_series.enmo > 1, 'enmo'] = 1\nhuge_enmo2 = train_series[train_series['enmo'] == 1]\nprint(huge_enmo2.shape)\n\nenmo_mxs = train_series.enmo.max()\nenmo_mns = train_series.enmo.min()\nenmo_means = train_series.enmo.mean()\nenmo_sts = train_series.enmo.std()\nenmo_mds = train_series.enmo.median()\nenmo_perc25s = train_series.enmo.quantile(0.25)\nenmo_perc75s = train_series.enmo.quantile(0.75)\nenmo_perc99s = train_series.enmo.quantile(0.99)\n\nprint(f'step max is {enmo_mxs}')\nprint(f'step min is {enmo_mns}')\nprint(f'step mean is {enmo_means}')\nprint(f'step standard deviation is {enmo_sts}')\nprint(f'step median is {enmo_mds}')\nprint(f'step first quantile is {enmo_perc25s}')\nprint(f'step third quantile is {enmo_perc75s}')\nprint(f'step 99% is {enmo_perc99s}')","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:16:18.983922Z","iopub.execute_input":"2023-11-03T05:16:18.984519Z","iopub.status.idle":"2023-11-03T05:16:27.849649Z","shell.execute_reply.started":"2023-11-03T05:16:18.984466Z","shell.execute_reply":"2023-11-03T05:16:27.848279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 6))\nax = sns.distplot(train_series.enmo)\nplt.title('Distribution of ENMO values in train_series')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:16:27.851294Z","iopub.execute_input":"2023-11-03T05:16:27.851816Z","iopub.status.idle":"2023-11-03T05:25:36.289733Z","shell.execute_reply.started":"2023-11-03T05:16:27.851784Z","shell.execute_reply":"2023-11-03T05:25:36.288549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"anglez_mxs = train_series.anglez.max()\nanglez_mns = train_series.anglez.min()\nanglez_means = train_series.anglez.mean()\nanglez_sts = train_series.anglez.std()\nanglez_mds = train_series.anglez.median()\nanglez_perc25s = train_series.anglez.quantile(0.25)\nanglez_perc75s = train_series.anglez.quantile(0.75)\n\nprint(f'step max is {anglez_mxs}')\nprint(f'step min is {anglez_mns}')\nprint(f'step mean is {anglez_means}')\nprint(f'step standard deviation is {anglez_sts}')\nprint(f'step median is {anglez_mds}')\nprint(f'step first quantile is {anglez_perc25s}')\nprint(f'step third quantile is {anglez_perc75s}')\n\n# plot the distribution of anglez-values\nplt.figure(figsize=(10, 6))\nax = sns.distplot(train_series.anglez)\nplt.title('Distribution of anglez values in train_series')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:25:36.291204Z","iopub.execute_input":"2023-11-03T05:25:36.291562Z","iopub.status.idle":"2023-11-03T05:35:49.017978Z","shell.execute_reply.started":"2023-11-03T05:25:36.291532Z","shell.execute_reply":"2023-11-03T05:35:49.016471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colour_enmo = '#FF7F50'\ncolour_anglez = '#0000FF'\nid_0402a003dae9 = train_series[train_series['series_id'] == '0402a003dae9']\nid_0402a003dae9\nid_0402a003dae9_2w = id_0402a003dae9[id_0402a003dae9['date'].isin(['2018-12-20', '2018-12-21', '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02'])]\nid_0402a003dae9_2w\n\nfig, ax = plt.subplots(ncols = 2, nrows = 5, sharex = True, figsize = (20, 16))\n\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.anglez, color = colour_anglez, ax=ax[0,0])\nax[0, 0].set_title('ANGLEZ values (5 sec.)', fontsize = 16)\n\nresampled_ang1min = id_0402a003dae9_2w[['timestamp', 'anglez']].resample('min', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_ang1min.timestamp, y = resampled_ang1min.anglez, color = colour_anglez, ax=ax[1,0])\nax[1, 0].set_title('ANGLEZ values (resampled 1 min.)', fontsize = 16)\n\nresampled_ang30 = id_0402a003dae9_2w[['timestamp', 'anglez']].resample('30min', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_ang30.timestamp, y = resampled_ang30.anglez, color = colour_anglez, ax=ax[2,0])\nax[2, 0].set_title('ANGLEZ values (resampled 30 min.)', fontsize = 16)\n\nresampled_ang = id_0402a003dae9_2w[['timestamp', 'anglez']].resample('H', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_ang.timestamp, y = resampled_ang.anglez, color = colour_anglez, ax=ax[3,0])\nax[3, 0].set_title('ANGLEZ values (resampled 1 hour)', fontsize = 16)\n\nresampled_ang2h = id_0402a003dae9_2w[['timestamp', 'anglez']].resample('2H', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_ang2h.timestamp, y = resampled_ang2h.anglez, color = colour_anglez, ax=ax[4,0])\nax[4, 0].set_title('ANGLEZ values (resampled 2 hour)', fontsize = 16)\n\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.enmo, color = colour_enmo, ax=ax[0,1])\nax[0, 1].set_title('ENMO values (5 sec.)', fontsize = 16)\n\nresampled_enmo1min = id_0402a003dae9_2w[['timestamp', 'enmo']].resample('min', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_enmo1min.timestamp, y = resampled_enmo1min.enmo, color = colour_enmo, ax=ax[1,1])\nax[1, 1].set_title('ENMO values (resampled 1 min.)', fontsize = 16)\n\nresampled_enmo30 = id_0402a003dae9_2w[['timestamp', 'enmo']].resample('36min', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_enmo30.timestamp, y = resampled_enmo30.enmo, color = colour_enmo, ax=ax[2,1])\nax[2, 1].set_title('ENMO values (resampled 30 min.)', fontsize = 16)\n\nresampled_enmo = id_0402a003dae9_2w[['timestamp', 'enmo']].resample('H', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_enmo.timestamp, y = resampled_enmo.enmo, color = colour_enmo, ax=ax[3,1])\nax[3, 1].set_title('ENMO values (resampled 1 hour)', fontsize = 16)\n\nresampled_enmo2h = id_0402a003dae9_2w[['timestamp', 'enmo']].resample('2H', on='timestamp').mean().reset_index(drop=False)\nsns.lineplot(x = resampled_enmo2h.timestamp, y = resampled_enmo2h.enmo, color = colour_enmo, ax=ax[4,1])\nax[4, 1].set_title('ENMO values (resampled 2 hour)', fontsize = 16)\n\nfor i in range(2):\n    ax[4, i].set_xticklabels(['2018-12-20', '2018-12-21', '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02'], rotation = 45)\n\nfig.suptitle('Resampled ANGLEZ & ENMO values for series_id \"0402a003dae9\" during 2 weeks', fontsize = 20)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:35:49.020288Z","iopub.execute_input":"2023-11-03T05:35:49.021419Z","iopub.status.idle":"2023-11-03T05:36:17.753295Z","shell.execute_reply.started":"2023-11-03T05:35:49.021379Z","shell.execute_reply":"2023-11-03T05:36:17.752117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tes = train_events.shape\nprint(f'The shape of train_events is: {tes}')\ntes = train_events.head()\ntrain_events.info()\nseries_full = train_events[~train_events.isnull().any(axis=1)]\nseries_full.nunique()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:36:17.754980Z","iopub.execute_input":"2023-11-03T05:36:17.755471Z","iopub.status.idle":"2023-11-03T05:36:17.797852Z","shell.execute_reply.started":"2023-11-03T05:36:17.755429Z","shell.execute_reply":"2023-11-03T05:36:17.796422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colour_enmo = '#FF7F50'\ncolour_anglez = '#0000FF'\ncolour_state = '#000000'\nid_0402a003dae9 = train_series[train_series['series_id'] == '0402a003dae9']\nid_0402a003dae9\nid_0402a003dae9_2w = id_0402a003dae9[id_0402a003dae9['date'].isin(['2018-12-20', '2018-12-21', '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02'])]\nid_0402a003dae9_2w\n\nid_0402a003dae9_eve = train_events[train_events['series_id'] == '0402a003dae9'].dropna()\nid_0402a003dae9_eve.loc[train_events.event == 'onset', 'event'] = 1\nid_0402a003dae9_eve.loc[train_events.event == 'wakeup', 'event'] = 0\nid_0402a003dae9_eve_2w = id_0402a003dae9_eve[id_0402a003dae9_eve['date'].isin(['2018-12-20', '2018-12-21', '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02'])]\nid_0402a003dae9_eve_2w\n\nfig, ax = plt.subplots(ncols = 1, nrows = 1, sharex = True, figsize = (10, 6))\n\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.anglez.abs() / id_0402a003dae9_2w.anglez.abs().max(), color = colour_anglez, ax=ax)\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.enmo.abs() / id_0402a003dae9_2w.enmo.abs().max(), color = colour_enmo, ax=ax)\nsns.lineplot(x = id_0402a003dae9_eve_2w.timestamp, y = id_0402a003dae9_eve_2w.event, color = colour_state, ax=ax)\nplt.title('Distribution of anglez values in train_series')","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:36:17.800069Z","iopub.execute_input":"2023-11-03T05:36:17.800937Z","iopub.status.idle":"2023-11-03T05:36:40.751634Z","shell.execute_reply.started":"2023-11-03T05:36:17.800889Z","shell.execute_reply":"2023-11-03T05:36:40.750170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colour_enmo = '#FF7F50'\ncolour_anglez = '#0000FF'\ncolour_state = '#000000'\n\nid_0402a003dae9 = train_series[train_series['series_id'] == '038441c925bb']\nid_0402a003dae9\nid_0402a003dae9_2w = id_0402a003dae9[id_0402a003dae9['date'].isin(['2018-8-14', '2018-8-15', '2018-8-16', '2018-8-17', '2018-8-18', '2018-8-19', '2018-8-20', '2018-8-21', '2018-8-22', '2018-8-23', '2018-8-24', '2018-8-25', '2018-8-26', '2018-8-27'])]\nid_0402a003dae9_2w\n\nid_0402a003dae9_eve = train_events[train_events['series_id'] == '038441c925bb'].dropna()\nid_0402a003dae9_eve.loc[train_events.event == 'onset', 'event'] = 1\nid_0402a003dae9_eve.loc[train_events.event == 'wakeup', 'event'] = 0\nid_0402a003dae9_eve_2w = id_0402a003dae9_eve[id_0402a003dae9_eve['date'].isin(['2018-8-14', '2018-8-15', '2018-8-16', '2018-8-17', '2018-8-18', '2018-8-19', '2018-8-20', '2018-8-21', '2018-8-22', '2018-8-23', '2018-8-24', '2018-8-25', '2018-8-26', '2018-8-27'])]\nid_0402a003dae9_eve_2w\n\nfig, ax = plt.subplots(ncols = 1, nrows = 1, sharex = True, figsize = (10, 6))\n\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.anglez.abs() / id_0402a003dae9_2w.anglez.abs().max(), color = colour_anglez, ax=ax)\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.enmo.abs() / id_0402a003dae9_2w.enmo.abs().max(), color = colour_enmo, ax=ax)\nsns.lineplot(x = id_0402a003dae9_eve_2w.timestamp, y = id_0402a003dae9_eve_2w.event, color = colour_state, ax=ax)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:36:40.753537Z","iopub.execute_input":"2023-11-03T05:36:40.754317Z","iopub.status.idle":"2023-11-03T05:37:02.332596Z","shell.execute_reply.started":"2023-11-03T05:36:40.754281Z","shell.execute_reply":"2023-11-03T05:37:02.331305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_series[\"anglezdif\"] = train_series[\"anglez\"].diff().astype(np.float32)\n\ncolour_enmo = '#FF7F50'\ncolour_anglez = '#0000FF'\nid_0402a003dae9 = train_series[train_series['series_id'] == '0402a003dae9']\nid_0402a003dae9\nid_0402a003dae9_2w = id_0402a003dae9[id_0402a003dae9['date'].isin(['2018-12-20', '2018-12-21', '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02'])]\nid_0402a003dae9_2w\n\nid_0402a003dae9_eve = train_events[train_events['series_id'] == '0402a003dae9'].dropna()\nid_0402a003dae9_eve.loc[train_events.event == 'onset', 'event'] = 1\nid_0402a003dae9_eve.loc[train_events.event == 'wakeup', 'event'] = 0\nid_0402a003dae9_eve_2w = id_0402a003dae9_eve[id_0402a003dae9_eve['date'].isin(['2018-12-20', '2018-12-21', '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29', '2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02'])]\nid_0402a003dae9_eve_2w\n\nfig, ax = plt.subplots(ncols = 1, nrows = 1, sharex = True, figsize = (10, 6))\n\nsns.lineplot(x = id_0402a003dae9_2w.timestamp, y = id_0402a003dae9_2w.anglezdif.abs() / id_0402a003dae9_2w.anglezdif.abs().max(), color = colour_anglez, ax=ax)\nsns.lineplot(x = id_0402a003dae9_eve_2w.timestamp, y = id_0402a003dae9_eve_2w.event, color = colour_state, ax=ax)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:37:02.334482Z","iopub.execute_input":"2023-11-03T05:37:02.334865Z","iopub.status.idle":"2023-11-03T05:37:14.268246Z","shell.execute_reply.started":"2023-11-03T05:37:02.334831Z","shell.execute_reply":"2023-11-03T05:37:14.267251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Feature Engineering","metadata":{}},{"cell_type":"code","source":"def basic_fe(df, periods):\n    \n    df['series_id'] = df['series_id'].astype('category')\n    df['timestamp'] = pd.to_datetime(df['timestamp']).apply(lambda t: t.tz_localize(None))\n    df['hour'] = df[\"timestamp\"].dt.hour\n    \n    df.sort_values(['timestamp'], inplace=True)\n    df.set_index('timestamp', inplace=True)\n    \n    df['lids'] = np.maximum(0., df['enmo'] - 0.02)\n    df['lids'] = df['lids'].rolling(f'{120*5}s', center=True, min_periods=1).agg('sum')\n    df['lids'] = 100 / (df['lids'] + 1)\n    df['lids'] = df['lids'].rolling(f'{360*5}s', center=True, min_periods=1).agg('mean').astype(np.float16)\n    \n    df[\"enmo\"] = (df[\"enmo\"]*1000).astype(np.int16)\n    df[\"anglez\"] = df[\"anglez\"].astype(np.int16)\n    df[\"anglezdiffabs\"] = df[\"anglez\"].diff().abs().astype(np.float16)\n    \n    for col in ['enmo', 'anglez', 'anglezdiffabs']:\n        for p in periods:\n            rol_args = {'window':f'{p+5}s', 'min_periods':10, 'center':True}\n            \n            for agg in ['mean', 'max', 'min']:\n                df[f'{col}_{p}_{agg}'] = df[col].rolling(**rol_args).agg(agg).astype(np.float16).values\n                gc.collect()\n            # There was an overflow error when trying to cast to float16, so I decided to leave it as float32\n            for agg in ['var']:\n                df[f'{col}_{p}_{agg}'] = df[col].rolling(**rol_args).agg(agg).astype(np.float32).values\n                gc.collect()\n\n            \n            df[f'{col}_{p}_amplit'] = df[f'{col}_{p}_max'] - df[f'{col}_{p}_min']\n            df[f'{col}_diff_{p}_max'] = df[f'{col}_{p}_max'].diff().abs().rolling(**rol_args).max().astype(np.float16)\n            df[f'{col}_diff_{p}_mean'] = df[f'{col}_{p}_min'].diff().abs().rolling(**rol_args).mean().astype(np.float16)\n            gc.collect()\n \n    df.reset_index(inplace=True)\n    df.dropna(inplace=True)\n    gc.collect()\n\n    return df","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:42:31.235426Z","iopub.execute_input":"2023-11-03T06:42:31.236068Z","iopub.status.idle":"2023-11-03T06:42:31.254963Z","shell.execute_reply.started":"2023-11-03T06:42:31.236024Z","shell.execute_reply":"2023-11-03T06:42:31.253534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def feat_eng_by_id(idx, periods):\n    \n    from warnings import simplefilter \n    simplefilter(action=\"ignore\", category=pd.errors.PerformanceWarning)\n    \n    df = pd.read_parquet('/kaggle/input/zzzs-lightweight-training-dataset-target/Zzzs_train.parquet', filters=[('series_id','=',idx)])\n    df = basic_fe(df, periods)\n    \n    return df","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:42:33.800862Z","iopub.execute_input":"2023-11-03T06:42:33.801298Z","iopub.status.idle":"2023-11-03T06:42:33.808810Z","shell.execute_reply.started":"2023-11-03T06:42:33.801266Z","shell.execute_reply":"2023-11-03T06:42:33.807380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"periods = [60] # 30 120 300","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:42:36.257480Z","iopub.execute_input":"2023-11-03T06:42:36.257943Z","iopub.status.idle":"2023-11-03T06:42:36.263840Z","shell.execute_reply.started":"2023-11-03T06:42:36.257907Z","shell.execute_reply":"2023-11-03T06:42:36.262479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"series_id  = pd.read_parquet('/kaggle/input/zzzs-lightweight-training-dataset-target/Zzzs_train.parquet', columns=['series_id'])\nseries_id = series_id['series_id'].unique()\n\nweird_series = ['31011ade7c0a', 'a596ad0b82aa']\nseries_id = [s for s in series_id if s not in weird_series]\n\n\ndf = Parallel(n_jobs=-2)(delayed(feat_eng_by_id)(i, periods) for i in series_id)\ndf = pd.concat(df, ignore_index=True)\n\nfeatures = [col for col in df.columns if col not in ['timestamp', 'series_id', 'step', 'awake']]\n\nfor p in periods:\n    plt.figure(figsize=(12,12))\n    plt.title(f\"Correlation heatmap for features with period {p}[s]\")\n    sns.heatmap(df[features].filter(like=f'_{p}_').corr(),\n    vmin=-1, vmax=1, center=0,\n    cmap=sns.color_palette(\"flare\", as_cmap=True),\n    square=True)\n    plt.show() ","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:42:42.271867Z","iopub.execute_input":"2023-11-03T06:42:42.272330Z","iopub.status.idle":"2023-11-03T06:51:45.541438Z","shell.execute_reply.started":"2023-11-03T06:42:42.272292Z","shell.execute_reply":"2023-11-03T06:51:45.536365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features_to_drop = ['anglezdiffabs_300_min', 'anglezdiffabs_120_min',  ]\nfor p in periods:\n    features_to_drop.append(f'anglezdiffabs_{p}_amplit')\n    features_to_drop.append(f'enmo_{p}_amplit')","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:48:44.573574Z","iopub.execute_input":"2023-11-03T05:48:44.574082Z","iopub.status.idle":"2023-11-03T05:48:44.582321Z","shell.execute_reply.started":"2023-11-03T05:48:44.574037Z","shell.execute_reply":"2023-11-03T05:48:44.580622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"corr_with_target = df[features].corrwith(df['awake'])\ncorr_with_target.abs().sort_values().tail(50)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:48:44.584749Z","iopub.execute_input":"2023-11-03T05:48:44.585263Z","iopub.status.idle":"2023-11-03T05:48:44.648167Z","shell.execute_reply.started":"2023-11-03T05:48:44.585217Z","shell.execute_reply":"2023-11-03T05:48:44.646861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features_for_heatmap = corr_with_target.abs().sort_values().tail(27).index.to_list()\nfeatures_for_heatmap = [f for f in features_for_heatmap if f not in ['anglezdiffabs_3600_min','anglezdiffabs_diff_3600_mean']]\nplt.figure(figsize=(14,14))\nplt.title(f\"Correlation heatmap\")\nsns.heatmap(df[features_for_heatmap].corr(),\nvmin=-1, vmax=1, center=0,\ncmap=sns.color_palette(\"flare\", as_cmap=True),\nsquare=True)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:48:44.650213Z","iopub.execute_input":"2023-11-03T05:48:44.650737Z","iopub.status.idle":"2023-11-03T05:48:45.644160Z","shell.execute_reply.started":"2023-11-03T05:48:44.650692Z","shell.execute_reply":"2023-11-03T05:48:45.642721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df[::50]\n\nlgb_params = {\n'boosting_type':'gbdt',\n'num_leaves':35,\n'max_depth':6,\n'learning_rate':0.03,\n'n_estimators':850,\n'subsample_for_bin':200000,\n'min_child_weight':0.001,\n'min_child_samples':20,\n'subsample':0.9,\n'reg_alpha':0.05,\n'reg_lambda':0.05,\n'verbose': -1\n}","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:52:47.382524Z","iopub.execute_input":"2023-11-03T06:52:47.383058Z","iopub.status.idle":"2023-11-03T06:52:47.391878Z","shell.execute_reply.started":"2023-11-03T06:52:47.383018Z","shell.execute_reply":"2023-11-03T06:52:47.390468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(df, cv):\n    \n    drop_cols = ['series_id', 'step', 'timestamp']\n    X, y = df.drop(columns=drop_cols+['awake']), df['awake']\n    gc.collect()\n    \n    cv_split = cv.split(X)\n    models = []\n    mean_f1 = 0\n    mean_acc = 0\n    \n    for i, (train_index, test_index) in enumerate(cv_split):\n\n        X_train, y_train = X.iloc[train_index], y.iloc[train_index]\n        X_test, y_test = X.iloc[test_index], y.iloc[test_index]\n        \n        print(f\"Fitting model {i+1} of {cv.n_splits}\")\n        \n        model = lgb.LGBMClassifier(random_state=42, n_jobs=-1, **lgb_params)\n        model.fit(X_train, y_train)\n        preds = model.predict(X_test)\n        f1 = f1_score(y_test, preds)\n        acc = accuracy_score(y_test, preds)\n        print(f\"Fold {i+1} finished training\\n F1:{f1_score(y_test, preds)} | Acc:{accuracy_score(y_test, preds)}\")\n        mean_f1 += f1\n        mean_acc += acc\n        models.append(model)\n        \n    print('-'*50)\n    print(f\"Training finished\\nF1: {mean_f1 / cv.n_splits}, Acc: {mean_acc / cv.n_splits}\")   \n    gc.collect()\n    \n    return models","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:52:49.712306Z","iopub.execute_input":"2023-11-03T06:52:49.712737Z","iopub.status.idle":"2023-11-03T06:52:49.724796Z","shell.execute_reply.started":"2023-11-03T06:52:49.712707Z","shell.execute_reply":"2023-11-03T06:52:49.723548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Fitting model with all {len(features)} features\")\nfrom sklearn.model_selection import KFold, train_test_split\nimport lightgbm as lgb\nfrom sklearn.metrics import f1_score, accuracy_score\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nmodels = train_model(df, kf)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:52:56.380626Z","iopub.execute_input":"2023-11-03T06:52:56.381055Z","iopub.status.idle":"2023-11-03T06:55:21.562481Z","shell.execute_reply.started":"2023-11-03T06:52:56.381023Z","shell.execute_reply":"2023-11-03T06:55:21.560975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fi = pd.DataFrame([pd.Series(model.feature_importances_, index=features) for model in models])\nfeature_importance = fi.mean(axis=0).sort_values()\n\nplt.figure(figsize=(15,8))\nplt.xticks(rotation='vertical')\nsns.barplot(x=feature_importance[-15:].index, y=feature_importance[-15:].values)\nplt.title('LightGBM feature importance')","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:59:13.048584Z","iopub.execute_input":"2023-11-03T06:59:13.049595Z","iopub.status.idle":"2023-11-03T06:59:13.634677Z","shell.execute_reply.started":"2023-11-03T06:59:13.049552Z","shell.execute_reply":"2023-11-03T06:59:13.633227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df.drop(columns=features_to_drop)\nfeatures = [col for col in df.columns if col not in ['timestamp', 'series_id', 'step', 'awake']]\n\nprint(f\"Fitting model with {len(features)} features\")\n\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nmodels = train_model(df, kf)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:48:49.877792Z","iopub.execute_input":"2023-11-03T05:48:49.878333Z","iopub.status.idle":"2023-11-03T05:48:53.484153Z","shell.execute_reply.started":"2023-11-03T05:48:49.878289Z","shell.execute_reply":"2023-11-03T05:48:53.482881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fi = pd.DataFrame([pd.Series(model.feature_importances_, index=features) for model in models])\nfeature_importance = fi.mean(axis=0).sort_values()\nplt.figure(figsize=(15,8))\nplt.xticks(rotation='vertical')\nsns.barplot(x=feature_importance[-15:].index, y=feature_importance[-15:].values)\nplt.title('LightGBM feature importance after dropping some features')","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:48:53.489079Z","iopub.execute_input":"2023-11-03T05:48:53.489491Z","iopub.status.idle":"2023-11-03T05:48:54.027186Z","shell.execute_reply.started":"2023-11-03T05:48:53.489455Z","shell.execute_reply":"2023-11-03T05:48:54.025968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training Models","metadata":{}},{"cell_type":"markdown","source":"### Training and validating random forest","metadata":{}},{"cell_type":"code","source":"# Saving classifier \nimport pickle\nwith open('model.pkl', 'wb') as f:\n    pickle.dump(models, f)\n\n#with open('rf_classifier.pkl', 'rb') as f:\n#    rf_classifier = pickle.load(f)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:00:29.625683Z","iopub.execute_input":"2023-11-03T07:00:29.626228Z","iopub.status.idle":"2023-11-03T07:00:30.203483Z","shell.execute_reply.started":"2023-11-03T07:00:29.626192Z","shell.execute_reply":"2023-11-03T07:00:30.202211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Applying to test data","metadata":{}},{"cell_type":"code","source":"# Recovering memory\ndel features\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:00:32.040445Z","iopub.execute_input":"2023-11-03T07:00:32.043636Z","iopub.status.idle":"2023-11-03T07:00:32.291829Z","shell.execute_reply.started":"2023-11-03T07:00:32.043591Z","shell.execute_reply":"2023-11-03T07:00:32.290434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from itertools import groupby\n\ndef predict_test(idx): # 这里period只能用一个\n    \n    test  = pd.read_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet',\n                            filters=[('series_id','=',idx)])\n    \n    test = basic_fe(test, periods)\n    \n    drop_cols = ['series_id', 'step', 'timestamp']\n    \n#     features_to_drop = ['anglezdiffabs_300_min', 'anglezdiffabs_120_min',  ]\n#     for p in periods:\n#         features_to_drop.append(f'anglezdiffabs_{p}_amplit')\n#         features_to_drop.append(f'enmo_{p}_amplit')\n        \n    X_test = test.drop(columns=drop_cols)\n#     X_test = X_test.drop(columns=features_to_drop)\n    \n    p = mod.predict(X_test)\n    \n    test[\"not_awake\"] = p[0]\n    test[\"awake\"]     = p[1]\n    \n    smoothing_length = 2*230\n\n    test[\"score\"]  = test[\"awake\"].rolling(smoothing_length, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n    test[\"smooth\"] = test[\"not_awake\"].rolling(smoothing_length, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n    # re-binarize\n    test[\"smooth\"] = test[\"smooth\"].round()\n\n    # https://stackoverflow.com/questions/73777727/how-to-mark-start-end-of-a-series-of-non-null-and-non-0-values-in-a-column-of-a\n    def 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    test['event'] = get_event(test)\n    \n    return test.loc[test['event'] != 0][['series_id','step','event','score']]","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:05:11.471279Z","iopub.execute_input":"2023-11-03T07:05:11.471846Z","iopub.status.idle":"2023-11-03T07:05:11.489545Z","shell.execute_reply.started":"2023-11-03T07:05:11.471808Z","shell.execute_reply":"2023-11-03T07:05:11.487935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"series_id  = pd.read_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet', columns=['series_id'])\nseries_id = series_id.series_id.unique()\ntests = []\n\nfor idx in series_id:\n    for mod in models:\n        tests.append(predict_test(idx))","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:05:13.694617Z","iopub.execute_input":"2023-11-03T07:05:13.695607Z","iopub.status.idle":"2023-11-03T07:06:12.233693Z","shell.execute_reply.started":"2023-11-03T07:05:13.695551Z","shell.execute_reply":"2023-11-03T07:06:12.232281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.concat(tests)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:06:20.672980Z","iopub.execute_input":"2023-11-03T07:06:20.673428Z","iopub.status.idle":"2023-11-03T07:06:20.696233Z","shell.execute_reply.started":"2023-11-03T07:06:20.673395Z","shell.execute_reply":"2023-11-03T07:06:20.694475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:09:39.508756Z","iopub.execute_input":"2023-11-03T07:09:39.509418Z","iopub.status.idle":"2023-11-03T07:09:39.525931Z","shell.execute_reply.started":"2023-11-03T07:09:39.509366Z","shell.execute_reply":"2023-11-03T07:09:39.524136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission = test.copy().reset_index(drop=True).reset_index(names='row_id')\nsample_submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:06:28.563483Z","iopub.execute_input":"2023-11-03T07:06:28.563960Z","iopub.status.idle":"2023-11-03T07:06:28.573417Z","shell.execute_reply.started":"2023-11-03T07:06:28.563923Z","shell.execute_reply":"2023-11-03T07:06:28.571935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission","metadata":{"execution":{"iopub.status.busy":"2023-11-03T07:09:43.948398Z","iopub.execute_input":"2023-11-03T07:09:43.948828Z","iopub.status.idle":"2023-11-03T07:09:43.960391Z","shell.execute_reply.started":"2023-11-03T07:09:43.948795Z","shell.execute_reply":"2023-11-03T07:09:43.959277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Getting event predictions for test set and saving submission\n# submission = get_events(test_series.collect(), models)\n# submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:49:01.956676Z","iopub.status.idle":"2023-11-03T05:49:01.957064Z","shell.execute_reply.started":"2023-11-03T05:49:01.956873Z","shell.execute_reply":"2023-11-03T05:49:01.956891Z"},"trusted":true},"execution_count":null,"outputs":[]}]}