{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"sourceType":"competition"},{"sourceId":12858789,"sourceType":"datasetVersion","datasetId":3261751}],"dockerImageVersionId":31089,"isInternetEnabled":false,"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":"2025-08-25T21:51:25.553305Z","iopub.execute_input":"2025-08-25T21:51:25.553743Z","iopub.status.idle":"2025-08-25T21:51:28.391743Z","shell.execute_reply.started":"2025-08-25T21:51:25.553707Z","shell.execute_reply":"2025-08-25T21:51:28.390633Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install /kaggle/input/offline-sktime/scikit_base-0.12.5-py3-none-any.whl\n!pip install /kaggle/input/offline-sktime/sktime-0.38.5-py3-none-any.whl","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T21:53:27.728376Z","iopub.execute_input":"2025-08-25T21:53:27.728697Z","iopub.status.idle":"2025-08-25T21:53:40.300141Z","shell.execute_reply.started":"2025-08-25T21:53:27.728672Z","shell.execute_reply":"2025-08-25T21:53:40.298793Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# CMI - Shapelets","metadata":{}},{"cell_type":"markdown","source":"The goal of this notebook is trying to identify gestures using shapelets implementation of sktime.","metadata":{}},{"cell_type":"code","source":"from sktime.classification.shapelet_based import ShapeletTransformClassifier\nfrom sklearn.ensemble import RandomForestClassifier\nfrom scipy.stats import randint\nfrom sklearn.model_selection import RandomizedSearchCV, StratifiedKFold\nfrom sklearn.metrics import f1_score\nimport kaggle_evaluation.cmi_inference_server\nfrom datetime import datetime\nimport polars as pl\npd.set_option('display.max_columns', 500)\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T21:53:44.656281Z","iopub.execute_input":"2025-08-25T21:53:44.656620Z","iopub.status.idle":"2025-08-25T21:53:49.167897Z","shell.execute_reply.started":"2025-08-25T21:53:44.656594Z","shell.execute_reply":"2025-08-25T21:53:49.166720Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv(r'/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv')\ntest_df = pd.read_csv(r'/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:28:03.046821Z","iopub.execute_input":"2025-08-24T13:28:03.047666Z","iopub.status.idle":"2025-08-24T13:28:43.147310Z","shell.execute_reply.started":"2025-08-24T13:28:03.047611Z","shell.execute_reply":"2025-08-24T13:28:43.146257Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.shape, test_df.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:28:49.132078Z","iopub.execute_input":"2025-08-24T13:28:49.132473Z","iopub.status.idle":"2025-08-24T13:28:49.140364Z","shell.execute_reply.started":"2025-08-24T13:28:49.132366Z","shell.execute_reply":"2025-08-24T13:28:49.139462Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_pl = pl.read_csv(r'/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv')\ntest_demo_pl = pl.read_csv(r'/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:28:51.347507Z","iopub.execute_input":"2025-08-24T13:28:51.348265Z","iopub.status.idle":"2025-08-24T13:28:51.648536Z","shell.execute_reply.started":"2025-08-24T13:28:51.348201Z","shell.execute_reply":"2025-08-24T13:28:51.647550Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:28:53.796745Z","iopub.execute_input":"2025-08-24T13:28:53.797470Z","iopub.status.idle":"2025-08-24T13:28:54.039183Z","shell.execute_reply.started":"2025-08-24T13:28:53.797443Z","shell.execute_reply":"2025-08-24T13:28:54.038237Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df[['sequence_type','phase','gesture']].drop_duplicates()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:28:58.121524Z","iopub.execute_input":"2025-08-24T13:28:58.121895Z","iopub.status.idle":"2025-08-24T13:28:58.302721Z","shell.execute_reply.started":"2025-08-24T13:28:58.121871Z","shell.execute_reply":"2025-08-24T13:28:58.301962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:02.871824Z","iopub.execute_input":"2025-08-24T13:29:02.874121Z","iopub.status.idle":"2025-08-24T13:29:03.170415Z","shell.execute_reply.started":"2025-08-24T13:29:02.874060Z","shell.execute_reply":"2025-08-24T13:29:03.169402Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:05.732151Z","iopub.execute_input":"2025-08-24T13:29:05.732490Z","iopub.status.idle":"2025-08-24T13:29:05.738539Z","shell.execute_reply.started":"2025-08-24T13:29:05.732465Z","shell.execute_reply":"2025-08-24T13:29:05.737617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for col in [col for col in train_df.columns if col.startswith('tof_')]:\n    train_df[col] = train_df[col].fillna(-2)\n\nfor col in [col for col in train_df.columns if col.startswith('thm_')]:\n    train_df[col] = train_df[col].fillna(-2)\n\nfor col in [col for col in train_df.columns if col.startswith('rot_')]:\n    train_df[col] = train_df[col].fillna(-2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:07.997582Z","iopub.execute_input":"2025-08-24T13:29:07.997932Z","iopub.status.idle":"2025-08-24T13:29:09.804967Z","shell.execute_reply.started":"2025-08-24T13:29:07.997905Z","shell.execute_reply":"2025-08-24T13:29:09.804037Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:10.592006Z","iopub.execute_input":"2025-08-24T13:29:10.592654Z","iopub.status.idle":"2025-08-24T13:29:10.990696Z","shell.execute_reply.started":"2025-08-24T13:29:10.592623Z","shell.execute_reply":"2025-08-24T13:29:10.989758Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tof1 = [col for col in test_df.columns if col.startswith('tof_1')]\ntof2 = [col for col in test_df.columns if col.startswith('tof_2')]\ntof3 = [col for col in test_df.columns if col.startswith('tof_3')]\ntof4 = [col for col in test_df.columns if col.startswith('tof_4')]\ntof5 = [col for col in test_df.columns if col.startswith('tof_5')]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:13.808153Z","iopub.execute_input":"2025-08-24T13:29:13.808739Z","iopub.status.idle":"2025-08-24T13:29:13.815614Z","shell.execute_reply.started":"2025-08-24T13:29:13.808684Z","shell.execute_reply":"2025-08-24T13:29:13.814678Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"d = {'tof1': tof1, 'tof2':tof2, 'tof3':tof3, 'tof4':tof4, 'tof5':tof5}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:16.092671Z","iopub.execute_input":"2025-08-24T13:29:16.093017Z","iopub.status.idle":"2025-08-24T13:29:16.097844Z","shell.execute_reply.started":"2025-08-24T13:29:16.092982Z","shell.execute_reply":"2025-08-24T13:29:16.096832Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for k, col in d.items():\n    test_df[f'Mean_{k}'] = test_df[col].mean(axis = 1)\n    test_df[f'Min_{k}'] = test_df[col].mean(axis = 1)\n    test_df[f'Max_{k}'] = test_df[col].mean(axis = 1)\n\n    train_df[f'Mean_{k}'] = train_df[col].mean(axis = 1)\n    train_df[f'Min_{k}'] = train_df[col].mean(axis = 1)\n    train_df[f'Max_{k}'] = train_df[col].mean(axis = 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:18.056971Z","iopub.execute_input":"2025-08-24T13:29:18.057380Z","iopub.status.idle":"2025-08-24T13:29:28.098743Z","shell.execute_reply.started":"2025-08-24T13:29:18.057352Z","shell.execute_reply":"2025-08-24T13:29:28.097712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:28.100410Z","iopub.execute_input":"2025-08-24T13:29:28.100755Z","iopub.status.idle":"2025-08-24T13:29:28.303466Z","shell.execute_reply.started":"2025-08-24T13:29:28.100724Z","shell.execute_reply":"2025-08-24T13:29:28.302561Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.drop(columns = [col for col in train_df.columns if col.startswith('tof')], axis = 1 , inplace = True)\ntest_df.drop(columns = [col for col in test_df.columns if col.startswith('tof')], axis = 1 , inplace = True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:28.304664Z","iopub.execute_input":"2025-08-24T13:29:28.304929Z","iopub.status.idle":"2025-08-24T13:29:28.489831Z","shell.execute_reply.started":"2025-08-24T13:29:28.304901Z","shell.execute_reply":"2025-08-24T13:29:28.488552Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:28.491931Z","iopub.execute_input":"2025-08-24T13:29:28.492984Z","iopub.status.idle":"2025-08-24T13:29:28.527783Z","shell.execute_reply.started":"2025-08-24T13:29:28.492947Z","shell.execute_reply":"2025-08-24T13:29:28.526098Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:28.528635Z","iopub.execute_input":"2025-08-24T13:29:28.528911Z","iopub.status.idle":"2025-08-24T13:29:28.561961Z","shell.execute_reply.started":"2025-08-24T13:29:28.528880Z","shell.execute_reply":"2025-08-24T13:29:28.560850Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.shape, test_df.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:32.612468Z","iopub.execute_input":"2025-08-24T13:29:32.612774Z","iopub.status.idle":"2025-08-24T13:29:32.618535Z","shell.execute_reply.started":"2025-08-24T13:29:32.612752Z","shell.execute_reply":"2025-08-24T13:29:32.617710Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"total_columns = ['acc_x','acc_y','acc_z',\n                 'rot_x', 'rot_y', 'rot_z', 'rot_w',\n                'thm_1','thm_2','thm_3','thm_4','thm_5',\n                'Mean_tof1','Min_tof1','Max_tof1',\n                 'Mean_tof2','Min_tof2','Max_tof2',\n                 'Mean_tof3','Min_tof3', 'Max_tof3',\n                 'Mean_tof4','Min_tof4', 'Max_tof4',\n                 'Mean_tof5', 'Min_tof5', \t'Max_tof5'] ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:34.556807Z","iopub.execute_input":"2025-08-24T13:29:34.557162Z","iopub.status.idle":"2025-08-24T13:29:34.562621Z","shell.execute_reply.started":"2025-08-24T13:29:34.557137Z","shell.execute_reply":"2025-08-24T13:29:34.561522Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.preprocessing import StandardScaler","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:37.077346Z","iopub.execute_input":"2025-08-24T13:29:37.077667Z","iopub.status.idle":"2025-08-24T13:29:37.082113Z","shell.execute_reply.started":"2025-08-24T13:29:37.077643Z","shell.execute_reply":"2025-08-24T13:29:37.081306Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"scaler = StandardScaler()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:38.766983Z","iopub.execute_input":"2025-08-24T13:29:38.767337Z","iopub.status.idle":"2025-08-24T13:29:38.771722Z","shell.execute_reply.started":"2025-08-24T13:29:38.767314Z","shell.execute_reply":"2025-08-24T13:29:38.770768Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_scaled = pd.DataFrame(scaler.fit_transform(train_df[total_columns]), \n             columns = scaler.get_feature_names_out())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:54.857646Z","iopub.execute_input":"2025-08-24T13:29:54.857945Z","iopub.status.idle":"2025-08-24T13:29:55.468801Z","shell.execute_reply.started":"2025-08-24T13:29:54.857923Z","shell.execute_reply":"2025-08-24T13:29:55.467459Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_scaled = pd.DataFrame(scaler.transform(test_df[total_columns]), \n             columns = scaler.get_feature_names_out())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:29:57.101856Z","iopub.execute_input":"2025-08-24T13:29:57.102186Z","iopub.status.idle":"2025-08-24T13:29:57.110668Z","shell.execute_reply.started":"2025-08-24T13:29:57.102163Z","shell.execute_reply":"2025-08-24T13:29:57.109867Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.drop(total_columns, axis = 1 , inplace = True)\ntest_df.drop(total_columns, axis = 1 , inplace = True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:00.012407Z","iopub.execute_input":"2025-08-24T13:30:00.012717Z","iopub.status.idle":"2025-08-24T13:30:00.077842Z","shell.execute_reply.started":"2025-08-24T13:30:00.012698Z","shell.execute_reply":"2025-08-24T13:30:00.077084Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.shape, train_scaled.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:01.727989Z","iopub.execute_input":"2025-08-24T13:30:01.728385Z","iopub.status.idle":"2025-08-24T13:30:01.734909Z","shell.execute_reply.started":"2025-08-24T13:30:01.728360Z","shell.execute_reply":"2025-08-24T13:30:01.734090Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.concat([train_df.reset_index(drop=True), train_scaled.reset_index(drop=True)],axis = 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:04.497782Z","iopub.execute_input":"2025-08-24T13:30:04.498168Z","iopub.status.idle":"2025-08-24T13:30:04.900493Z","shell.execute_reply.started":"2025-08-24T13:30:04.498141Z","shell.execute_reply":"2025-08-24T13:30:04.899419Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = pd.concat([test_df.reset_index(drop=True), test_scaled.reset_index(drop=True)],axis = 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:07.437552Z","iopub.execute_input":"2025-08-24T13:30:07.438122Z","iopub.status.idle":"2025-08-24T13:30:07.444988Z","shell.execute_reply.started":"2025-08-24T13:30:07.438093Z","shell.execute_reply":"2025-08-24T13:30:07.444081Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:11.171970Z","iopub.execute_input":"2025-08-24T13:30:11.172687Z","iopub.status.idle":"2025-08-24T13:30:11.198388Z","shell.execute_reply.started":"2025-08-24T13:30:11.172654Z","shell.execute_reply":"2025-08-24T13:30:11.197444Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:16.463642Z","iopub.execute_input":"2025-08-24T13:30:16.463993Z","iopub.status.idle":"2025-08-24T13:30:16.490514Z","shell.execute_reply.started":"2025-08-24T13:30:16.463957Z","shell.execute_reply":"2025-08-24T13:30:16.488959Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = train_df.groupby(['sequence_id','sequence_counter','gesture'], as_index = False)[total_columns].mean()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:34.567909Z","iopub.execute_input":"2025-08-24T13:30:34.568352Z","iopub.status.idle":"2025-08-24T13:30:36.484437Z","shell.execute_reply.started":"2025-08-24T13:30:34.568322Z","shell.execute_reply":"2025-08-24T13:30:36.483170Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:36.737560Z","iopub.execute_input":"2025-08-24T13:30:36.738506Z","iopub.status.idle":"2025-08-24T13:30:36.767862Z","shell.execute_reply.started":"2025-08-24T13:30:36.738470Z","shell.execute_reply":"2025-08-24T13:30:36.767077Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seq_target = train_df[['sequence_id','gesture']].drop_duplicates()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:43.987574Z","iopub.execute_input":"2025-08-24T13:30:43.987979Z","iopub.status.idle":"2025-08-24T13:30:44.082590Z","shell.execute_reply.started":"2025-08-24T13:30:43.987934Z","shell.execute_reply":"2025-08-24T13:30:44.081524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = test_df.groupby(['sequence_id','sequence_counter'], as_index = False)[total_columns].mean()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:46.352080Z","iopub.execute_input":"2025-08-24T13:30:46.352481Z","iopub.status.idle":"2025-08-24T13:30:46.362740Z","shell.execute_reply.started":"2025-08-24T13:30:46.352451Z","shell.execute_reply":"2025-08-24T13:30:46.361839Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:48.066864Z","iopub.execute_input":"2025-08-24T13:30:48.067198Z","iopub.status.idle":"2025-08-24T13:30:48.092131Z","shell.execute_reply.started":"2025-08-24T13:30:48.067175Z","shell.execute_reply":"2025-08-24T13:30:48.091109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def resample_sequence(group, target_length):\n    \"\"\"Resample one sequence (all dimensions) to target length.\"\"\"\n    new_time = np.linspace(0, len(group) - 1, target_length)\n    resampled = {\"sequence_id\": group[\"sequence_id\"].iloc[0]}\n    \n    for col in group.columns:\n        if col not in [\"sequence_id\", \"sequence_counter\"]:\n            resampled[col] = np.interp(\n                new_time,\n                np.arange(len(group)),\n                group[col].values\n            )\n    return pd.DataFrame(resampled)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:52.351953Z","iopub.execute_input":"2025-08-24T13:30:52.352300Z","iopub.status.idle":"2025-08-24T13:30:52.358830Z","shell.execute_reply.started":"2025-08-24T13:30:52.352278Z","shell.execute_reply":"2025-08-24T13:30:52.357791Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def make_equal_length(df, target_length=None):\n    \"\"\"Resample all sequences in df to the same length.\"\"\"\n    # If no target length specified, use max length across sequences\n    if target_length is None:\n        target_length = df.groupby(\"sequence_id\").size().max()\n\n    resampled_dfs = []\n    for seq_id, group in df.groupby(\"sequence_id\"):\n        resampled_group = resample_sequence(group.sort_values(\"sequence_counter\"), target_length)\n        resampled_group[\"sequence_counter\"] = np.arange(target_length)\n        resampled_dfs.append(resampled_group)\n    \n    return pd.concat(resampled_dfs, ignore_index=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:30:58.727992Z","iopub.execute_input":"2025-08-24T13:30:58.728329Z","iopub.status.idle":"2025-08-24T13:30:58.734223Z","shell.execute_reply.started":"2025-08-24T13:30:58.728307Z","shell.execute_reply":"2025-08-24T13:30:58.733397Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df_same_lenghts = make_equal_length(train_df[[col for col in train_df.columns if col not in 'gesture']])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:01.407714Z","iopub.execute_input":"2025-08-24T13:31:01.408007Z","iopub.status.idle":"2025-08-24T13:31:24.401016Z","shell.execute_reply.started":"2025-08-24T13:31:01.407987Z","shell.execute_reply":"2025-08-24T13:31:24.400084Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df_same_lenghts.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:24.403088Z","iopub.execute_input":"2025-08-24T13:31:24.403494Z","iopub.status.idle":"2025-08-24T13:31:24.425343Z","shell.execute_reply.started":"2025-08-24T13:31:24.403465Z","shell.execute_reply":"2025-08-24T13:31:24.424574Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = seq_target.merge(train_df_same_lenghts, how = 'left', left_on = 'sequence_id' , right_on = 'sequence_id')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:24.426156Z","iopub.execute_input":"2025-08-24T13:31:24.426431Z","iopub.status.idle":"2025-08-24T13:31:27.091551Z","shell.execute_reply.started":"2025-08-24T13:31:24.426404Z","shell.execute_reply":"2025-08-24T13:31:27.090590Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:27.093376Z","iopub.execute_input":"2025-08-24T13:31:27.093706Z","iopub.status.idle":"2025-08-24T13:31:27.115706Z","shell.execute_reply.started":"2025-08-24T13:31:27.093676Z","shell.execute_reply":"2025-08-24T13:31:27.114783Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def to_sktime_panel(df, label_col=None):\n    \"\"\"Convert long-format DataFrame to sktime multivariate panel format.\"\"\"\n    X_list = []\n    y_list = []\n\n    # Group by sequence (each gesture example)\n    for seq_id, group in df.groupby(\"sequence_id\"):\n        # Drop sequence_id and counter\n        group = group.sort_values(\"sequence_counter\")\n\n        # Collect each dimension as a pandas Series\n        acc_x = pd.Series(group[\"acc_x\"].values)\n        acc_y = pd.Series(group[\"acc_y\"].values)\n        acc_z = pd.Series(group[\"acc_z\"].values)\n        rot_x = pd.Series(group[\"rot_x\"].values)\n        rot_y = pd.Series(group[\"rot_y\"].values)\n        rot_z = pd.Series(group[\"rot_z\"].values)\n        rot_w = pd.Series(group[\"rot_w\"].values)\n        thm_1 = pd.Series(group[\"thm_1\"].values)\n        thm_2 = pd.Series(group[\"thm_2\"].values)\n        thm_3 = pd.Series(group[\"thm_3\"].values)\n        thm_4 = pd.Series(group[\"thm_4\"].values)\n        thm_5 = pd.Series(group[\"thm_5\"].values)\n        Mean_tof1 = pd.Series(group[\"Mean_tof1\"].values)\n        Min_tof1 = pd.Series(group[\"Min_tof1\"].values)\n        Max_tof1 = pd.Series(group[\"Max_tof1\"].values)\n        Mean_tof2 = pd.Series(group[\"Mean_tof2\"].values)\n        Min_tof2 = pd.Series(group[\"Min_tof2\"].values)\n        Max_tof2 = pd.Series(group[\"Max_tof2\"].values)\n        Mean_tof3 = pd.Series(group[\"Mean_tof3\"].values)\n        Min_tof3 = pd.Series(group[\"Min_tof3\"].values)\n        Max_tof3 = pd.Series(group[\"Max_tof3\"].values)\n        Mean_tof4 = pd.Series(group[\"Mean_tof4\"].values)\n        Min_tof4 = pd.Series(group[\"Min_tof4\"].values)\n        Max_tof4 = pd.Series(group[\"Max_tof4\"].values)\n        Mean_tof5 = pd.Series(group[\"Mean_tof5\"].values)\n        Min_tof5 = pd.Series(group[\"Min_tof5\"].values)\n        Max_tof5 = pd.Series(group[\"Max_tof5\"].values)\n\n        # Each row in sktime multivariate panel = [Series_x, Series_y, Series_z]\n        X_list.append([acc_x, acc_y, acc_z,rot_x, rot_y,\n           rot_z, rot_w, thm_1, thm_2, thm_3, thm_4, thm_5,\n           Mean_tof1, Min_tof1, Max_tof1, Mean_tof2, Min_tof2,\n           Max_tof2, Mean_tof3, Min_tof3, Max_tof3, Mean_tof4,\n           Min_tof4, Max_tof4, Mean_tof5, Min_tof5, Max_tof5])\n\n        if label_col is not None:\n            # Take label (same for all rows in a sequence)\n            y_list.append(group[label_col].iloc[0])\n\n    # Convert to nested DataFrame (sktime format: one row per sequence, one col per dimension)\n    X = pd.DataFrame(X_list, columns=['acc_x', 'acc_y', 'acc_z', 'rot_x', 'rot_y',\n       'rot_z', 'rot_w', 'thm_1', 'thm_2', 'thm_3', 'thm_4', 'thm_5',\n       'Mean_tof1', 'Min_tof1', 'Max_tof1', 'Mean_tof2', 'Min_tof2',\n       'Max_tof2', 'Mean_tof3', 'Min_tof3', 'Max_tof3', 'Mean_tof4',\n       'Min_tof4', 'Max_tof4', 'Mean_tof5', 'Min_tof5', 'Max_tof5'])\n\n    if label_col is not None:\n        y = pd.Series(y_list)\n        return X, y\n    else:\n        return X","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:30.062260Z","iopub.execute_input":"2025-08-24T13:31:30.062544Z","iopub.status.idle":"2025-08-24T13:31:30.074750Z","shell.execute_reply.started":"2025-08-24T13:31:30.062525Z","shell.execute_reply":"2025-08-24T13:31:30.073504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X,y = to_sktime_panel(train_df,'gesture')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:34.572454Z","iopub.execute_input":"2025-08-24T13:31:34.572746Z","iopub.status.idle":"2025-08-24T13:31:56.727625Z","shell.execute_reply.started":"2025-08-24T13:31:34.572726Z","shell.execute_reply":"2025-08-24T13:31:56.726774Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:56.728760Z","iopub.execute_input":"2025-08-24T13:31:56.729046Z","iopub.status.idle":"2025-08-24T13:31:57.086123Z","shell.execute_reply.started":"2025-08-24T13:31:56.729010Z","shell.execute_reply":"2025-08-24T13:31:57.085103Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-24T13:31:57.087228Z","iopub.execute_input":"2025-08-24T13:31:57.087533Z","iopub.status.idle":"2025-08-24T13:31:57.094460Z","shell.execute_reply.started":"2025-08-24T13:31:57.087512Z","shell.execute_reply":"2025-08-24T13:31:57.093456Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = ShapeletTransformClassifier(\n    n_shapelet_samples=500,  # number of candidate shapelets to search\n    max_shapelets=360,       # number of shapelets kept\n    random_state=42,\n    #estimator = RandomForestClassifier(n_estimators=200, random_state=42),\n    time_limit_in_minutes = 100\n)","metadata":{"execution":{"iopub.status.busy":"2025-08-19T21:23:14.550504Z","iopub.execute_input":"2025-08-19T21:23:14.550847Z","iopub.status.idle":"2025-08-19T21:23:14.556672Z","shell.execute_reply.started":"2025-08-19T21:23:14.550822Z","shell.execute_reply":"2025-08-19T21:23:14.555751Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"datetime.now()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:23:20.942923Z","iopub.execute_input":"2025-08-19T21:23:20.943245Z","iopub.status.idle":"2025-08-19T21:23:20.949307Z","shell.execute_reply.started":"2025-08-19T21:23:20.943220Z","shell.execute_reply":"2025-08-19T21:23:20.948474Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.fit(X, y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:23:35.043067Z","iopub.execute_input":"2025-08-19T21:23:35.043443Z","iopub.status.idle":"2025-08-19T21:26:52.261780Z","shell.execute_reply.started":"2025-08-19T21:23:35.043392Z","shell.execute_reply":"2025-08-19T21:26:52.260792Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"datetime.now()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:26:52.263066Z","iopub.execute_input":"2025-08-19T21:26:52.263485Z","iopub.status.idle":"2025-08-19T21:26:52.269643Z","shell.execute_reply.started":"2025-08-19T21:26:52.263450Z","shell.execute_reply":"2025-08-19T21:26:52.268782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pickle\nfrom pathlib import Path","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-20T20:47:17.648826Z","iopub.execute_input":"2025-08-20T20:47:17.649612Z","iopub.status.idle":"2025-08-20T20:47:17.653942Z","shell.execute_reply.started":"2025-08-20T20:47:17.649580Z","shell.execute_reply":"2025-08-20T20:47:17.653001Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"out_path = Path(\"/kaggle/working/shapelet_model.pkl\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-20T20:47:20.167356Z","iopub.execute_input":"2025-08-20T20:47:20.167648Z","iopub.status.idle":"2025-08-20T20:47:20.172315Z","shell.execute_reply.started":"2025-08-20T20:47:20.167624Z","shell.execute_reply":"2025-08-20T20:47:20.171439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"out_path = Path(\"/kaggle/working/shapelet_model.pkl\")\nwith open(out_path, \"wb\") as f:\n    pickle.dump(model, f)\n\nprint(\"Saved:\", out_path)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target_length = train_df.groupby(\"sequence_id\").size().max()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:27:11.372001Z","iopub.execute_input":"2025-08-19T21:27:11.372727Z","iopub.status.idle":"2025-08-19T21:27:11.440473Z","shell.execute_reply.started":"2025-08-19T21:27:11.372698Z","shell.execute_reply":"2025-08-19T21:27:11.439451Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target_length","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:27:14.035374Z","iopub.execute_input":"2025-08-19T21:27:14.035806Z","iopub.status.idle":"2025-08-19T21:27:14.042678Z","shell.execute_reply.started":"2025-08-19T21:27:14.035773Z","shell.execute_reply":"2025-08-19T21:27:14.041479Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df_same_lenghts = make_equal_length(test_df,target_length)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:27:21.608489Z","iopub.execute_input":"2025-08-19T21:27:21.609116Z","iopub.status.idle":"2025-08-19T21:27:21.622654Z","shell.execute_reply.started":"2025-08-19T21:27:21.609088Z","shell.execute_reply":"2025-08-19T21:27:21.621798Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = to_sktime_panel(test_df_same_lenghts, label_col=None)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:27:26.676542Z","iopub.execute_input":"2025-08-19T21:27:26.676865Z","iopub.status.idle":"2025-08-19T21:27:26.689296Z","shell.execute_reply.started":"2025-08-19T21:27:26.676842Z","shell.execute_reply":"2025-08-19T21:27:26.688302Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:27:28.755294Z","iopub.execute_input":"2025-08-19T21:27:28.755633Z","iopub.status.idle":"2025-08-19T21:27:28.844610Z","shell.execute_reply.started":"2025-08-19T21:27:28.755608Z","shell.execute_reply":"2025-08-19T21:27:28.843572Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n    try:\n        test_df = sequence.to_pandas()\n        demographics_df = demographics.to_pandas()\n        for col in [col for col in test_df.columns if col.startswith('tof_')]:\n            test_df[col] = test_df[col].fillna(-2)\n        for col in [col for col in test_df.columns if col.startswith('thm_')]:\n            test_df[col] = test_df[col].fillna(-2)\n        for col in [col for col in test_df.columns if col.startswith('rot_')]:\n            test_df[col] = test_df[col].fillna(-2)    \n        tof1 = [col for col in test_df.columns if col.startswith('tof_1')]\n        tof2 = [col for col in test_df.columns if col.startswith('tof_2')]\n        tof3 = [col for col in test_df.columns if col.startswith('tof_3')]\n        tof4 = [col for col in test_df.columns if col.startswith('tof_4')]\n        tof5 = [col for col in test_df.columns if col.startswith('tof_5')]\n        d = {'tof1': tof1, 'tof2':tof2, 'tof3':tof3, 'tof4':tof4, 'tof5':tof5}\n        for k, col in d.items():\n            test_df[f'Mean_{k}'] = test_df[col].mean(axis = 1)\n            test_df[f'Min_{k}'] = test_df[col].mean(axis = 1)\n            test_df[f'Max_{k}'] = test_df[col].mean(axis = 1)\n        test_df.drop(columns = [col for col in test_df.columns if col.startswith('tof')], axis = 1 , inplace = True)\n        total_columns = ['acc_x','acc_y','acc_z',\n                 'rot_x', 'rot_y', 'rot_z', 'rot_w',\n                'thm_1','thm_2','thm_3','thm_4','thm_5',\n                'Mean_tof1','Min_tof1','Max_tof1',\n                 'Mean_tof2','Min_tof2','Max_tof2',\n                 'Mean_tof3','Min_tof3', 'Max_tof3',\n                 'Mean_tof4','Min_tof4', 'Max_tof4',\n                 'Mean_tof5', 'Min_tof5', \t'Max_tof5']\n        test_scaled = pd.DataFrame(scaler.transform(test_df[total_columns]), \n             columns = scaler.get_feature_names_out())\n        test_df.drop(total_columns, axis = 1 , inplace = True)\n        test_df = pd.concat([test_df.reset_index(drop=True), test_scaled.reset_index(drop=True)],axis = 1)\n        test_df = test_df.groupby(['sequence_id','sequence_counter'], as_index = False)[total_columns].mean()\n        test_df_same_lenghts = make_equal_length(test_df,71 )\n        test_df = to_sktime_panel(test_df_same_lenghts, label_col=None)\n        return str(model.predict(test_df)[0])\n    except Exception as e:\n        print(f'Error in prediction: {e}')\n        return 'Forehead - pull hairline'   ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:35:10.022844Z","iopub.execute_input":"2025-08-19T21:35:10.023213Z","iopub.status.idle":"2025-08-19T21:35:10.036694Z","shell.execute_reply.started":"2025-08-19T21:35:10.023186Z","shell.execute_reply":"2025-08-19T21:35:10.035625Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict(test_pl,test_demo_pl)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:35:55.842564Z","iopub.execute_input":"2025-08-19T21:35:55.843234Z","iopub.status.idle":"2025-08-19T21:35:56.113052Z","shell.execute_reply.started":"2025-08-19T21:35:55.843204Z","shell.execute_reply":"2025-08-19T21:35:56.112087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inference_server = kaggle_evaluation.cmi_inference_server.CMIInferenceServer(predict)\n\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway(\n        data_paths=(\n            '/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv',\n            '/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv',\n        )\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:36:07.020726Z","iopub.execute_input":"2025-08-19T21:36:07.021027Z","iopub.status.idle":"2025-08-19T21:36:08.578820Z","shell.execute_reply.started":"2025-08-19T21:36:07.021007Z","shell.execute_reply":"2025-08-19T21:36:08.577909Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd.read_parquet(r'/kaggle/working/submission.parquet')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T21:36:11.849645Z","iopub.execute_input":"2025-08-19T21:36:11.849985Z","iopub.status.idle":"2025-08-19T21:36:12.015884Z","shell.execute_reply.started":"2025-08-19T21:36:11.849958Z","shell.execute_reply":"2025-08-19T21:36:12.015133Z"}},"outputs":[],"execution_count":null}]}