{"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,"sourceType":"competition"}],"dockerImageVersionId":31089,"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) 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-08-08T07:36:50.568425Z","iopub.execute_input":"2025-08-08T07:36:50.568800Z","iopub.status.idle":"2025-08-08T07:36:51.133163Z","shell.execute_reply.started":"2025-08-08T07:36:50.568761Z","shell.execute_reply":"2025-08-08T07:36:51.132127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_filePath = '/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv'\ntrain_demographics_filePath = '/kaggle/input/cmi-detect-behavior-with-sensor-data/train_demographics.csv'\ntest_filePath = '/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv'\ntest_demographics_filePath = '/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:36:51.137136Z","iopub.execute_input":"2025-08-08T07:36:51.138152Z","iopub.status.idle":"2025-08-08T07:36:51.145612Z","shell.execute_reply.started":"2025-08-08T07:36:51.138044Z","shell.execute_reply":"2025-08-08T07:36:51.143570Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv(train_filePath)\ntrain_dem_df = pd.read_csv(train_demographics_filePath)\ntest_df = pd.read_csv(test_filePath)\ntest_dem_df = pd.read_csv(test_demographics_filePath)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:36:51.147374Z","iopub.execute_input":"2025-08-08T07:36:51.147781Z","iopub.status.idle":"2025-08-08T07:37:31.857318Z","shell.execute_reply.started":"2025-08-08T07:36:51.147747Z","shell.execute_reply":"2025-08-08T07:37:31.855571Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:31.858585Z","iopub.execute_input":"2025-08-08T07:37:31.858924Z","iopub.status.idle":"2025-08-08T07:37:31.926617Z","shell.execute_reply.started":"2025-08-08T07:37:31.858891Z","shell.execute_reply":"2025-08-08T07:37:31.925091Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df['phase'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:31.928040Z","iopub.execute_input":"2025-08-08T07:37:31.928464Z","iopub.status.idle":"2025-08-08T07:37:31.990848Z","shell.execute_reply.started":"2025-08-08T07:37:31.928428Z","shell.execute_reply":"2025-08-08T07:37:31.989750Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head(26)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:31.992073Z","iopub.execute_input":"2025-08-08T07:37:31.992699Z","iopub.status.idle":"2025-08-08T07:37:32.058475Z","shell.execute_reply.started":"2025-08-08T07:37:31.992661Z","shell.execute_reply":"2025-08-08T07:37:32.057192Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\nfrom statsmodels.graphics.mosaicplot import mosaic\n\n# 모자이크 플롯으로 시각화\nplt.figure(figsize=(15, 10))\nmosaic(train_df, ['orientation', 'gesture'], title='Mosaic Plot of Orientation and Gesture')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:32.062357Z","iopub.execute_input":"2025-08-08T07:37:32.062685Z","iopub.status.idle":"2025-08-08T07:37:34.692183Z","shell.execute_reply.started":"2025-08-08T07:37:32.062660Z","shell.execute_reply":"2025-08-08T07:37:34.690531Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1. 교차표 생성\ncrosstab_df = pd.crosstab(train_df['orientation'], train_df['gesture'])\nprint(\"교차표:\\n\", crosstab_df)\n\n# 2. 히트맵으로 시각화\nplt.figure(figsize=(15, 10))\nsns.heatmap(crosstab_df, annot=True, fmt='d', cmap='YlGnBu')\nplt.title('Correlation between Orientation and Gesture', fontsize=16)\nplt.xlabel('Gesture', fontsize=12)\nplt.ylabel('Orientation', fontsize=12)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:34.693913Z","iopub.execute_input":"2025-08-08T07:37:34.694645Z","iopub.status.idle":"2025-08-08T07:37:35.590933Z","shell.execute_reply.started":"2025-08-08T07:37:34.694597Z","shell.execute_reply":"2025-08-08T07:37:35.589524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:35.592171Z","iopub.execute_input":"2025-08-08T07:37:35.592509Z","iopub.status.idle":"2025-08-08T07:37:35.622177Z","shell.execute_reply.started":"2025-08-08T07:37:35.592482Z","shell.execute_reply":"2025-08-08T07:37:35.621038Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df['sequence_id'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:35.623427Z","iopub.execute_input":"2025-08-08T07:37:35.624448Z","iopub.status.idle":"2025-08-08T07:37:35.654569Z","shell.execute_reply.started":"2025-08-08T07:37:35.624405Z","shell.execute_reply":"2025-08-08T07:37:35.653459Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dem_df = pd.read_csv(train_demographics_filePath)\n\ntrain_dem_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:35.655578Z","iopub.execute_input":"2025-08-08T07:37:35.655863Z","iopub.status.idle":"2025-08-08T07:37:35.697299Z","shell.execute_reply.started":"2025-08-08T07:37:35.655839Z","shell.execute_reply":"2025-08-08T07:37:35.695240Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Check missing value","metadata":{}},{"cell_type":"code","source":"datasets = {\n    \"Train Data\": train_df,\n    \"Train Demographics\": train_dem_df,\n    \"Test Data\": test_df,\n    \"Test Demographics\": test_dem_df,\n}\n\n# Print shapes\nfor name, df in datasets.items():\n    num_rows, num_cols = df.shape\n    print(f\"{name}:\")\n    print(f\"  Number of Rows: {num_rows}\")\n    print(f\"  Number of Columns: {num_cols}\\n\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:35.698752Z","iopub.execute_input":"2025-08-08T07:37:35.699154Z","iopub.status.idle":"2025-08-08T07:37:35.707495Z","shell.execute_reply.started":"2025-08-08T07:37:35.699084Z","shell.execute_reply":"2025-08-08T07:37:35.706259Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Count duplicate rows in train_df\ntrain_duplicates = train_df.duplicated().sum()\n\n# Count duplicate rows in test_df\ntest_duplicates = test_df.duplicated().sum()\n\n# Count duplicate rows in train_dem_df (optional)\ntrain_dem_duplicates = train_dem_df.duplicated().sum()\n\n# Count duplicate rows in test_dem_df (optional)\ntest_dem_duplicates = test_dem_df.duplicated().sum()\n\n# Print the results\nprint(f\"Number of duplicate rows in train_df: {train_duplicates}\")\nprint(f\"Number of duplicate rows in test_df: {test_duplicates}\")\nprint(f\"Number of duplicate rows in train_dem_df: {train_dem_duplicates}\")\nprint(f\"Number of duplicate rows in test_dem_df: {test_dem_duplicates}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:35.708565Z","iopub.execute_input":"2025-08-08T07:37:35.708868Z","iopub.status.idle":"2025-08-08T07:37:44.298787Z","shell.execute_reply.started":"2025-08-08T07:37:35.708843Z","shell.execute_reply":"2025-08-08T07:37:44.293673Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_seq_df = train_df[['sequence_id', 'sequence_counter']]\ntest_seq_df = test_df[['sequence_id', 'sequence_counter']]\n\n# Count duplicate rows in train_df\ntrain_duplicates = train_seq_df.duplicated().sum()\n\n# Count duplicate rows in test_df\ntest_duplicates = test_seq_df.duplicated().sum()\n\n# Print the results\nprint(f\"Number of duplicate rows in train_df: {train_duplicates}\")\nprint(f\"Number of duplicate rows in test_df: {test_duplicates}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:44.303642Z","iopub.execute_input":"2025-08-08T07:37:44.304552Z","iopub.status.idle":"2025-08-08T07:37:44.648507Z","shell.execute_reply.started":"2025-08-08T07:37:44.304514Z","shell.execute_reply":"2025-08-08T07:37:44.645457Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"checking missing row (sequence_counter)","metadata":{}},{"cell_type":"markdown","source":"### checking correlation (orientation & imu)","metadata":{}},{"cell_type":"code","source":"filtered_df = train_df[train_df['sequence_counter'] == 0].copy()\nfiltered_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:37:44.652080Z","iopub.execute_input":"2025-08-08T07:37:44.654527Z","iopub.status.idle":"2025-08-08T07:37:45.052635Z","shell.execute_reply.started":"2025-08-08T07:37:44.654356Z","shell.execute_reply":"2025-08-08T07:37:45.047829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nimport torch\n\nle = LabelEncoder()\n\nfiltered_df['orientation'] = le.fit_transform(filtered_df['orientation'])\nfiltered_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:47:52.614908Z","iopub.execute_input":"2025-08-08T07:47:52.616216Z","iopub.status.idle":"2025-08-08T07:47:52.781668Z","shell.execute_reply.started":"2025-08-08T07:47:52.616065Z","shell.execute_reply":"2025-08-08T07:47:52.779987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMU_df = filtered_df[['orientation', 'acc_x', 'acc_y', 'acc_z', 'rot_w', 'rot_x', 'rot_y', 'rot_z',]]\nIMU_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:51:22.361756Z","iopub.execute_input":"2025-08-08T07:51:22.362760Z","iopub.status.idle":"2025-08-08T07:51:22.387664Z","shell.execute_reply.started":"2025-08-08T07:51:22.362696Z","shell.execute_reply":"2025-08-08T07:51:22.385836Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"correlation_matrix = IMU_df.corr()\nplt.figure(figsize=(15,10))\nsns.heatmap(\n    correlation_matrix,\n    annot=True,\n    fmt=\".2f\",\n    cmap='coolwarm',\n    cbar=True\n)\n\nplt.title('Correlation Heatmap')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:51:40.480128Z","iopub.execute_input":"2025-08-08T07:51:40.480570Z","iopub.status.idle":"2025-08-08T07:51:40.968248Z","shell.execute_reply.started":"2025-08-08T07:51:40.480538Z","shell.execute_reply":"2025-08-08T07:51:40.966307Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Predict orientation","metadata":{}},{"cell_type":"code","source":"orientation_df = train_df[['orientation', 'acc_x', 'acc_y', 'acc_z', 'rot_w', 'rot_x', 'rot_y', 'rot_z']]\norientation_df","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"orientation_df['orientation'] = le.fit_transform(orientation_df['orientation'])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import LSTM, Dense, Dropout\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.preprocessing import StandardScaler\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:55:56.978312Z","iopub.execute_input":"2025-08-08T07:55:56.978729Z","iopub.status.idle":"2025-08-08T07:56:31.780609Z","shell.execute_reply.started":"2025-08-08T07:55:56.978700Z","shell.execute_reply":"2025-08-08T07:56:31.778969Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 피처와 타겟 분리\nfeatures = orientation_df[['acc_x', 'acc_y', 'acc_z', 'rot_w', 'rot_x', 'rot_y', 'rot_z']]\ntarget = orientation_df['orientation']\n\n# 데이터 정규화\nscaler = StandardScaler()\nfeatures_scaled = scaler.fit_transform(features)\n\n# 시퀀스 데이터 생성 함수\ndef create_sequences(data, labels, time_steps):\n    X, y = [], []\n    for i in range(len(data) - time_steps):\n        X.append(data[i:(i + time_steps)])\n        y.append(labels[i + time_steps])\n    return np.array(X), np.array(y)\n\nTIME_STEPS = 25 # 시퀀스 길이\nX, y = create_sequences(features_scaled, target.values, TIME_STEPS)\n\n# 타겟 레이블 원-핫 인코딩\nnum_classes = len(np.unique(y))\ny_one_hot = to_categorical(y, num_classes=num_classes)\n\n# 학습/테스트 데이터 분리\nX_train, X_test, y_train, y_test = train_test_split(X, y_one_hot, test_size=0.2, random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:56:31.782994Z","iopub.execute_input":"2025-08-08T07:56:31.784360Z","iopub.status.idle":"2025-08-08T07:56:31.895341Z","shell.execute_reply.started":"2025-08-08T07:56:31.784302Z","shell.execute_reply":"2025-08-08T07:56:31.893534Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# LSTM 모델 구축\nmodel = Sequential()\nmodel.add(LSTM(units=64, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))\nmodel.add(Dropout(0.2))\nmodel.add(LSTM(units=64))\nmodel.add(Dropout(0.2))\nmodel.add(Dense(units=num_classes, activation='softmax'))\n\n# 모델 컴파일\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# 모델 학습\nhistory = model.fit(X_train, y_train, epochs=20, batch_size=32, validation_data=(X_test, y_test))\n\n# 모델 평가\nloss, accuracy = model.evaluate(X_test, y_test)\nprint(f\"Test Accuracy: {accuracy}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-08T07:56:31.896930Z","iopub.execute_input":"2025-08-08T07:56:31.897392Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}