{"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"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### LightGBM\n\nReference: [Random Forest starter](https://www.kaggle.com/code/carlmcbrideellis/zzzs-random-forest-model-starter) by [Carl McBride Ellis](https://www.kaggle.com/carlmcbrideellis)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom itertools import groupby\nimport gc","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-09-13T12:59:42.392210Z","iopub.execute_input":"2023-09-13T12:59:42.392705Z","iopub.status.idle":"2023-09-13T12:59:42.780879Z","shell.execute_reply.started":"2023-09-13T12:59:42.392673Z","shell.execute_reply":"2023-09-13T12:59:42.779551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TR_FILE = '/kaggle/input/zzzs-lightweight-training-dataset-target/Zzzs_train.parquet'\nTE_FILE = '/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet'","metadata":{"execution":{"iopub.status.busy":"2023-09-13T12:59:43.882182Z","iopub.execute_input":"2023-09-13T12:59:43.882674Z","iopub.status.idle":"2023-09-13T12:59:43.887684Z","shell.execute_reply.started":"2023-09-13T12:59:43.882645Z","shell.execute_reply":"2023-09-13T12:59:43.886382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_parquet(TR_FILE, columns=['series_id', 'timestamp', 'anglez', 'enmo', 'awake'])\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-13T12:59:45.105610Z","iopub.execute_input":"2023-09-13T12:59:45.106028Z","iopub.status.idle":"2023-09-13T12:59:51.809588Z","shell.execute_reply.started":"2023-09-13T12:59:45.105991Z","shell.execute_reply":"2023-09-13T12:59:51.808620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Feature Engineering","metadata":{}},{"cell_type":"code","source":"def create_features(df):\n    # parse the timestamp and create an \"hour\" feature\n    df[\"timestamp\"] = pd.to_datetime(df[\"timestamp\"],utc=True)\n    df[\"hour\"] = df[\"timestamp\"].dt.hour\n    \n    # drop timestamp once time features are extracted\n    df.drop(columns=['timestamp'], inplace=True)\n    \n    # feature cross\n    df[\"anglez_times_enmo\"] = abs(df[\"anglez\"]) * df[\"enmo\"]\n    \n    # \"rolling\" features\n    periods = 50\n    df[\"anglez_diff\"] = df.groupby('series_id')['anglez'].diff(periods=periods).fillna(method=\"bfill\")\n    df[\"enmo_diff\"]   = df.groupby('series_id')['enmo'].diff(periods=periods).fillna(method=\"bfill\")\n    df[\"anglez_rolling\"] = df[\"anglez\"].rolling(periods,center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n    df[\"enmo_rolling\"]   = df[\"enmo\"].rolling(periods,center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n    df[\"anglez_diff_rolling\"] = df[\"anglez_diff\"].rolling(periods,center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n    df[\"enmo_diff_rolling\"]   = df[\"enmo_diff\"].rolling(periods,center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n    return df","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:00:13.235137Z","iopub.execute_input":"2023-09-13T13:00:13.235508Z","iopub.status.idle":"2023-09-13T13:00:13.246823Z","shell.execute_reply.started":"2023-09-13T13:00:13.235481Z","shell.execute_reply":"2023-09-13T13:00:13.245716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features = [\"hour\",\"anglez_times_enmo\",\n           \"anglez\",\"anglez_diff\",\"anglez_rolling\",\"anglez_diff_rolling\",\n           \"enmo\",\"enmo_diff\",\"enmo_rolling\",\"enmo_diff_rolling\"]","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:00:16.020666Z","iopub.execute_input":"2023-09-13T13:00:16.021096Z","iopub.status.idle":"2023-09-13T13:00:16.026106Z","shell.execute_reply.started":"2023-09-13T13:00:16.021061Z","shell.execute_reply":"2023-09-13T13:00:16.025097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = create_features(train)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:00:17.609460Z","iopub.execute_input":"2023-09-13T13:00:17.609862Z","iopub.status.idle":"2023-09-13T13:02:09.830284Z","shell.execute_reply.started":"2023-09-13T13:00:17.609827Z","shell.execute_reply":"2023-09-13T13:02:09.829181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nimport lightgbm as lgb\nclassifier = lgb.LGBMClassifier()\n\nX_train = train[features]\ny_train = train[\"awake\"]\n\nclassifier.fit(X_train, y_train)","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:02:17.012408Z","iopub.execute_input":"2023-09-13T13:02:17.013344Z","iopub.status.idle":"2023-09-13T13:03:32.182489Z","shell.execute_reply.started":"2023-09-13T13:02:17.013296Z","shell.execute_reply":"2023-09-13T13:03:32.181439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del train, X_train, y_train\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:03:52.347169Z","iopub.execute_input":"2023-09-13T13:03:52.347689Z","iopub.status.idle":"2023-09-13T13:03:52.468945Z","shell.execute_reply.started":"2023-09-13T13:03:52.347654Z","shell.execute_reply":"2023-09-13T13:03:52.467578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predictions on test set","metadata":{}},{"cell_type":"markdown","source":"We will consider using one series at a time ","metadata":{}},{"cell_type":"code","source":"def get_test_series_id():\n    return pd.read_parquet(TE_FILE, columns=['series_id'])['series_id'].unique()\n\ntest_series = get_test_series_id()","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:03:57.744737Z","iopub.execute_input":"2023-09-13T13:03:57.745808Z","iopub.status.idle":"2023-09-13T13:03:57.761948Z","shell.execute_reply.started":"2023-09-13T13:03:57.745768Z","shell.execute_reply":"2023-09-13T13:03:57.760977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define a function to extract events (onset and wakeup) from smoothed data:\ndef get_event(df):\n    lstCV = zip(df.series_id, df.smooth)\n    lstPOI = []\n    for (c, v), g in groupby(lstCV, lambda cv: (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","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:04:02.347417Z","iopub.execute_input":"2023-09-13T13:04:02.347831Z","iopub.status.idle":"2023-09-13T13:04:02.357748Z","shell.execute_reply.started":"2023-09-13T13:04:02.347799Z","shell.execute_reply":"2023-09-13T13:04:02.356421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_predictions(test_series):\n    for series in test_series:\n        test = pd.read_parquet(TE_FILE,\n                             columns=['timestamp', 'anglez', 'enmo', 'step'],\n                             filters=[('series_id', '=', series)])\n        test['series_id'] = series\n        test = create_features(test)\n        \n        test['score'] = classifier.predict_proba(test[features])[:,1]\n        test[\"not_awake\"] = 1 - test[\"score\"]\n        \n        smoothing_length = 2 * 250 \n        test[\"smooth\"] = test[\"not_awake\"].rolling(smoothing_length, center=True).mean().fillna(method=\"bfill\").fillna(method=\"ffill\")\n        test[\"smooth\"] = test[\"smooth\"].round()\n        test[\"event\"] = get_event(test)\n        \n        df = test.loc[test[\"event\"] != 0][[\"series_id\",\"step\",\"event\",\"score\"]].copy().reset_index(drop=True)\n        df.to_csv(f'{series}.csv', index=False)\n        del df, test\n        gc.collect()\n        \ndef combine_predictions(test_series):\n    sub = pd.read_csv(f'{test_series[0]}.csv')\n    for series in test_series[1:]:\n        temp = pd.read_csv(f'{series}.csv')\n        sub = pd.concat([sub, temp], ignore_index=True)\n        del temp\n        gc.collect()\n    sub = sub.copy().reset_index(drop=True).reset_index(names=\"row_id\")\n    sub.to_csv('submission.csv', index=False)\n    return sub","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:04:59.639156Z","iopub.execute_input":"2023-09-13T13:04:59.639609Z","iopub.status.idle":"2023-09-13T13:04:59.651602Z","shell.execute_reply.started":"2023-09-13T13:04:59.639576Z","shell.execute_reply":"2023-09-13T13:04:59.650542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generate_predictions(test_series)\nsub = combine_predictions(test_series)\nsub.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-13T13:05:01.251180Z","iopub.execute_input":"2023-09-13T13:05:01.251598Z","iopub.status.idle":"2023-09-13T13:05:01.961628Z","shell.execute_reply.started":"2023-09-13T13:05:01.251565Z","shell.execute_reply":"2023-09-13T13:05:01.960439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}],"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"}}