{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":82611,"databundleVersionId":9553358,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:44:47.765852Z","iopub.execute_input":"2024-12-04T08:44:47.766231Z","iopub.status.idle":"2024-12-04T08:44:49.118259Z","shell.execute_reply.started":"2024-12-04T08:44:47.766194Z","shell.execute_reply":"2024-12-04T08:44:49.117084Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! pip install feature_engine","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:44:49.120393Z","iopub.execute_input":"2024-12-04T08:44:49.120835Z","iopub.status.idle":"2024-12-04T08:45:07.512542Z","shell.execute_reply.started":"2024-12-04T08:44:49.120802Z","shell.execute_reply":"2024-12-04T08:45:07.511111Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\nimport datetime\nfrom tqdm import tqdm\n\nfrom feature_engine.timeseries.forecasting import LagFeatures\n\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")\n\n\ntrain = pd.read_csv(\"/kaggle/input/brist1d/train.csv\").rename(columns={\"bg+1:00\": \"bg_1h\"})\ntest = pd.read_csv(\"/kaggle/input/brist1d/test.csv\").assign(bg_1h=np.nan)\n\n\nsplit = \"train\"\npnum = \"p01\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:07.514243Z","iopub.execute_input":"2024-12-04T08:45:07.514623Z","iopub.status.idle":"2024-12-04T08:45:22.887505Z","shell.execute_reply.started":"2024-12-04T08:45:07.514586Z","shell.execute_reply":"2024-12-04T08:45:22.886348Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"activity_mapper = {\n    \"Aerobic Workout\": 1,\n    \"CoreTraining\": 1,\n    \"HIIT\": 1,\n    \"Indoor climbing\": 1,\n    \"Sport\": 1,\n    \"Stairclimber\": 1,\n    \"Strength training\": 1,\n    \"Workout\": 1,\n    \"Weights\": 1,\n    \"Bike\": 2,\n    \"Cycling\": 2,\n    \"Outdoor Bike\": 2,\n    \"Spinning\": 2,\n    \"Dancing\": 3,\n    \"Zumba\": 3,\n    \"Hike\": 4,\n    \"Walk\": 4,\n    \"Walking\": 4,\n    \"Run\": 5,\n    \"Running\": 5,\n    \"Swim\": 6,\n    \"Swimming\": 6,\n    \"Tennis\": 7,\n    \"Yoga\": 8,\n}\n\n\nfreqs_list = [\n    \"5min\",\n    \"10min\",\n    \"15min\",\n    \"20min\",\n    \"25min\",\n    \"30min\",\n    \"35min\",\n    \"40min\",\n    \"45min\",\n    \"50min\",\n    \"55min\",\n    \"1h\",\n    \"1h30min\",\n    \"2h\",\n    \"2h30min\",\n    \"3h\",\n    \"3h30min\",\n    \"4h\",\n    \"4h30min\",\n    \"5h\",\n    \"5h30min\",\n    \"6h\",\n]\n\nvariables = [\n    \"bg\",\n    \"insulin\",\n    \"carbs\",\n    \"hr\",\n    \"steps\",\n    \"cals\",\n    \"activity_bn\",\n    \"carbs_bn\",\n    \"steps_bn\",\n    \"cals_bn\",\n]\n\nbase_datetime = datetime.datetime(2024, 1, 1)\n\n\ndef preprocess_test(df):\n    return df.assign(\n        ranker=lambda df_: df_.groupby([\"p_num\"]).cumcount() + 1,\n        day_of_year=lambda df_: df_.ranker * 2,\n        date_str=lambda df_: df_.day_of_year.apply(\n            lambda x: base_datetime + datetime.timedelta(x - 1)\n        ).astype(str)\n        + \" \"\n        + df_.time,\n        time=lambda df_: pd.to_datetime(df_.date_str, format=\"%Y-%m-%d %H:%M:%S\"),\n    ).drop([\"date_str\", \"day_of_year\", \"ranker\"], axis=1)\n\n\ndef preprocess_train(df):\n    return (\n        df.assign(rank=lambda df_: df_.id.apply(lambda x: x.split(\"_\")[1]).astype(int))\n        .sort_values([\"rank\", \"time\"])\n        .assign(\n            hour=lambda df_: df_.time.apply(lambda x: x[:2]).astype(int),\n            hour_lag=lambda df_: df_.hour.astype(int).shift(1),\n            day_of_year=lambda df_: (df_.hour.astype(int) - df_.hour_lag < 0)\n            .astype(int)\n            .cumsum()\n            + 1,\n        )\n        .assign(\n            date_str=lambda df_: df_.day_of_year.apply(\n                lambda x: base_datetime + datetime.timedelta(x - 1)\n            ).astype(str)\n            + \" \"\n            + df_.time,\n            time=lambda df_: pd.to_datetime(df_.date_str, format=\"%Y-%m-%d %H:%M:%S\"),\n        )\n        .drop([\"date_str\", \"hour_lag\", \"hour\", \"rank\", \"day_of_year\"], axis=1)\n    )\n\n\ndef formate_time(df):\n    df[\"hour\"] = df.time.dt.hour\n    df[\"minute\"] = df.time.dt.minute\n    df[\"hour_sin\"] = np.sin(2 * np.pi * df[\"hour\"] / 24)\n    df[\"hour_cos\"] = np.cos(2 * np.pi * df[\"hour\"] / 24)\n    df[\"minute_sin\"] = np.sin(2 * np.pi * df[\"minute\"] / 60)\n    df[\"minute_cos\"] = np.cos(2 * np.pi * df[\"minute\"] / 60)\n    return df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:22.890342Z","iopub.execute_input":"2024-12-04T08:45:22.890820Z","iopub.status.idle":"2024-12-04T08:45:22.908209Z","shell.execute_reply.started":"2024-12-04T08:45:22.890770Z","shell.execute_reply":"2024-12-04T08:45:22.906810Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if split == \"train\":\n    df = train\nelse:\n    df = test\n\ntimes = (\n    pd.Series(\n        df.columns[df.columns.str.contains(\"-\")].tolist(),\n        name=\"column_names\",\n    )\n    .to_frame()\n    .assign(time=lambda df_: df_.column_names.apply(lambda x: x.split(\"-\")[1]))\n    .time.sort_values()\n    .unique()\n    .tolist()\n)\n\nif split == \"train\":\n    df_time = df.query(f\"p_num == @pnum\").pipe(preprocess_train)\nelse:\n    df_time = df.query(f\"p_num == @pnum\").pipe(preprocess_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:22.909524Z","iopub.execute_input":"2024-12-04T08:45:22.909921Z","iopub.status.idle":"2024-12-04T08:45:23.275670Z","shell.execute_reply.started":"2024-12-04T08:45:22.909888Z","shell.execute_reply":"2024-12-04T08:45:23.274668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_processed = pd.DataFrame()\n\nfor time in times:\n    time_cols = df_time.columns[df_time.columns.str.contains(time)].tolist()\n\n    hour = int(time.split(\":\")[0])\n    minute = int(time.split(\":\")[1])\n\n    df_processed_part = df_time[[\"time\", \"id\", \"p_num\", *time_cols]].assign(\n        time=lambda df_: df_.time\n        - pd.Timedelta(hours=hour)\n        - pd.Timedelta(minutes=minute)\n    )\n\n    df_processed_part_renamed = df_processed_part.rename(\n        columns=dict(\n            zip(\n                time_cols,\n                [\n                    \"bg\",\n                    \"insulin\",\n                    \"carbs\",\n                    \"hr\",\n                    \"steps\",\n                    \"cals\",\n                    \"activity\",\n                ],\n            )\n        )\n    )\n    df_processed = pd.concat([df_processed, df_processed_part_renamed], axis=0)\n\ndf_processed = df_processed.drop_duplicates(\n    subset=[\"time\", \"bg\"],\n).merge(\n    df_time[[\"time\", \"bg_1h\"]].rename(columns={\"bg_1h\": \"bg_1h_raw\"}),\n    how=\"left\",\n    left_on=\"time\",\n    right_on=\"time\",\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:23.277095Z","iopub.execute_input":"2024-12-04T08:45:23.277431Z","iopub.status.idle":"2024-12-04T08:45:24.388858Z","shell.execute_reply.started":"2024-12-04T08:45:23.277399Z","shell.execute_reply":"2024-12-04T08:45:24.387816Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_processed = (\n    df_processed.drop_duplicates(\n        subset=[\"time\"],\n    )\n    .pipe(formate_time)\n    .assign(\n        activity_encoded=lambda df_: df_.activity.map(activity_mapper),\n        activity_bn=lambda df_: np.where(df_.activity.notna(), 1, np.nan),\n        carbs_bn=lambda df_: np.where(df_.carbs.notna(), 1, np.nan),\n        steps_bn=lambda df_: np.where(df_.steps.notna(), 1, np.nan),\n        cals_bn=lambda df_: np.where(df_.cals.notna(), 1, np.nan),\n    )\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:24.390085Z","iopub.execute_input":"2024-12-04T08:45:24.390395Z","iopub.status.idle":"2024-12-04T08:45:24.425074Z","shell.execute_reply.started":"2024-12-04T08:45:24.390364Z","shell.execute_reply":"2024-12-04T08:45:24.423915Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_norm_const = pd.DataFrame()\n\nfor col in [\"bg\", \"insulin\", \"carbs\", \"hr\", \"steps\", \"cals\"]:\n    df_norm_const_part = (\n        df_processed.groupby([\"hour\"])\n        .agg({col: [\"min\", \"max\", \"std\", \"mean\"]})\n        .droplevel(level=0, axis=1)\n        .rename(\n            columns=dict(\n                zip(\n                    [\"min\", \"max\", \"std\", \"mean\"],\n                    [f\"{col}_{stat}\" for stat in [\"min\", \"max\", \"std\", \"mean\"]],\n                )\n            )\n        )\n    )\n\n    if df_norm_const.empty:\n        df_norm_const = df_norm_const_part\n    else:\n        df_norm_const = df_norm_const.join(df_norm_const_part, how=\"left\")\n\ndf_processed = df_processed.merge(\n    df_norm_const.reset_index(),\n    how=\"left\",\n    left_on=[\"hour\"],\n    right_on=[\"hour\"],\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:24.426673Z","iopub.execute_input":"2024-12-04T08:45:24.427032Z","iopub.status.idle":"2024-12-04T08:45:24.479483Z","shell.execute_reply.started":"2024-12-04T08:45:24.426971Z","shell.execute_reply":"2024-12-04T08:45:24.478422Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"lag_f = LagFeatures(\n    variables=variables,\n    freq=freqs_list,\n)\ndf_processed_part = df_processed.fillna(-9999).set_index([\"time\"]).sort_index()\n\ndf_processed_lags = lag_f.fit_transform(df_processed_part).replace(-9999, np.nan)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:24.480895Z","iopub.execute_input":"2024-12-04T08:45:24.481913Z","iopub.status.idle":"2024-12-04T08:45:24.741551Z","shell.execute_reply.started":"2024-12-04T08:45:24.481862Z","shell.execute_reply":"2024-12-04T08:45:24.740537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for var in tqdm(variables):\n    for i, last_freq in enumerate(freqs_list):\n        cols_to_agg = [f\"{var}_lag_{freq}\" for freq in np.array(freqs_list)[:i]]\n        cols_to_agg.append(var)\n        df_processed_lags[f\"{var}_rolling_mean_{last_freq}\"] = df_processed_lags[\n            cols_to_agg\n        ].mean(axis=1)\n        df_processed_lags[f\"{col}_rolling_std_{last_freq}\"] = df_processed_lags[\n            cols_to_agg\n        ].std(axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:24.744930Z","iopub.execute_input":"2024-12-04T08:45:24.745422Z","iopub.status.idle":"2024-12-04T08:45:29.356983Z","shell.execute_reply.started":"2024-12-04T08:45:24.745374Z","shell.execute_reply":"2024-12-04T08:45:29.355925Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_processed","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T08:45:29.358510Z","iopub.execute_input":"2024-12-04T08:45:29.358942Z","iopub.status.idle":"2024-12-04T08:45:29.402236Z","shell.execute_reply.started":"2024-12-04T08:45:29.358894Z","shell.execute_reply":"2024-12-04T08:45:29.400920Z"}},"outputs":[],"execution_count":null}]}