{"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,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":254124796,"sourceType":"kernelVersion"}],"dockerImageVersionId":31089,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-08-04T10:22:00.234727Z","iopub.execute_input":"2025-08-04T10:22:00.235082Z","iopub.status.idle":"2025-08-04T10:22:00.245869Z","shell.execute_reply.started":"2025-08-04T10:22:00.235057Z","shell.execute_reply":"2025-08-04T10:22:00.244776Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import polars as pl\nfrom sklearn.preprocessing import LabelEncoder\n\ntrain_df = pl.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv')\nGESTURE_LABELS = train_df[\"gesture\"].unique().sort().to_numpy()\n\nle = LabelEncoder()\nle.fit(GESTURE_LABELS)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-04T10:14:55.619145Z","iopub.execute_input":"2025-08-04T10:14:55.619440Z","iopub.status.idle":"2025-08-04T10:15:09.898149Z","shell.execute_reply.started":"2025-08-04T10:14:55.619414Z","shell.execute_reply":"2025-08-04T10:15:09.897148Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\n\ndef data_process(sequence_df, demo_df):\n    exclude_cols = {\"row_id\", \"sequence_type\", \"sequence_id\", \"sequence_counter\", \"subject\", \"orientation\", \"behavior\", \"phase\", \"gesture\", \"gesture_id\"}\n    value_cols = [col for col in sequence_df.columns if col not in exclude_cols]\n\n    features = []\n    for seq_id, group in tqdm(sequence_df.group_by(\"sequence_id\")):\n        for col in value_cols:\n            if group.select(pl.col(col).is_null().all()).to_numpy()[0][0]:\n                group = group.with_columns(pl.lit(0).alias(col))\n            else:\n                mean_val = group.select(pl.col(col).mean()).to_numpy()[0][0]\n                group = group.with_columns(pl.col(col).fill_null(mean_val).alias(col))\n\n        if group[\"subject\"].n_unique() > 1:\n            print(\"Warning: Duplicate `gesture` detected! The same `sequence_id` cannot have multiple `gesture`.\")\n        \n        subject = group[\"subject\"].first()\n        row = {\n            \"sequence_id\": seq_id[0],\n            \"subject\": subject\n        }\n        for col in value_cols:\n            values = group[col].to_numpy()\n            row[f\"{col}_mean\"] = values.mean()\n            row[f\"{col}_std\"] = values.std()\n            row[f\"{col}_min\"] = values.min()\n            row[f\"{col}_max\"] = values.max()\n            row[f\"{col}_median\"] = np.median(values)\n            row[f\"{col}_q25\"] = np.percentile(values, 25)\n            row[f\"{col}_q75\"] = np.percentile(values, 75)\n\n        features.append(row)\n\n    feature_df = pd.DataFrame(features)\n\n    for col in [\"age\", \"height_cm\", \"shoulder_to_wrist_cm\", \"elbow_to_wrist_cm\"]:\n        fill_val = 0\n        if not demo_df.select(pl.col(col).is_null().all()).to_numpy()[0][0]:\n            fill_val = demo_df.select(pl.col(col).median()).to_numpy()[0][0]\n        demo_df = demo_df.with_columns(\n            pl.col(col).fill_null(fill_val)\n        )\n\n    for col in [\"adult_child\", \"sex\", \"handedness\"]:\n        fill_val = 0\n        if not demo_df.select(pl.col(col).is_null().all()).to_numpy()[0][0]:\n            modes = demo_df.select(pl.col(col).mode()).to_series()\n            if modes.is_empty() or modes[0] is None:\n                fill_val = 0\n            else:\n                fill_val = modes[0]\n        demo_df = demo_df.with_columns(\n            pl.col(col).fill_null(fill_val)\n        )\n    \n    demo_df = demo_df.to_pandas()\n    \n    return feature_df.merge(demo_df, on=\"subject\", how=\"left\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-04T10:15:09.899268Z","iopub.execute_input":"2025-08-04T10:15:09.899737Z","iopub.status.idle":"2025-08-04T10:15:10.259637Z","shell.execute_reply.started":"2025-08-04T10:15:09.899657Z","shell.execute_reply":"2025-08-04T10:15:10.258750Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pickle\n\nwith open('/kaggle/input/cmi25-randomforestclassifier-pretrain/random_forest_model.pkl', 'rb') as f:\n    model = pickle.load(f)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-04T10:22:30.656003Z","iopub.execute_input":"2025-08-04T10:22:30.656316Z","iopub.status.idle":"2025-08-04T10:22:32.853547Z","shell.execute_reply.started":"2025-08-04T10:22:30.656293Z","shell.execute_reply":"2025-08-04T10:22:32.852437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n    process = data_process(sequence, demographics)\n    X_test = process.drop([\"sequence_id\", \"subject\"], axis=1)\n    preds = model.predict(X_test)\n    return le.classes_[preds][0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-04T10:22:35.328951Z","iopub.execute_input":"2025-08-04T10:22:35.329278Z","iopub.status.idle":"2025-08-04T10:22:35.334522Z","shell.execute_reply.started":"2025-08-04T10:22:35.329253Z","shell.execute_reply":"2025-08-04T10:22:35.333460Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import kaggle_evaluation.cmi_inference_server\n\ninference_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-04T10:22:37.160063Z","iopub.execute_input":"2025-08-04T10:22:37.160383Z","iopub.status.idle":"2025-08-04T10:22:38.657552Z","shell.execute_reply.started":"2025-08-04T10:22:37.160326Z","shell.execute_reply":"2025-08-04T10:22:38.656411Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if not os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    print(pd.read_parquet(\"submission.parquet\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-04T10:22:40.030863Z","iopub.execute_input":"2025-08-04T10:22:40.031179Z","iopub.status.idle":"2025-08-04T10:22:40.171469Z","shell.execute_reply.started":"2025-08-04T10:22:40.031155Z","shell.execute_reply":"2025-08-04T10:22:40.170630Z"}},"outputs":[],"execution_count":null}]}