{"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":150631933,"sourceType":"kernelVersion"},{"sourceId":151583600,"sourceType":"kernelVersion"}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import sys \nsys.path.append('/kaggle/input/event-detection-ap/')\nfrom metric import score","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ntrain_events = pd.read_csv(\"/kaggle/input/child-mind-institute-detect-sleep-states/train_events.csv\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-11-24T19:54:21.503715Z","iopub.execute_input":"2023-11-24T19:54:21.504172Z","iopub.status.idle":"2023-11-24T19:54:21.892559Z","shell.execute_reply.started":"2023-11-24T19:54:21.504131Z","shell.execute_reply":"2023-11-24T19:54:21.891079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"series_ids = train_events['series_id'].unique()","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:54:21.895071Z","iopub.execute_input":"2023-11-24T19:54:21.895729Z","iopub.status.idle":"2023-11-24T19:54:21.913329Z","shell.execute_reply.started":"2023-11-24T19:54:21.895688Z","shell.execute_reply":"2023-11-24T19:54:21.911487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"WINDOW_SIZE = int(2*60*60/5)\nSTEP_SIZE = int(20*60/5)","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:54:21.914640Z","iopub.execute_input":"2023-11-24T19:54:21.915008Z","iopub.status.idle":"2023-11-24T19:54:21.920923Z","shell.execute_reply.started":"2023-11-24T19:54:21.914978Z","shell.execute_reply":"2023-11-24T19:54:21.919476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_data(series_id, window_size, step_size):\n    features = ['awake', 'timestamp', 'anglez', 'enmo', 'step', 'series_id']\n\n    _train_series = pd.read_csv(\"/kaggle/input/intermediatedatageneration/train_series_{}.csv\".format(series_id))\n\n    _data = []\n    for _start_step in range(0, len(_train_series)-window_size, step_size):\n        _data.append(_train_series[features].iloc[_start_step:(_start_step+window_size)].values)\n\n    _data = np.stack(_data)\n    train_data = _data[np.all(_data[:,:,0]!=-1, axis=1),:,:]\n\n    data_info = pd.DataFrame(\n        train_data[:, int(window_size/2), np.isin(features, ['series_id', 'timestamp', 'step'])],\n        columns = ['timestamp', 'step', 'series_id']\n    )\n    data_info['timestamp'] = pd.to_datetime(data_info['timestamp'], utc=True).dt.tz_convert('America/Los_Angeles')\n\n    X = train_data[:, :, np.isin(features, ['anglez', 'enmo'])].astype(np.float32)\n\n    y = train_data[:, int(window_size/2), np.isin(features, ['awake'])].astype(np.int32)\n    y = np.concatenate([y, 1-y], 1)\n    \n    return X, y, data_info","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:54:21.922926Z","iopub.execute_input":"2023-11-24T19:54:21.923216Z","iopub.status.idle":"2023-11-24T19:54:21.933399Z","shell.execute_reply.started":"2023-11-24T19:54:21.923193Z","shell.execute_reply":"2023-11-24T19:54:21.932314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nfrom keras.utils import Sequence\nimport random\n\nclass MyGenerator(Sequence):\n    def __init__(self, series_ids, batch_size, steps_per_epoch):\n        self.series_ids = series_ids\n        self.batch_size = batch_size\n        self.steps_per_epoch = steps_per_epoch\n        \n        self.num_X_used = 0\n        self.num_called = 0\n\n        self.X = np.empty(0)\n        self.y = np.empty(0)\n\n    def __len__(self):\n        return self.steps_per_epoch\n    \n    def _load_data(self, series_id):\n        X, y, _ = load_data(series_id, WINDOW_SIZE, STEP_SIZE)\n        \n        self.X = X\n        self.y = y\n        self.num_X_used = 0\n        \n    def __getitem__(self, idx):\n        if (self.num_X_used > int(len(self.X)/self.batch_size)) or (len(self.X)==0):\n            series_id = random.choice(self.series_ids)\n            self._load_data(series_id)\n            \n        start_id = self.num_X_used*self.batch_size\n        end_id = (self.num_X_used*self.batch_size+self.batch_size)\n\n        batch_x = self.X[start_id:end_id,:,:]\n        batch_y = self.y[start_id:end_id,:]\n        \n        self.num_called += 1\n        self.num_X_used += 1\n            \n        if self.num_called==(self.steps_per_epoch-1):\n            self.num_called = 0 \n        \n        return batch_x, batch_y","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:54:21.934865Z","iopub.execute_input":"2023-11-24T19:54:21.935192Z","iopub.status.idle":"2023-11-24T19:54:36.579452Z","shell.execute_reply.started":"2023-11-24T19:54:21.935162Z","shell.execute_reply":"2023-11-24T19:54:36.578217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_epoch = 300\n\nbatch_size = 8\nsteps_per_epoch = 50\n\nmy_generator = MyGenerator(series_ids, batch_size, steps_per_epoch)","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:54:36.580938Z","iopub.execute_input":"2023-11-24T19:54:36.581560Z","iopub.status.idle":"2023-11-24T19:54:36.588993Z","shell.execute_reply.started":"2023-11-24T19:54:36.581527Z","shell.execute_reply":"2023-11-24T19:54:36.587939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Dense\nfrom keras.layers import Dropout\nfrom keras.layers import Activation\nfrom keras.layers import LSTM\nfrom keras.optimizers import Adam\n\n# model = Sequential() \n# model.add(LSTM(128, batch_input_shape=(None, WINDOW_SIZE, 2)))\n# model.add(Dropout(0.5))\n# model.add(Dense(2, activation='softmax')) \n\nmodel = Sequential() \nmodel.add(LSTM(128,return_sequences=True, batch_input_shape=(None, WINDOW_SIZE, 2)))\nmodel.add(Dropout(0.2))\nmodel.add(LSTM(units=32))\nmodel.add(Dropout(0.2))\nmodel.add(Dense(2, activation='softmax')) \n\nmodel.compile(\n    loss='binary_crossentropy', \n    optimizer=Adam(), \n    metrics = ['accuracy']\n)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:54:36.590184Z","iopub.execute_input":"2023-11-24T19:54:36.594450Z","iopub.status.idle":"2023-11-24T19:54:37.083363Z","shell.execute_reply.started":"2023-11-24T19:54:36.594246Z","shell.execute_reply":"2023-11-24T19:54:37.081758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nhist = model.fit_generator(\n    my_generator,\n    epochs=n_epoch,\n#     validation_data=(X_valid, y_valid),\n    )\n\nplt.plot(hist.history['loss'],label=\"train set\")\n# plt.plot(hist.history['val_loss'],label=\"test set\")\nplt.title('model loss')\nplt.xlabel('epoch')\nplt.ylabel('loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-26T16:42:42.418299Z","iopub.execute_input":"2023-11-26T16:42:42.418623Z","iopub.status.idle":"2023-11-26T16:42:42.694697Z","shell.execute_reply.started":"2023-11-26T16:42:42.418597Z","shell.execute_reply":"2023-11-26T16:42:42.692981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('lstm.h5')","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:55:36.308128Z","iopub.status.idle":"2023-11-24T19:55:36.308831Z","shell.execute_reply.started":"2023-11-24T19:55:36.308552Z","shell.execute_reply":"2023-11-24T19:55:36.308585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"series_id = series_ids[0]\nX, y, data_info = load_data(series_id, WINDOW_SIZE, STEP_SIZE)","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:55:36.309923Z","iopub.status.idle":"2023-11-24T19:55:36.310946Z","shell.execute_reply.started":"2023-11-24T19:55:36.310724Z","shell.execute_reply":"2023-11-24T19:55:36.310747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_y = model.predict(X) ","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:55:36.312041Z","iopub.status.idle":"2023-11-24T19:55:36.312805Z","shell.execute_reply.started":"2023-11-24T19:55:36.312525Z","shell.execute_reply":"2023-11-24T19:55:36.312546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\n\ndef rmse(y_pred, y_true):\n    return np.sqrt(((y_true - y_pred) ** 2).mean())\n\nprint(\"RMSE Score\")\nprint(\"  - \" , rmse(pred_y[:,0], y[:,0]))\n\npred_y_df = pd.DataFrame(pred_y[:,0])\npred_y_df.index = data_info['timestamp']\n\ny_df = pd.DataFrame(y[:,0])\ny_df.index = data_info['timestamp']\n\nfig, ax = plt.subplots(figsize=(20, 3))\nax.plot(pred_y_df, color='red',  label=\"train\")\nax.plot(y_df, color='blue',  label=\"observed\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:55:36.314176Z","iopub.status.idle":"2023-11-24T19:55:36.315118Z","shell.execute_reply.started":"2023-11-24T19:55:36.314909Z","shell.execute_reply":"2023-11-24T19:55:36.314930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_events(preds, probs, test, prediction_window=10+1, score_window=10+1) :\n    test.loc[:, 'prediction'] = preds\n    test.loc[:, 'prediction'] = test['prediction'].rolling(prediction_window, center=True).median()\n    test.loc[:, 'probability'] = probs\n    \n    # test.loc[test['prediction']==0, 'probability'] = 1-test.loc[test['prediction']==0, 'probability']\n    test.loc[:, 'score'] = test['probability'].rolling(score_window, center=True, min_periods=10).mean().bfill().ffill()\n\n    test.loc[:, 'pred_diff'] = test['prediction'].diff()\n    \n    test.loc[:, 'event'] = test['pred_diff'].replace({1:'wakeup', -1:'onset', 0:np.nan})\n    \n    test_wakeup = test[test['event']=='wakeup'].groupby(test['timestamp'].dt.date).agg('first')\n    test_onset = test[test['event']=='onset'].groupby(test['timestamp'].dt.date).agg('last')\n    test = pd.concat([test_wakeup, test_onset], ignore_index=True).sort_values('timestamp')\n    \n    test['step'] = test['step'].astype('int32')\n\n    return test\n\npreds = 1-np.argmax(pred_y, axis=1)\nprobs = np.max(pred_y, axis=1)\n\npredict_events = get_events(preds, probs, data_info)\npredict_events","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tolerances = {\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\nseries_id_column_name = \"series_id\"\ntime_column_name = \"step\"\nevent_column_name = \"event\"\nscore_column_name = \"score\"\nuse_scoring_intervals = None\n\nscore(\n        train_events,\n        predict_events,\n        tolerances,\n        series_id_column_name,\n        time_column_name,\n        event_column_name,\n        score_column_name,\n        use_scoring_intervals\n)","metadata":{},"execution_count":null,"outputs":[]}]}