{"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":"gpu","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\n#pd.set_option('display.width', None)\n#pd.set_option('display.max_columns', None)\n#pd.set_option('display.max_rows', None)\nfrom scipy.stats import shapiro\nimport numpy as np\nfrom scipy.stats import skew\nfrom sklearn.preprocessing import PowerTransformer\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.preprocessing import StandardScaler\nfrom xgboost import XGBClassifier\nfrom lightgbm import LGBMClassifier\nimport kaggle_evaluation.cmi_inference_server\nfrom sklearn.model_selection import RandomizedSearchCV\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:52:26.793406Z","iopub.execute_input":"2025-06-04T09:52:26.793702Z","iopub.status.idle":"2025-06-04T09:52:32.926650Z","shell.execute_reply.started":"2025-06-04T09:52:26.793681Z","shell.execute_reply":"2025-06-04T09:52:32.926012Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data=pd.read_csv(\"/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv\")\ndata.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:52:32.927856Z","iopub.execute_input":"2025-06-04T09:52:32.928385Z","iopub.status.idle":"2025-06-04T09:53:01.319352Z","shell.execute_reply.started":"2025-06-04T09:52:32.928363Z","shell.execute_reply":"2025-06-04T09:53:01.318704Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gdata=pd.read_csv(\"/kaggle/input/cmi-detect-behavior-with-sensor-data/train_demographics.csv\")\ngdata.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:01.320003Z","iopub.execute_input":"2025-06-04T09:53:01.320175Z","iopub.status.idle":"2025-06-04T09:53:01.344575Z","shell.execute_reply.started":"2025-06-04T09:53:01.320161Z","shell.execute_reply":"2025-06-04T09:53:01.344059Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data[\"sequence_type\"].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:01.345981Z","iopub.execute_input":"2025-06-04T09:53:01.346178Z","iopub.status.idle":"2025-06-04T09:53:01.399797Z","shell.execute_reply.started":"2025-06-04T09:53:01.346163Z","shell.execute_reply":"2025-06-04T09:53:01.399075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"result = data.groupby('sequence_id').agg({\n    'sequence_type': lambda x: ','.join(x),  # Concatenate types as string\n    'sequence_counter': 'sum'                # Sum of counters\n}).reset_index()\n\nresult","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:01.400765Z","iopub.execute_input":"2025-06-04T09:53:01.400982Z","iopub.status.idle":"2025-06-04T09:53:01.721754Z","shell.execute_reply.started":"2025-06-04T09:53:01.400958Z","shell.execute_reply":"2025-06-04T09:53:01.721088Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:01.722437Z","iopub.execute_input":"2025-06-04T09:53:01.722711Z","iopub.status.idle":"2025-06-04T09:53:02.448548Z","shell.execute_reply.started":"2025-06-04T09:53:01.722687Z","shell.execute_reply":"2025-06-04T09:53:02.447950Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gdata.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:02.449160Z","iopub.execute_input":"2025-06-04T09:53:02.449358Z","iopub.status.idle":"2025-06-04T09:53:02.455145Z","shell.execute_reply.started":"2025-06-04T09:53:02.449344Z","shell.execute_reply":"2025-06-04T09:53:02.454487Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"number_data=data.select_dtypes([\"int64\",\"float64\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:02.455701Z","iopub.execute_input":"2025-06-04T09:53:02.455889Z","iopub.status.idle":"2025-06-04T09:53:02.994215Z","shell.execute_reply.started":"2025-06-04T09:53:02.455875Z","shell.execute_reply":"2025-06-04T09:53:02.993587Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"total_rows=number_data.shape[0]\nnull_data = number_data.isna().sum().reset_index().rename(columns = {0: \"Nulls_Count\", \"index\": \"Column_Name\"}).sort_values(by=\"Nulls_Count\", ascending=False)\nnull_data['Percentage']=(null_data['Nulls_Count']/total_rows)*100\nnull_data[null_data[\"Nulls_Count\"] > 0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:02.994985Z","iopub.execute_input":"2025-06-04T09:53:02.995195Z","iopub.status.idle":"2025-06-04T09:53:03.532533Z","shell.execute_reply.started":"2025-06-04T09:53:02.995178Z","shell.execute_reply":"2025-06-04T09:53:03.531793Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"stat, p = shapiro(number_data)\nprint('Statistics=%.3f, p=%.3f' % (stat, p))\nif p > 0.05:\n    print(\"Data looks normally distributed (fail to reject H0)\")\nelse:\n    print(\"Data does not look normally distributed (reject H0)\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:03.535211Z","iopub.execute_input":"2025-06-04T09:53:03.535430Z","iopub.status.idle":"2025-06-04T09:53:05.092421Z","shell.execute_reply.started":"2025-06-04T09:53:03.535414Z","shell.execute_reply":"2025-06-04T09:53:05.091622Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"median = number_data.median(numeric_only=True)\n\nclean_data = number_data.fillna(median)\n\nclean_data.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:05.093316Z","iopub.execute_input":"2025-06-04T09:53:05.093568Z","iopub.status.idle":"2025-06-04T09:53:08.628328Z","shell.execute_reply.started":"2025-06-04T09:53:05.093540Z","shell.execute_reply":"2025-06-04T09:53:08.627593Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"object_data=data.select_dtypes([\"object\"])\nobject_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:08.629178Z","iopub.execute_input":"2025-06-04T09:53:08.629931Z","iopub.status.idle":"2025-06-04T09:53:08.679121Z","shell.execute_reply.started":"2025-06-04T09:53:08.629905Z","shell.execute_reply":"2025-06-04T09:53:08.678319Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"total_rows=object_data.shape[0]\nnull_data = object_data.isna().sum().reset_index().rename(columns = {0: \"Nulls_Count\", \"index\": \"Column_Name\"}).sort_values(by=\"Nulls_Count\", ascending=False)\nnull_data['Percentage']=(null_data['Nulls_Count']/total_rows)*100\nnull_data[null_data[\"Nulls_Count\"] > 0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:08.679950Z","iopub.execute_input":"2025-06-04T09:53:08.680225Z","iopub.status.idle":"2025-06-04T09:53:08.911783Z","shell.execute_reply.started":"2025-06-04T09:53:08.680207Z","shell.execute_reply":"2025-06-04T09:53:08.910929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data=pd.concat([clean_data,object_data],axis=1)\ndata.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:08.912672Z","iopub.execute_input":"2025-06-04T09:53:08.913439Z","iopub.status.idle":"2025-06-04T09:53:11.488908Z","shell.execute_reply.started":"2025-06-04T09:53:08.913414Z","shell.execute_reply":"2025-06-04T09:53:11.488316Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"object_data = data.select_dtypes(include='object').columns.tolist()\nif 'sequence_id' in object_data:\n    object_data.remove('sequence_id')\n\nsensor_data = [col for col in data.select_dtypes(include='number').columns if col != 'gesture']\n\ndef extract_features_per_squence(data, sensor_cols):\n    feature_list = []\n    sequence_ids = data[\"sequence_id\"].unique()\n    for seq_id in sequence_ids:\n        seq_data = data[data['sequence_id'] == seq_id]\n        features = {'sequence_id': seq_id}\n        for col in sensor_cols:\n            values = seq_data[col]\n            features[f\"{col}_mean\"] = values.mean()\n            features[f\"{col}_std\"] = values.std()\n            features[f\"{col}_median\"] = values.median()\n            features[f\"{col}_min\"] = values.min()\n            features[f\"{col}_max\"] = values.max()\n            features[f\"{col}_range\"] = values.max() - values.min()\n            #features[f\"{col}_iqr\"] = values.quantile(0.75) - values.quantile(0.25)\n\n        feature_list.append(features)\n    return pd.DataFrame(feature_list)\n\nfixed_length_df = extract_features_per_squence(data, sensor_data)\nobject_cols_df = data.groupby('sequence_id')[object_data].first().reset_index()\ngesture_map = data.groupby('sequence_id')['gesture'].first().reset_index()\n\ndata = fixed_length_df.merge(object_cols_df, on='sequence_id', how='left')\ndata = data.merge(gesture_map, on='sequence_id', how='left')\n\ndata.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T09:53:11.489612Z","iopub.execute_input":"2025-06-04T09:53:11.489838Z","iopub.status.idle":"2025-06-04T10:02:53.630553Z","shell.execute_reply.started":"2025-06-04T09:53:11.489819Z","shell.execute_reply":"2025-06-04T10:02:53.629950Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def check_outliers(df):\n    for col in df.columns:\n        if df[col].dtype != 'object':\n            q1 = df[col].quantile(0.25)\n            q3 = df[col].quantile(0.75)\n            iqr = q3 - q1\n            lower_bound = q1 - (1.5 * iqr)\n            upper_bound = q3 + (1.5 * iqr)\n            outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]\n            #print(f\"Column: {col}\")\n            #print(f\"Outliers: {len(outliers)}\")\n    return df\ncheck_outliers(data)   ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:02:53.631218Z","iopub.execute_input":"2025-06-04T10:02:53.631435Z","iopub.status.idle":"2025-06-04T10:03:00.754228Z","shell.execute_reply.started":"2025-06-04T10:02:53.631410Z","shell.execute_reply":"2025-06-04T10:03:00.753502Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def solve_outliers(df):\n    for col in df.columns:\n        if df[col].dtype != 'object':\n            q1 = df[col].quantile(0.25)\n            q3 = df[col].quantile(0.75)\n            iqr = q3 - q1\n            lower_bound = q1 - (1.5 * iqr)\n            upper_bound = q3 + (1.5 * iqr)\n            median=df[col].median()\n            df[col] = np.where(df[col] < lower_bound, median, df[col])\n            df[col] = np.where(df[col] > upper_bound, median, df[col])\n            #print(f\"Column: {col}\")\n            #print(f\"Outliers: {len(df[(df[col] < lower_bound) | (df[col] > upper_bound)])}\")\n           \n    return df\ndata=solve_outliers(data)        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:00.755093Z","iopub.execute_input":"2025-06-04T10:03:00.755351Z","iopub.status.idle":"2025-06-04T10:03:03.980052Z","shell.execute_reply.started":"2025-06-04T10:03:00.755328Z","shell.execute_reply":"2025-06-04T10:03:03.979521Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data.select_dtypes(exclude='object').skew()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:03.980708Z","iopub.execute_input":"2025-06-04T10:03:03.980943Z","iopub.status.idle":"2025-06-04T10:03:04.319416Z","shell.execute_reply.started":"2025-06-04T10:03:03.980923Z","shell.execute_reply":"2025-06-04T10:03:04.318856Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nskewed_features = data.apply(\n    lambda x: skew(x.dropna()) if x.dtype != 'object' else 0\n)\nhigh_skew = skewed_features[abs(skewed_features) > 0.75].index.tolist()\n\nprint(f\"عدد الأعمدة اللي فيها skew عالي: {len(high_skew)}\")\n\npt = PowerTransformer(method='yeo-johnson')\n\ndata[high_skew] = pt.fit_transform(data[high_skew])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:04.320106Z","iopub.execute_input":"2025-06-04T10:03:04.320302Z","iopub.status.idle":"2025-06-04T10:03:13.118611Z","shell.execute_reply.started":"2025-06-04T10:03:04.320281Z","shell.execute_reply":"2025-06-04T10:03:13.118040Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from scipy.stats import chi2_contingency\n\nchi2_stat, p_val, dof, ex = chi2_contingency(pd.crosstab(data['subject'], data['gesture_x']))\nprint(f\"P-value: {p_val}\")\nif p_val < 0.05:  # Typically, a p-value < 0.05 suggests significance\n    print(\"The column is significant.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.119343Z","iopub.execute_input":"2025-06-04T10:03:13.119578Z","iopub.status.idle":"2025-06-04T10:03:13.157584Z","shell.execute_reply.started":"2025-06-04T10:03:13.119562Z","shell.execute_reply":"2025-06-04T10:03:13.156956Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data['subject'] = data['subject'].str.replace('SUBJ_', '').astype(int)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.158226Z","iopub.execute_input":"2025-06-04T10:03:13.158398Z","iopub.status.idle":"2025-06-04T10:03:13.165945Z","shell.execute_reply.started":"2025-06-04T10:03:13.158385Z","shell.execute_reply":"2025-06-04T10:03:13.165293Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gdata['subject'] = gdata['subject'].str.replace('SUBJ_', '').astype(int)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.166665Z","iopub.execute_input":"2025-06-04T10:03:13.166932Z","iopub.status.idle":"2025-06-04T10:03:13.182156Z","shell.execute_reply.started":"2025-06-04T10:03:13.166916Z","shell.execute_reply":"2025-06-04T10:03:13.181456Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data=data.drop(\"gesture_y\",axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.183090Z","iopub.execute_input":"2025-06-04T10:03:13.183337Z","iopub.status.idle":"2025-06-04T10:03:13.404010Z","shell.execute_reply.started":"2025-06-04T10:03:13.183316Z","shell.execute_reply":"2025-06-04T10:03:13.403437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\n\nobject_cols = data.select_dtypes(include='object').columns.tolist()\n\nobject_cols = [col for col in object_cols if col != 'gesture_x']  \n\nle_dict = {}\nfor col in object_cols:\n    le = LabelEncoder()\n    data[col] = le.fit_transform(data[col].astype(str))\n    le_dict[col] = le  \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.404680Z","iopub.execute_input":"2025-06-04T10:03:13.404899Z","iopub.status.idle":"2025-06-04T10:03:13.446584Z","shell.execute_reply.started":"2025-06-04T10:03:13.404883Z","shell.execute_reply":"2025-06-04T10:03:13.445796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.447362Z","iopub.execute_input":"2025-06-04T10:03:13.447977Z","iopub.status.idle":"2025-06-04T10:03:13.474818Z","shell.execute_reply.started":"2025-06-04T10:03:13.447960Z","shell.execute_reply":"2025-06-04T10:03:13.474233Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data[\"gesture_x\"].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.475520Z","iopub.execute_input":"2025-06-04T10:03:13.475754Z","iopub.status.idle":"2025-06-04T10:03:13.482867Z","shell.execute_reply.started":"2025-06-04T10:03:13.475720Z","shell.execute_reply":"2025-06-04T10:03:13.482165Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import joblib\n\nle = LabelEncoder()\ndata['gesture_encoded'] = le.fit_transform(data['gesture_x'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.483519Z","iopub.execute_input":"2025-06-04T10:03:13.483688Z","iopub.status.idle":"2025-06-04T10:03:13.498410Z","shell.execute_reply.started":"2025-06-04T10:03:13.483676Z","shell.execute_reply":"2025-06-04T10:03:13.497799Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"joblib.dump(le, 'gesture_encoder.pkl')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:03:13.501664Z","iopub.execute_input":"2025-06-04T10:03:13.501832Z","iopub.status.idle":"2025-06-04T10:03:13.514276Z","shell.execute_reply.started":"2025-06-04T10:03:13.501819Z","shell.execute_reply":"2025-06-04T10:03:13.513776Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X=data.drop([\"gesture_encoded\",\"gesture_x\"],axis=1)\ny=data[\"gesture_encoded\"]\n\"\"\"\"\"\nxgb_pipeline = Pipeline([\n    ('scaler', StandardScaler()),\n    ('xgb', XGBClassifier(use_label_encoder=False, eval_metric='mlogloss',tree_method='hist',device=\"cuda\"))\n])\nxgb_scores = cross_val_score(xgb_pipeline, X, y, cv=5, scoring='accuracy')\nprint(\"XGBoost CV Accuracy:\", xgb_scores.mean())\n\"\"\"\"\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:56:07.348527Z","iopub.execute_input":"2025-06-04T10:56:07.348866Z","iopub.status.idle":"2025-06-04T10:56:07.438805Z","shell.execute_reply.started":"2025-06-04T10:56:07.348840Z","shell.execute_reply":"2025-06-04T10:56:07.438025Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\"\"\nparam_dist = {\n    'xgb__n_estimators': [100, 200, 300],\n    'xgb__max_depth': [3, 5, 7],\n    'xgb__learning_rate': [0.01, 0.05, 0.1],\n    'xgb__subsample': [0.7, 0.8, 1],\n    'xgb__colsample_bytree': [0.7, 0.9, 1.0],\n    'xgb__gamma': [0, 0.1, 0.3]\n}\n\nrandom_search = RandomizedSearchCV(\n    xgb_pipeline,\n    param_distributions=param_dist,\n    n_iter=20,\n    scoring='accuracy',\n    cv=5,\n    verbose=1,\n    random_state=42,\n    n_jobs=-1\n)\nrandom_search.fit(X, y)\n\"\"\"\"\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:55:54.789859Z","iopub.execute_input":"2025-06-04T10:55:54.790764Z","iopub.status.idle":"2025-06-04T10:55:54.795533Z","shell.execute_reply.started":"2025-06-04T10:55:54.790730Z","shell.execute_reply":"2025-06-04T10:55:54.794780Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"best_params = {\n    'subsample': 0.8,\n    'n_estimators': 300,\n    'max_depth': 7,\n    'learning_rate': 0.05,\n    'gamma': 0.1,\n    'colsample_bytree': 0.7\n}\n\npipeline = Pipeline([\n    ('scaler', StandardScaler()),\n    ('xgb', XGBClassifier(\n        use_label_encoder=False,\n        eval_metric='mlogloss',\n        device='cuda',\n        **best_params\n    ))\n])\nxgb_scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')\nprint(\"XGBoost CV Accuracy:\", xgb_scores.mean())\npipeline.fit(X, y)\njoblib.dump(pipeline, \"xgb_best_model.pkl\")\nprint(\"✅ Model saved as xgb_best_model.pkl\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:45:31.173051Z","iopub.execute_input":"2025-06-04T10:45:31.173927Z","iopub.status.idle":"2025-06-04T10:49:48.008942Z","shell.execute_reply.started":"2025-06-04T10:45:31.173888Z","shell.execute_reply":"2025-06-04T10:49:48.008055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gesture = joblib.load('/kaggle/working/gesture_encoder.pkl')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:38:43.268818Z","iopub.execute_input":"2025-06-04T10:38:43.269091Z","iopub.status.idle":"2025-06-04T10:38:43.273228Z","shell.execute_reply.started":"2025-06-04T10:38:43.269066Z","shell.execute_reply":"2025-06-04T10:38:43.272653Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"feature_cols = X.columns.tolist()\n\nnp.save(\"/kaggle/working/sensor_data_cols.npy\", feature_cols, allow_pickle=True)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:38:43.273931Z","iopub.execute_input":"2025-06-04T10:38:43.274130Z","iopub.status.idle":"2025-06-04T10:38:43.286838Z","shell.execute_reply.started":"2025-06-04T10:38:43.274106Z","shell.execute_reply":"2025-06-04T10:38:43.286135Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import polars as pl\nimport joblib\nimport numpy as np\nimport pandas as pd\n\ndef predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n    sequence_df = sequence.to_pandas()\n    demographics_df = demographics.to_pandas()\n\n    sensor_data = [col for col in sequence_df.select_dtypes(include='number').columns]\n\n    features = {}\n    for col in sensor_data:\n        values = sequence_df[col]\n        features[f\"{col}_mean\"] = values.mean()\n        features[f\"{col}_std\"] = values.std()\n        features[f\"{col}_median\"] = values.median()\n        features[f\"{col}_min\"] = values.min()\n        features[f\"{col}_max\"] = values.max()\n    \n    combined = {**features, **demographics_df.iloc[0].to_dict()}\n    input_df = pd.DataFrame([combined])\n\n    if 'subject' in input_df.columns:\n        input_df['subject'] = input_df['subject'].astype(str).str.replace('SUBJ_', '').astype(int)\n\n    model = joblib.load(\"/kaggle/working/xgb_best_model.pkl\")\n    encoder = joblib.load(\"/kaggle/working/gesture_encoder.pkl\")\n\n    try:\n        feature_cols = np.load(\"/kaggle/working/sensor_data_cols.npy\", allow_pickle=True).tolist()\n        missing_cols = [col for col in feature_cols if col not in input_df.columns]\n\n        if missing_cols:\n            zero_df = pd.DataFrame(0, index=input_df.index, columns=missing_cols)\n            input_df = pd.concat([input_df, zero_df], axis=1)\n\n        input_df = input_df[feature_cols]\n    except FileNotFoundError:\n        pass\n\n    pred_encoded = model.predict(input_df)\n    pred = encoder.inverse_transform(pred_encoded)\n\n    return pred[0]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-04T10:55:27.906868Z","iopub.execute_input":"2025-06-04T10:55:27.907588Z","iopub.status.idle":"2025-06-04T10:55:27.914913Z","shell.execute_reply.started":"2025-06-04T10:55:27.907565Z","shell.execute_reply":"2025-06-04T10:55:27.914157Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\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-06-04T10:55:31.374872Z","iopub.execute_input":"2025-06-04T10:55:31.375360Z","iopub.status.idle":"2025-06-04T10:55:32.845025Z","shell.execute_reply.started":"2025-06-04T10:55:31.375340Z","shell.execute_reply":"2025-06-04T10:55:32.844406Z"}},"outputs":[],"execution_count":null}]}