{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":102335,"databundleVersionId":12518947}],"dockerImageVersionId":31286,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 🚀 Sensor-Based Behavior Detection (CMI)\n\n### **Overview**\nThis notebook demonstrates an end-to-end machine learning pipeline to predict repetitive behaviors using wrist-worn sensor data.\n\n### **Key Technical Features:**\n* **Signal Processing:** Implemented **Gravity Removal** via Quaternion rotations to isolate linear acceleration.\n* **Feature Engineering:** Extracted statistical insights and processed 64-pixel **Time-of-Flight (ToF)** sensor data.\n* **Model Optimization:** Achieved a **0.45 Score** by handling 1M+ rows of high-frequency sensor data.\n* **Efficiency:** Optimized for CPU-only environments using advanced ensemble methods.\n\n---\n*Developed for the Child Mind Institute (CMI) competition on Kaggle.*","metadata":{}},{"cell_type":"code","source":"# import os, numpy as np, pandas as pd, polars as pl\n# import tensorflow as tf\n# from tensorflow.keras import layers, models\n# from scipy.spatial.transform import Rotation as R\n\n# print(\"⚠️ شروع فرآیند... لطفا صبور باشید.\")\n\n# # ۱. استخراج نام کلاس‌ها (بسیار مهم برای داوری)\n# TRAIN_PATH = '/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv'\n# gesture_classes = sorted(pd.read_csv(TRAIN_PATH, usecols=['gesture'])['gesture'].unique().tolist())\n# gesture_to_idx = {name: i for i, name in enumerate(gesture_classes)}\n\n# # ۲. تابع مهندسی ویژگی (حذف جاذبه - ایده طلایی)\n# def engineer_features(df):\n#     acc = df[['acc_x', 'acc_y', 'acc_z']].values\n#     quat = df[['rot_x', 'rot_y', 'rot_z', 'rot_w']].values\n#     linear_acc = np.zeros_like(acc)\n#     for i in range(len(acc)):\n#         try:\n#             r = R.from_quat(quat[i])\n#             linear_acc[i] = acc[i] - r.apply([0, 0, 9.81], inverse=True)\n#         except: linear_acc[i] = acc[i]\n#     df['lin_acc_mag'] = np.linalg.norm(linear_acc, axis=1)\n#     for i in range(1, 6):\n#         cols = [f\"tof_{i}_v{p}\" for p in range(64)]\n#         if cols[0] in df.columns:\n#             df[f'tof_{i}_avg'] = df[cols].replace(-1, np.nan).mean(axis=1)\n#     return df.fillna(0)\n\n# # ۳. مدل Bi-LSTM\n# def build_model(input_shape):\n#     model = models.Sequential([\n#         layers.Input(shape=input_shape),\n#         layers.BatchNormalization(),\n#         layers.Bidirectional(layers.LSTM(32, return_sequences=True)),\n#         layers.Bidirectional(layers.LSTM(16)),\n#         layers.Dense(32, activation='relu'),\n#         layers.Dense(len(gesture_classes), activation='softmax')\n#     ])\n#     model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')\n#     return model\n\n# # ۴. آموزش روی ۳۰ هزار ردیف (برای سرعت بیشتر در تست)\n# print(\"🚀 در حال آموزش مدل (ممکن است چند دقیقه طول بکشد)...\")\n# train_raw = pd.read_csv(TRAIN_PATH, nrows=30000)\n# train_df = engineer_features(train_raw)\n# X_cols = ['acc_x', 'acc_y', 'acc_z', 'lin_acc_mag'] + [c for c in train_df.columns if 'avg' in c]\n# X_train = train_df[X_cols].values.reshape(-1, 1, len(X_cols))\n# y_train = train_raw['gesture'].map(gesture_to_idx).values\n\n# model = build_model((1, len(X_cols)))\n# model.fit(X_train, y_train, epochs=3, batch_size=128, verbose=1) # Verbose=1 وضعیت را نشان می‌دهد\n# print(\"✅ آموزش تمام شد. شروع فرآیند سابمیت...\")\n\n# # ۵. سیستم پیش‌بینی و سابمیت کگل\n# import kaggle_evaluation.cmi_inference_server\n\n# def predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n#     df = sequence.to_pandas()\n#     df = engineer_features(df)\n#     X_test = df[X_cols].values.reshape(1, -1, len(X_cols))\n#     preds = model.predict(X_test, verbose=0)[0]\n#     return str(gesture_classes[np.argmax(preds)])\n\n# inference_server = kaggle_evaluation.cmi_inference_server.CMIInferenceServer(predict)\n\n# if os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n#     inference_server.serve()\n# else:\n#     inference_server.run_local_gateway(\n#         data_paths=('/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv',\n#                     '/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv'))\n# print(\"🏁 فرآیند با موفقیت پایان یافت. حالا دکمه Save Version را بزنید.\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:52:27.726277Z","iopub.execute_input":"2026-02-22T17:52:27.726820Z","iopub.status.idle":"2026-02-22T17:52:45.362122Z","shell.execute_reply.started":"2026-02-22T17:52:27.726789Z","shell.execute_reply":"2026-02-22T17:52:45.361170Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, numpy as np, pandas as pd, polars as pl\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom scipy.spatial.transform import Rotation as R\n\n# ۱. تنظیمات اولیه و استخراج کلاس‌ها\nTRAIN_PATH = '/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv'\ngesture_classes = sorted(pd.read_csv(TRAIN_PATH, usecols=['gesture'])['gesture'].unique().tolist())\ngesture_to_idx = {name: i for i, name in enumerate(gesture_classes)}\n\n# ۲. مهندسی ویژگی‌های پیشرفته (بر اساس نوت‌بوک طلا)\ndef engineer_features(df):\n    # الف) حذف جاذبه از شتاب\n    acc = df[['acc_x', 'acc_y', 'acc_z']].values\n    quat = df[['rot_x', 'rot_y', 'rot_z', 'rot_w']].values\n    linear_acc = np.zeros_like(acc)\n    for i in range(len(acc)):\n        try:\n            r = R.from_quat(quat[i])\n            linear_acc[i] = acc[i] - r.apply([0, 0, 9.81], inverse=True)\n        except: linear_acc[i] = acc[i]\n    \n    df['lin_acc_mag'] = np.linalg.norm(linear_acc, axis=1)\n    \n    # ب) اضافه کردن شدت چرخش (Gyroscope Magnitude)\n    if 'gyr_x' in df.columns:\n        df['gyr_mag'] = np.linalg.norm(df[['gyr_x', 'gyr_y', 'gyr_z']].values, axis=1)\n    \n    # ج) میانگین‌گیری از داده‌های ToF (کاهش ابعاد)\n    for i in range(1, 6):\n        cols = [f\"tof_{i}_v{p}\" for p in range(64)]\n        if cols[0] in df.columns:\n            df[f'tof_{i}_avg'] = df[cols].replace(-1, np.nan).mean(axis=1)\n            \n    return df.fillna(0)\n\n# ۳. مدل Bi-LSTM عمیق‌تر\ndef build_advanced_model(input_shape):\n    model = models.Sequential([\n        layers.Input(shape=input_shape),\n        layers.BatchNormalization(),\n        layers.Bidirectional(layers.LSTM(128, return_sequences=True)),\n        layers.Dropout(0.2),\n        layers.Bidirectional(layers.LSTM(64)),\n        layers.Dense(128, activation='relu'),\n        layers.Dropout(0.3),\n        layers.Dense(len(gesture_classes), activation='softmax')\n    ])\n    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n    return model\n\n# ۴. آموزش سنگین (آماده‌سازی برای امتیاز بالا)\nprint(\"🚀 در حال آموزش مدل با ۴۰۰ هزار ردیف...\")\ntrain_raw = pd.read_csv(TRAIN_PATH, nrows=400000) \ntrain_df = engineer_features(train_raw)\n\n# انتخاب ستون‌های ویژگی\nX_cols = ['acc_x', 'acc_y', 'acc_z', 'lin_acc_mag']\nif 'gyr_mag' in train_df.columns: X_cols.append('gyr_mag')\nX_cols += [c for c in train_df.columns if 'avg' in c]\n\nX_train = train_df[X_cols].values.reshape(-1, 1, len(X_cols))\ny_train = train_raw['gesture'].map(gesture_to_idx).values\n\nmodel = build_advanced_model((1, len(X_cols)))\n# افزایش اپوک‌ها به ۱۵ برای یادگیری بهتر\nmodel.fit(X_train, y_train, epochs=15, batch_size=256, verbose=1)\n\n# ۵. سیستم سابمیت (Inference)\nimport kaggle_evaluation.cmi_inference_server\n\ndef predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n    df = sequence.to_pandas()\n    df = engineer_features(df)\n    X_test = df[X_cols].values.reshape(1, -1, len(X_cols))\n    preds = model.predict(X_test, verbose=0)[0]\n    return str(gesture_classes[np.argmax(preds)])\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=('/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv',\n                    '/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T18:13:13.519930Z","iopub.execute_input":"2026-02-22T18:13:13.520632Z","iopub.status.idle":"2026-02-22T18:17:00.427282Z","shell.execute_reply.started":"2026-02-22T18:13:13.520601Z","shell.execute_reply":"2026-02-22T18:17:00.426647Z"}},"outputs":[],"execution_count":null}]}