{"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":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-07-15T06:48:08.320368Z","iopub.execute_input":"2025-07-15T06:48:08.320742Z","iopub.status.idle":"2025-07-15T06:48:08.339873Z","shell.execute_reply.started":"2025-07-15T06:48:08.320716Z","shell.execute_reply":"2025-07-15T06:48:08.338953Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom sklearn.preprocessing import StandardScaler, LabelEncoder\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:08.369685Z","iopub.execute_input":"2025-07-15T06:48:08.369999Z","iopub.status.idle":"2025-07-15T06:48:08.374802Z","shell.execute_reply.started":"2025-07-15T06:48:08.369974Z","shell.execute_reply":"2025-07-15T06:48:08.373760Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv')\ntest = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:08.376311Z","iopub.execute_input":"2025-07-15T06:48:08.376645Z","iopub.status.idle":"2025-07-15T06:48:42.100049Z","shell.execute_reply.started":"2025-07-15T06:48:08.376623Z","shell.execute_reply":"2025-07-15T06:48:42.099291Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = train\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.101668Z","iopub.execute_input":"2025-07-15T06:48:42.102144Z","iopub.status.idle":"2025-07-15T06:48:42.129538Z","shell.execute_reply.started":"2025-07-15T06:48:42.102113Z","shell.execute_reply":"2025-07-15T06:48:42.128517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sequences = df.groupby(\"sequence_id\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.130691Z","iopub.execute_input":"2025-07-15T06:48:42.131023Z","iopub.status.idle":"2025-07-15T06:48:42.137714Z","shell.execute_reply.started":"2025-07-15T06:48:42.130993Z","shell.execute_reply":"2025-07-15T06:48:42.136505Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y = df.groupby(\"sequence_id\")['gesture'].first().values","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.139756Z","iopub.execute_input":"2025-07-15T06:48:42.140043Z","iopub.status.idle":"2025-07-15T06:48:42.233848Z","shell.execute_reply.started":"2025-07-15T06:48:42.140022Z","shell.execute_reply":"2025-07-15T06:48:42.232797Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.utils import to_categorical\n\nle = LabelEncoder()\ny = le.fit_transform(y)\ny = to_categorical(y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.234712Z","iopub.execute_input":"2025-07-15T06:48:42.234941Z","iopub.status.idle":"2025-07-15T06:48:42.243210Z","shell.execute_reply.started":"2025-07-15T06:48:42.234923Z","shell.execute_reply":"2025-07-15T06:48:42.242305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.244203Z","iopub.execute_input":"2025-07-15T06:48:42.244580Z","iopub.status.idle":"2025-07-15T06:48:42.260365Z","shell.execute_reply.started":"2025-07-15T06:48:42.244551Z","shell.execute_reply":"2025-07-15T06:48:42.259640Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"needCols = [i for i in df.columns if i.startswith(\"acc_\") or i.startswith(\"rot_\") or i.startswith(\"thm_\") or i.startswith(\"tof_\")]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.261311Z","iopub.execute_input":"2025-07-15T06:48:42.261740Z","iopub.status.idle":"2025-07-15T06:48:42.277667Z","shell.execute_reply.started":"2025-07-15T06:48:42.261709Z","shell.execute_reply":"2025-07-15T06:48:42.276472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[needCols].isna().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:42.278764Z","iopub.execute_input":"2025-07-15T06:48:42.279099Z","iopub.status.idle":"2025-07-15T06:48:43.534176Z","shell.execute_reply.started":"2025-07-15T06:48:42.279068Z","shell.execute_reply":"2025-07-15T06:48:43.533478Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X=[]\nXlen=[]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:48:43.535328Z","iopub.execute_input":"2025-07-15T06:48:43.535619Z","iopub.status.idle":"2025-07-15T06:48:43.545561Z","shell.execute_reply.started":"2025-07-15T06:48:43.535594Z","shell.execute_reply":"2025-07-15T06:48:43.544621Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def func(data, colss):\n    data = data[colss].copy()\n    data = data.fillna(-2)\n    scaler = StandardScaler()\n    scaled_data = scaler.fit_transform(data)\n    return scaled_data, scaler","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:16:42.256926Z","iopub.execute_input":"2025-07-15T07:16:42.257259Z","iopub.status.idle":"2025-07-15T07:16:42.262273Z","shell.execute_reply.started":"2025-07-15T07:16:42.257235Z","shell.execute_reply":"2025-07-15T07:16:42.261350Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = []\nXlen = []\n\n# Use this once, for the first sequence, to extract the scaler\nfor i, j in sequences:\n    processed, scaler = func(j, needCols)  # <-- modified to return scaler\n    X.append(processed)\n    Xlen.append(processed.shape[0])\n    break  # only get scaler from the first one\n\n# Continue the rest with same scaler\nfor i, j in list(sequences)[1:]:\n    data = j[needCols].copy()\n    data = data.fillna(-2)\n    processed = scaler.transform(data)\n    X.append(processed)\n    Xlen.append(processed.shape[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:16:59.213027Z","iopub.execute_input":"2025-07-15T07:16:59.213444Z","iopub.status.idle":"2025-07-15T07:17:49.997711Z","shell.execute_reply.started":"2025-07-15T07:16:59.213397Z","shell.execute_reply":"2025-07-15T07:17:49.996724Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pad_len = int(np.percentile(Xlen, 90))\npad_len","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:21:06.215172Z","iopub.execute_input":"2025-07-15T07:21:06.216278Z","iopub.status.idle":"2025-07-15T07:21:06.223499Z","shell.execute_reply.started":"2025-07-15T07:21:06.216242Z","shell.execute_reply":"2025-07-15T07:21:06.222589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y = np.array(y)\ny.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:21:07.204043Z","iopub.execute_input":"2025-07-15T07:21:07.204355Z","iopub.status.idle":"2025-07-15T07:21:07.210812Z","shell.execute_reply.started":"2025-07-15T07:21:07.204331Z","shell.execute_reply":"2025-07-15T07:21:07.209783Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.sequence import pad_sequences\n\n\nX = pad_sequences(X , maxlen = pad_len, dtype = \"float64\", padding = \"post\", truncating = \"post\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:21:08.019451Z","iopub.execute_input":"2025-07-15T07:21:08.019804Z","iopub.status.idle":"2025-07-15T07:21:09.300664Z","shell.execute_reply.started":"2025-07-15T07:21:08.019782Z","shell.execute_reply":"2025-07-15T07:21:09.299680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X.shape, y.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:21:18.940975Z","iopub.execute_input":"2025-07-15T07:21:18.941298Z","iopub.status.idle":"2025-07-15T07:21:18.947422Z","shell.execute_reply.started":"2025-07-15T07:21:18.941275Z","shell.execute_reply":"2025-07-15T07:21:18.946383Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import joblib\nimport numpy as np\n\njoblib.dump(scaler, \"scaler.pkl\")\njoblib.dump(le, \"label_encoder.pkl\")\nnp.save(\"feature_cols.npy\", np.array(needCols, dtype=object))\nnp.save(\"pad_len.npy\", pad_len)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:21:24.959325Z","iopub.execute_input":"2025-07-15T07:21:24.959676Z","iopub.status.idle":"2025-07-15T07:21:24.967536Z","shell.execute_reply.started":"2025-07-15T07:21:24.959652Z","shell.execute_reply":"2025-07-15T07:21:24.966626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2 ,random_state=42, )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:21:14.034096Z","iopub.execute_input":"2025-07-15T07:21:14.034496Z","iopub.status.idle":"2025-07-15T07:21:14.768230Z","shell.execute_reply.started":"2025-07-15T07:21:14.034467Z","shell.execute_reply":"2025-07-15T07:21:14.767112Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import accuracy_score","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:50:18.717330Z","iopub.execute_input":"2025-07-15T06:50:18.717740Z","iopub.status.idle":"2025-07-15T06:50:18.722305Z","shell.execute_reply.started":"2025-07-15T06:50:18.717718Z","shell.execute_reply":"2025-07-15T06:50:18.721282Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import LSTM, Dense\n\nmodel = Sequential()\nmodel.add(LSTM(64, input_shape=(X.shape[1], X.shape[2])))\nmodel.add(Dense(18, activation='softmax'))  # for binary classification\n\nmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\nmodel.fit(X, y, epochs=50, batch_size=32)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:50:18.723398Z","iopub.execute_input":"2025-07-15T06:50:18.723760Z","iopub.status.idle":"2025-07-15T07:00:43.073877Z","shell.execute_reply.started":"2025-07-15T06:50:18.723731Z","shell.execute_reply":"2025-07-15T07:00:43.072948Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss, accuracy = model.evaluate(X_test, y_test)\nprint(\"Test Loss:\", loss)\nprint(\"Test Accuracy:\", accuracy)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:00:43.079325Z","iopub.execute_input":"2025-07-15T07:00:43.079678Z","iopub.status.idle":"2025-07-15T07:00:46.135304Z","shell.execute_reply.started":"2025-07-15T07:00:43.079654Z","shell.execute_reply":"2025-07-15T07:00:46.134370Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = model.save(\"lstm_model.h5\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:00:46.136260Z","iopub.execute_input":"2025-07-15T07:00:46.136612Z","iopub.status.idle":"2025-07-15T07:00:46.169023Z","shell.execute_reply.started":"2025-07-15T07:00:46.136581Z","shell.execute_reply":"2025-07-15T07:00:46.167984Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test[['sequence_id']]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:00:46.170079Z","iopub.execute_input":"2025-07-15T07:00:46.170357Z","iopub.status.idle":"2025-07-15T07:00:46.182065Z","shell.execute_reply.started":"2025-07-15T07:00:46.170332Z","shell.execute_reply":"2025-07-15T07:00:46.181088Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:01:42.096626Z","iopub.execute_input":"2025-07-15T07:01:42.097953Z","iopub.status.idle":"2025-07-15T07:01:42.102056Z","shell.execute_reply.started":"2025-07-15T07:01:42.097914Z","shell.execute_reply":"2025-07-15T07:01:42.101144Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport polars as pl\nimport joblib\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.preprocessing.sequence import pad_sequences\n\n# Load all the required saved files\nscaler = joblib.load(\"scaler.pkl\")\nle = joblib.load(\"label_encoder.pkl\")\nfeature_cols = np.load(\"feature_cols.npy\", allow_pickle=True)\npad_len = int(np.load(\"pad_len.npy\"))\nmodel = load_model(\"lstm_model.h5\")  # Your trained model\n\n# Define the predict function for Kaggle submission\ndef predict(seq: pl.DataFrame, dem: pl.DataFrame) -> str:\n    df_seq = seq.to_pandas()\n    df_seq = df_seq[feature_cols].copy()\n    df_seq = df_seq.fillna(-2)\n\n    mat = scaler.transform(df_seq.values.astype(\"float32\"))\n    x = pad_sequences([mat], maxlen=pad_len, padding=\"post\", dtype=\"float32\")\n\n    pred = model.predict(x, verbose=0)[0]\n    return le.inverse_transform([pred.argmax()])[0]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:23:03.265053Z","iopub.execute_input":"2025-07-15T07:23:03.266205Z","iopub.status.idle":"2025-07-15T07:23:03.331827Z","shell.execute_reply.started":"2025-07-15T07:23:03.266093Z","shell.execute_reply":"2025-07-15T07:23:03.330790Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import kaggle_evaluation.cmi_inference_server\nfrom kaggle_evaluation.cmi_inference_server import CMIInferenceServer\nimport os\n\ninference_server = CMIInferenceServer(predict)\n\nif os.getenv(\"KAGGLE_IS_COMPETITION_RERUN\"):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway((\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-07-15T07:24:31.204783Z","iopub.execute_input":"2025-07-15T07:24:31.205097Z","iopub.status.idle":"2025-07-15T07:24:33.256559Z","shell.execute_reply.started":"2025-07-15T07:24:31.205076Z","shell.execute_reply":"2025-07-15T07:24:33.255567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}