{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","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"}],"dockerImageVersionId":31040,"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)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:23:44.372143Z","iopub.execute_input":"2025-06-07T14:23:44.372571Z","iopub.status.idle":"2025-06-07T14:23:44.377820Z","shell.execute_reply.started":"2025-06-07T14:23:44.372536Z","shell.execute_reply":"2025-06-07T14:23:44.376682Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_path = \"/kaggle/input/cmi-detect-behavior-with-sensor-data\"\n\ntrain = pd.read_csv(f\"{base_path}/train.csv\")\ntrain_demo = pd.read_csv(f\"{base_path}/train_demographics.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:23:44.379467Z","iopub.execute_input":"2025-06-07T14:23:44.379788Z","iopub.status.idle":"2025-06-07T14:24:07.565752Z","shell.execute_reply.started":"2025-06-07T14:23:44.379761Z","shell.execute_reply":"2025-06-07T14:24:07.564792Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Display basic information\nprint(\"Train Shape:\", train.shape)\nprint(\"Train Demographics Shape:\", train_demo.shape)\nprint(train.info())\nprint(train_demo.info())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:24:07.566831Z","iopub.execute_input":"2025-06-07T14:24:07.567106Z","iopub.status.idle":"2025-06-07T14:24:07.595334Z","shell.execute_reply.started":"2025-06-07T14:24:07.567087Z","shell.execute_reply":"2025-06-07T14:24:07.593635Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Unique values in key columns\nprint(\"Unique gestures:\", train['gesture'].unique())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:24:07.596442Z","iopub.execute_input":"2025-06-07T14:24:07.596913Z","iopub.status.idle":"2025-06-07T14:24:07.639098Z","shell.execute_reply.started":"2025-06-07T14:24:07.596880Z","shell.execute_reply":"2025-06-07T14:24:07.638044Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Unique behaviors:\", train['behavior'].unique())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:24:07.641279Z","iopub.execute_input":"2025-06-07T14:24:07.641542Z","iopub.status.idle":"2025-06-07T14:24:07.685658Z","shell.execute_reply.started":"2025-06-07T14:24:07.641522Z","shell.execute_reply":"2025-06-07T14:24:07.684748Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Unique orientations:\", train['orientation'].unique())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:24:07.686566Z","iopub.execute_input":"2025-06-07T14:24:07.686908Z","iopub.status.idle":"2025-06-07T14:24:07.729851Z","shell.execute_reply.started":"2025-06-07T14:24:07.686882Z","shell.execute_reply":"2025-06-07T14:24:07.728919Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Select a sequence\nexample_seq_id = train['sequence_id'].unique()[0]\nexample_seq = train[train['sequence_id'] == example_seq_id]\n\n# Plot accelerometer data\nplt.plot(example_seq['sequence_counter'], example_seq['acc_x'], label='acc_x')\nplt.plot(example_seq['sequence_counter'], example_seq['acc_y'], label='acc_y')\nplt.plot(example_seq['sequence_counter'], example_seq['acc_z'], label='acc_z')\nplt.title(f\"Accelerometer Data for Sequence {example_seq_id}\")\nplt.xlabel(\"Sequence Step\")\nplt.ylabel(\"Acceleration (m/s^2)\")\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:24:07.730745Z","iopub.execute_input":"2025-06-07T14:24:07.730983Z","iopub.status.idle":"2025-06-07T14:24:08.017697Z","shell.execute_reply.started":"2025-06-07T14:24:07.730965Z","shell.execute_reply":"2025-06-07T14:24:08.016846Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import seaborn as sns\n\n# Identify ToF columns\ntof_cols = [col for col in train.columns if col.startswith('tof_')]\n\n# Calculate percentage of missing values\nmissing_tof = (train[tof_cols] == -1).mean().sort_values(ascending=False) * 100\n\n# Plot missing data\nmissing_tof.head(30).plot(kind='bar', title=\"Top ToF Pixels with Missing Signals (-1)\")\nplt.ylabel(\"% Missing\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:28:09.895831Z","iopub.execute_input":"2025-06-07T14:28:09.896192Z","iopub.status.idle":"2025-06-07T14:28:12.588589Z","shell.execute_reply.started":"2025-06-07T14:28:09.896164Z","shell.execute_reply":"2025-06-07T14:28:12.587681Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.manifold import TSNE\nfrom sklearn.decomposition import PCA\nimport umap\nfrom sklearn.preprocessing import StandardScaler\n\n# Aggregate features per sequence\nagg_features = train.groupby(\"sequence_id\").agg({\n    'acc_x': 'mean',\n    'acc_y': 'mean',\n    'acc_z': 'mean',\n    'rot_x': 'mean',\n    'rot_y': 'mean',\n    'rot_z': 'mean',\n    'thm_1': 'mean',\n    'thm_2': 'mean',\n    'thm_3': 'mean',\n    'thm_4': 'mean',\n    'thm_5': 'mean'\n}).reset_index()\n\n# Add gesture labels\ngesture_labels = train.groupby(\"sequence_id\")[\"gesture\"].first().reset_index()\nagg_features = agg_features.merge(gesture_labels, on=\"sequence_id\")\n\n# Drop rows with any NaN values\nagg_features_clean = agg_features.dropna()\n\n# Dimensionality reduction with UMAP\nreducer = umap.UMAP(n_neighbors=15, min_dist=0.1, random_state=42)\nembedding_umap = reducer.fit_transform(agg_features_clean.drop([\"sequence_id\", \"gesture\"], axis=1))\n\n# Plotting\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nplt.figure(figsize=(10, 6))\nsns.scatterplot(\n    x=embedding_umap[:, 0],\n    y=embedding_umap[:, 1],\n    hue=agg_features_clean[\"gesture\"],\n    palette=\"tab20\",\n    s=50\n)\nplt.title(\"UMAP projection of aggregated sensor features by gesture\")\nplt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T14:29:17.882466Z","iopub.execute_input":"2025-06-07T14:29:17.883023Z","iopub.status.idle":"2025-06-07T14:30:46.390618Z","shell.execute_reply.started":"2025-06-07T14:29:17.882990Z","shell.execute_reply":"2025-06-07T14:30:46.389664Z"}},"outputs":[],"execution_count":null}]}