{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"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":"code","source":"import pandas as pd\nimport numpy as np\nimport sklearn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import roc_auc_score, accuracy_score, confusion_matrix\nfrom datetime import datetime","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:11:37.946998Z","iopub.execute_input":"2023-09-07T14:11:37.948467Z","iopub.status.idle":"2023-09-07T14:11:37.955435Z","shell.execute_reply.started":"2023-09-07T14:11:37.948407Z","shell.execute_reply":"2023-09-07T14:11:37.954191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. Preprocess data","metadata":{}},{"cell_type":"code","source":"df_all = pd.read_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/train_series.parquet')","metadata":{"execution":{"iopub.status.busy":"2023-09-07T14:11:37.957563Z","iopub.execute_input":"2023-09-07T14:11:37.958878Z","iopub.status.idle":"2023-09-07T14:12:34.624931Z","shell.execute_reply.started":"2023-09-07T14:11:37.958833Z","shell.execute_reply":"2023-09-07T14:12:34.623579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_events_raw = pd.read_csv('/kaggle/input/child-mind-institute-detect-sleep-states/train_events.csv', dtype={'step': 'Int64', 'night': 'Int64', 'event': 'str'})\ndf_train_events = df_train_events_raw[df_train_events_raw.series_id=='038441c925bb']\ndf_train_events = df_train_events[~df_train_events.step.isna()]\n\n# sample_train_series.csv is data of series_id=='038441c925bb' in train_series.parquet\n# df_train_series = pd.read_csv('sample_train_series.csv')\ndf_train_series = df_all[df_all.series_id=='038441c925bb']\n\ndf = pd.merge(df_train_series, df_train_events, on=['series_id', 'step', 'timestamp'], how='outer')","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:12:34.628042Z","iopub.execute_input":"2023-09-07T14:12:34.628489Z","iopub.status.idle":"2023-09-07T14:12:45.755657Z","shell.execute_reply.started":"2023-09-07T14:12:34.628455Z","shell.execute_reply":"2023-09-07T14:12:45.754404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess(df):\n  df['dow'] = df.timestamp.apply(lambda x: datetime.strptime(x[:10], '%Y-%m-%d').weekday())\n  df['hr'] = df.timestamp.apply(lambda x: int(x[11:13]))\n  df['minute'] = df.timestamp.apply(lambda x: int(x[14:16]))\n  df['sec'] = df.timestamp.apply(lambda x: int(x[17:19]))\n  return df\n\n\ndef create_label(df):\n  df['event_code'] = df.event.apply(lambda x: 0 if isinstance(x, float) else 1 if x=='onset' else -1)\n  df['label'] = df['event_code'].cumsum()\n  return df\n\n\ndef get_df_train_events(series_id):\n  df = df_train_events_raw[df_train_events_raw.series_id==series_id]\n  df = df[~df.step.isna()]\n  return df","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:12:45.757128Z","iopub.execute_input":"2023-09-07T14:12:45.757518Z","iopub.status.idle":"2023-09-07T14:12:45.766587Z","shell.execute_reply.started":"2023-09-07T14:12:45.757486Z","shell.execute_reply":"2023-09-07T14:12:45.765251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = preprocess(df)\ndf = create_label(df)","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:12:45.770365Z","iopub.execute_input":"2023-09-07T14:12:45.770898Z","iopub.status.idle":"2023-09-07T14:12:50.105063Z","shell.execute_reply.started":"2023-09-07T14:12:45.770854Z","shell.execute_reply":"2023-09-07T14:12:50.103874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Train model","metadata":{}},{"cell_type":"code","source":"def evaluate(y, y_hat):\n  acc = accuracy_score(y_true=y, y_pred=y_hat)\n  print(confusion_matrix(y_true=y, y_pred=y_hat))\n  print(f'accuracy: {acc:.3f}')\n\nfeature_cols = ['anglez', 'enmo', 'dow', 'hr', 'minute', 'sec']\nlabel_col = 'label'\nrandom_state = 403\n\ndf_data = df[feature_cols + [label_col]]\ntrain, test = train_test_split(df_data, test_size=0.3, random_state=random_state)\n\ny_train = train.pop(label_col)\nprint(np.sum(y_train) / len(y_train))\nclf = RandomForestClassifier(n_jobs=-1)\nmdl = clf.fit(train, y_train)\n\ny_test = test.pop(label_col)\nprint(np.sum(y_test) / len(y_test))\nprint('=== EVAL TRAINING ===')\nevaluate(y_train, mdl.predict(train))\nprint('=== EVAL TESTING ===')\nevaluate(y_test, mdl.predict(test))","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:12:50.106562Z","iopub.execute_input":"2023-09-07T14:12:50.107256Z","iopub.status.idle":"2023-09-07T14:13:14.026360Z","shell.execute_reply.started":"2023-09-07T14:12:50.107212Z","shell.execute_reply":"2023-09-07T14:13:14.025030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame({'feature_importance': clf.feature_importances_}, index=clf.feature_names_in_).plot(kind='barh')","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:14.027777Z","iopub.execute_input":"2023-09-07T14:13:14.028543Z","iopub.status.idle":"2023-09-07T14:13:14.380558Z","shell.execute_reply.started":"2023-09-07T14:13:14.028502Z","shell.execute_reply":"2023-09-07T14:13:14.379490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = pd.read_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet')\ndf_test = preprocess(df_test)\ndf_test['is_sleep_prob'] = mdl.predict_proba(df_test[feature_cols])[:,1]","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:14.382752Z","iopub.execute_input":"2023-09-07T14:13:14.383250Z","iopub.status.idle":"2023-09-07T14:13:14.448858Z","shell.execute_reply.started":"2023-09-07T14:13:14.383208Z","shell.execute_reply":"2023-09-07T14:13:14.447505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.head()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:14.450515Z","iopub.execute_input":"2023-09-07T14:13:14.451705Z","iopub.status.idle":"2023-09-07T14:13:14.473635Z","shell.execute_reply.started":"2023-09-07T14:13:14.451660Z","shell.execute_reply":"2023-09-07T14:13:14.472422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:14.475301Z","iopub.execute_input":"2023-09-07T14:13:14.476010Z","iopub.status.idle":"2023-09-07T14:13:14.501396Z","shell.execute_reply.started":"2023-09-07T14:13:14.475970Z","shell.execute_reply":"2023-09-07T14:13:14.500217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all.series_id.value_counts()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:14.506301Z","iopub.execute_input":"2023-09-07T14:13:14.506700Z","iopub.status.idle":"2023-09-07T14:13:21.361391Z","shell.execute_reply.started":"2023-09-07T14:13:14.506668Z","shell.execute_reply":"2023-09-07T14:13:21.360177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. Evaluate\n\n- Just simple check with training data to confirm that model can learn.","metadata":{}},{"cell_type":"code","source":"# series_id = '60e51cad2ffb'\nseries_id = '038441c925bb'\ndf_test = pd.merge(df_all[df_all.series_id==series_id], get_df_train_events(series_id), on=['series_id', 'step', 'timestamp'], how='outer')\ndf_test = preprocess(df_test)\ndf_test = create_label(df_test)","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:21.364185Z","iopub.execute_input":"2023-09-07T14:13:21.364643Z","iopub.status.idle":"2023-09-07T14:13:36.274922Z","shell.execute_reply.started":"2023-09-07T14:13:21.364606Z","shell.execute_reply":"2023-09-07T14:13:36.273556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df_test['pred'] = mdl.predict(df_test[feature_cols])\nSCORE_THRES = 0.5\ndf_test['score'] = mdl.predict_proba(df_test[feature_cols])[:,1]\ndf_test['pred'] = (df_test['score'] >= SCORE_THRES).astype(int)\ndf_test['date'] = df_test['timestamp'].apply(lambda x: x[:10])","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:36.276643Z","iopub.execute_input":"2023-09-07T14:13:36.277173Z","iopub.status.idle":"2023-09-07T14:13:37.736446Z","shell.execute_reply.started":"2023-09-07T14:13:36.277125Z","shell.execute_reply":"2023-09-07T14:13:37.735088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.label.mean()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:37.738324Z","iopub.execute_input":"2023-09-07T14:13:37.738787Z","iopub.status.idle":"2023-09-07T14:13:37.747982Z","shell.execute_reply.started":"2023-09-07T14:13:37.738745Z","shell.execute_reply":"2023-09-07T14:13:37.746872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.pred.mean()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:37.749273Z","iopub.execute_input":"2023-09-07T14:13:37.749817Z","iopub.status.idle":"2023-09-07T14:13:37.765623Z","shell.execute_reply.started":"2023-09-07T14:13:37.749785Z","shell.execute_reply":"2023-09-07T14:13:37.764510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import recall_score, precision_score","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:37.768278Z","iopub.execute_input":"2023-09-07T14:13:37.768798Z","iopub.status.idle":"2023-09-07T14:13:37.779490Z","shell.execute_reply.started":"2023-09-07T14:13:37.768754Z","shell.execute_reply":"2023-09-07T14:13:37.778237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix(y_true=df_test[label_col], y_pred=df_test['pred'])","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:37.781129Z","iopub.execute_input":"2023-09-07T14:13:37.781618Z","iopub.status.idle":"2023-09-07T14:13:37.859878Z","shell.execute_reply.started":"2023-09-07T14:13:37.781576Z","shell.execute_reply":"2023-09-07T14:13:37.858714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"recall_score(y_true=df_test[label_col], y_pred=df_test['pred'])","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:37.862289Z","iopub.execute_input":"2023-09-07T14:13:37.862814Z","iopub.status.idle":"2023-09-07T14:13:38.010808Z","shell.execute_reply.started":"2023-09-07T14:13:37.862770Z","shell.execute_reply":"2023-09-07T14:13:38.009577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"precision_score(y_true=df_test[label_col], y_pred=df_test['pred'])","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:38.012167Z","iopub.execute_input":"2023-09-07T14:13:38.012533Z","iopub.status.idle":"2023-09-07T14:13:38.160580Z","shell.execute_reply.started":"2023-09-07T14:13:38.012502Z","shell.execute_reply":"2023-09-07T14:13:38.159423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test_norm = df_test.groupby(['series_id', 'date', 'hr', 'minute']).agg(pred=('pred', 'max'), score=('score', 'max'), step=('step', 'min')).reset_index()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:38.164131Z","iopub.execute_input":"2023-09-07T14:13:38.164524Z","iopub.status.idle":"2023-09-07T14:13:38.285242Z","shell.execute_reply.started":"2023-09-07T14:13:38.164492Z","shell.execute_reply":"2023-09-07T14:13:38.283907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Post-processing for submit","metadata":{}},{"cell_type":"code","source":"MIN_STEP_THRES = 30*60/5\n\ndef create_submission(df):\n  rs = []\n  sleep_flg = False\n  sleep_step_counter = 0\n  set_id = 0\n  for i, r in df.iterrows():\n    if sleep_flg:\n      sleep_step_counter += 1\n    if r.pred==1 and not sleep_flg:\n      sleep_flg = True\n      onset_row = (r['series_id'], r['step'], 'onset', r['score'], set_id)\n    elif r.pred==0 and sleep_flg:\n      sleep_flg = False\n      wakeup_row = (r['series_id'], r['step'], 'wakeup', r['score'], set_id)\n      # print(sleep_step_counter, onset_row, wakeup_row)\n      if sleep_step_counter >= MIN_STEP_THRES:\n        rs.append(onset_row)\n        rs.append(wakeup_row)\n      onset_row = None\n      wakeup_row = None\n      sleep_step_counter = 0\n      set_id += 1\n      \n  if sleep_flg:\n    wakeup_row = (r['series_id'], r['step'], 'wakeup', r['score'], set_id)\n    if sleep_step_counter >= MIN_STEP_THRES:\n      rs.append(onset_row)\n      rs.append(wakeup_row)\n  return pd.DataFrame(rs, columns=['series_id', 'step', 'event', 'score', 'set_id'])","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:38.286801Z","iopub.execute_input":"2023-09-07T14:13:38.287287Z","iopub.status.idle":"2023-09-07T14:13:38.298258Z","shell.execute_reply.started":"2023-09-07T14:13:38.287251Z","shell.execute_reply":"2023-09-07T14:13:38.296770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_submission(df_test_norm)","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:38.299721Z","iopub.execute_input":"2023-09-07T14:13:38.300159Z","iopub.status.idle":"2023-09-07T14:13:40.859533Z","shell.execute_reply.started":"2023-09-07T14:13:38.300125Z","shell.execute_reply":"2023-09-07T14:13:40.858579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_df_train_events(series_id)","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:13:40.860884Z","iopub.execute_input":"2023-09-07T14:13:40.861296Z","iopub.status.idle":"2023-09-07T14:13:40.886404Z","shell.execute_reply.started":"2023-09-07T14:13:40.861262Z","shell.execute_reply":"2023-09-07T14:13:40.884968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots(figsize=(20, 5))\ndf_test_norm.plot(x='step', y='pred', ax=ax)\ndf_true = get_df_train_events(series_id)\ndf_pred = create_submission(df_test_norm)\n\ntrue_sleep_routine = df_true.pivot(index='night', columns='event', values='step').to_dict('records')\nfor r in true_sleep_routine:\n  x1 = r['onset']\n  x2 = r['wakeup']\n  ax.axvspan(x1, x2, color='tab:green', alpha=0.5, label='true')\n  \npred_sleep_routine = df_pred.pivot(index='set_id', columns='event', values='step').to_dict('records')\nfor r in pred_sleep_routine:\n  x1 = r['onset']\n  x2 = r['wakeup']\n  ax.axvspan(x1, x2, color='tab:red', alpha=0.5, label='pred')\n\n# ax.legend()\nplt.show()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:14:03.054711Z","iopub.execute_input":"2023-09-07T14:14:03.055280Z","iopub.status.idle":"2023-09-07T14:14:06.367719Z","shell.execute_reply.started":"2023-09-07T14:14:03.055233Z","shell.execute_reply":"2023-09-07T14:14:06.366596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(df_pred)","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-09-07T14:14:09.499422Z","iopub.execute_input":"2023-09-07T14:14:09.499951Z","iopub.status.idle":"2023-09-07T14:14:09.507893Z","shell.execute_reply.started":"2023-09-07T14:14:09.499907Z","shell.execute_reply":"2023-09-07T14:14:09.506658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(df_true)","metadata":{"execution":{"iopub.status.busy":"2023-09-07T14:14:09.910651Z","iopub.execute_input":"2023-09-07T14:14:09.911213Z","iopub.status.idle":"2023-09-07T14:14:09.920604Z","shell.execute_reply.started":"2023-09-07T14:14:09.911168Z","shell.execute_reply":"2023-09-07T14:14:09.918807Z"},"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"}}