{"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":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport os\nfrom tqdm import tqdm\nimport warnings\nwarnings.filterwarnings('ignore')\n\nplt.style.use('fivethirtyeight')\nsns.set_palette(\"Set2\")\nplt.rcParams['figure.figsize'] = (12, 8)\nplt.rcParams['font.size'] = 12","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:27:16.493656Z","iopub.execute_input":"2025-06-24T20:27:16.494026Z","iopub.status.idle":"2025-06-24T20:27:16.510288Z","shell.execute_reply.started":"2025-06-24T20:27:16.494001Z","shell.execute_reply":"2025-06-24T20:27:16.509244Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv')\ntest_df = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv')\n\ntrain_demo_df = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/train_demographics.csv')\ntest_demo_df = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv')\n\ntrain_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:20:15.864543Z","iopub.execute_input":"2025-06-24T20:20:15.864923Z","iopub.status.idle":"2025-06-24T20:20:50.131342Z","shell.execute_reply.started":"2025-06-24T20:20:15.864894Z","shell.execute_reply":"2025-06-24T20:20:50.130224Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:21:36.023014Z","iopub.execute_input":"2025-06-24T20:21:36.023378Z","iopub.status.idle":"2025-06-24T20:21:36.052104Z","shell.execute_reply.started":"2025-06-24T20:21:36.023352Z","shell.execute_reply":"2025-06-24T20:21:36.050516Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Функция для вывода базовой информации о датафрейме\ndef analyze_dataframe(df, name):\n    print(f\"Анализ датафрейма {name}:\")\n    print(f\"Форма: {df.shape}\")\n    print(f\"Количество пропущенных значений: {df.isna().sum().sum()}\")\n    print(\"\\nТипы данных:\")\n    print(df.dtypes.value_counts())\n    print(\"\\nПримеры уникальных значений в некоторых столбцах:\")\n    \n    # Вывод уникальных значений для категориальных столбцов\n    for col in ['subject', 'behavior']:\n        if col in df.columns:\n            print(f\"{col}: {df[col].nunique()} уникальных значений\")\n            print(f\"Примеры: {df[col].unique()[:5]}\")\n    \n    # Дополнительно для тренировочного датасета\n    if 'gesture' in df.columns:\n        print(f\"gesture: {df['gesture'].nunique()} уникальных значений\")\n        print(f\"Распределение: \\n{df['gesture'].value_counts()}\")\n    \n    if 'sequence_type' in df.columns:\n        print(f\"sequence_type: {df['sequence_type'].nunique()} уникальных значений\")\n        print(f\"Распределение: \\n{df['sequence_type'].value_counts()}\")\n    \n    if 'orientation' in df.columns:\n        print(f\"orientation: {df['orientation'].nunique()} уникальных значений\")\n        print(f\"Примеры: {df['orientation'].unique()[:5]}\")\n\n# Анализ обоих датасетов\nanalyze_dataframe(train_df, \"train_df\")\nanalyze_dataframe(test_df, \"test_df\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:27:52.717034Z","iopub.execute_input":"2025-06-24T20:27:52.717438Z","iopub.status.idle":"2025-06-24T20:27:53.875653Z","shell.execute_reply.started":"2025-06-24T20:27:52.717413Z","shell.execute_reply":"2025-06-24T20:27:53.874435Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Визуализация распределения целевой переменной (только для train_df)\nplt.figure(figsize=(14, 6))\nsns.countplot(y='gesture', data=train_df, order=train_df['gesture'].value_counts().index)\nplt.title('Распределение жестов (целевая переменная)')\nplt.tight_layout()\nplt.show()\n\n\n# Распределение по ориентации\nif 'orientation' in train_df.columns:\n    plt.figure(figsize=(14, 5))\n    sns.countplot(y='orientation', data=train_df, order=train_df['orientation'].value_counts().index)\n    plt.title('Распределение по ориентации')\n    plt.tight_layout()\n    plt.show()\n\n# Распределение по поведению\nplt.figure(figsize=(14, 5))\nsns.countplot(y='behavior', data=train_df, order=train_df['behavior'].value_counts().index)\nplt.title('Распределение по поведению')\nplt.tight_layout()\nplt.show()\n\n# Распределение по типу последовательности\nif 'sequence_type' in train_df.columns:\n    plt.figure(figsize=(14, 4))\n    sns.countplot(x='sequence_type', data=train_df)\n    plt.title('Распределение по типу последовательности')\n    plt.show()\n\n# Распределение по субъектам\nplt.figure(figsize=(14, 4))\nsns.countplot(x='subject', data=train_df)\nplt.title('Распределение по субъектам')\nplt.xticks(rotation=90)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:32:26.769776Z","iopub.execute_input":"2025-06-24T20:32:26.771972Z","iopub.status.idle":"2025-06-24T20:32:29.863043Z","shell.execute_reply.started":"2025-06-24T20:32:26.771920Z","shell.execute_reply":"2025-06-24T20:32:29.861865Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Анализ числовых данных акселерометра\nplt.figure(figsize=(18, 6))\n\nplt.subplot(1, 3, 1)\nsns.histplot(train_df['acc_x'], kde=True)\nplt.title('Распределение acc_x')\n\nplt.subplot(1, 3, 2)\nsns.histplot(train_df['acc_y'], kde=True)\nplt.title('Распределение acc_y')\n\nplt.subplot(1, 3, 3)\nsns.histplot(train_df['acc_z'], kde=True)\nplt.title('Распределение acc_z')\n\nplt.tight_layout()\nplt.show()\n\n# Анализ данных вращения\nplt.figure(figsize=(20, 5))\n\nplt.subplot(1, 4, 1)\nsns.histplot(train_df['rot_w'], kde=True)\nplt.title('Распределение rot_w')\n\nplt.subplot(1, 4, 2)\nsns.histplot(train_df['rot_x'], kde=True)\nplt.title('Распределение rot_x')\n\nplt.subplot(1, 4, 3)\nsns.histplot(train_df['rot_y'], kde=True)\nplt.title('Распределение rot_y')\n\nplt.subplot(1, 4, 4)\nsns.histplot(train_df['rot_z'], kde=True)\nplt.title('Распределение rot_z')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:32:55.024040Z","iopub.execute_input":"2025-06-24T20:32:55.024392Z","iopub.status.idle":"2025-06-24T20:33:17.914139Z","shell.execute_reply.started":"2025-06-24T20:32:55.024369Z","shell.execute_reply":"2025-06-24T20:33:17.913018Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Анализ данных термопилей\nthm_cols = [col for col in train_df.columns if col.startswith('thm_')]\nplt.figure(figsize=(18, 6))\n\nfor i, col in enumerate(thm_cols, 1):\n    plt.subplot(1, 5, i)\n    sns.histplot(train_df[col], kde=True)\n    plt.title(f'Распределение {col}')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:34:51.399462Z","iopub.execute_input":"2025-06-24T20:34:51.400272Z","iopub.status.idle":"2025-06-24T20:35:08.355898Z","shell.execute_reply.started":"2025-06-24T20:34:51.400237Z","shell.execute_reply":"2025-06-24T20:35:08.354589Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Анализ зависимости acc_x, acc_y, acc_z от жеста\nplt.figure(figsize=(20, 15))\n\nplt.subplot(1, 3, 1)\nsns.boxplot(x='gesture', y='acc_x', data=train_df)\nplt.title('acc_x по жестам')\nplt.xticks(rotation=90)\n\nplt.subplot(1, 3, 2)\nsns.boxplot(x='gesture', y='acc_y', data=train_df)\nplt.title('acc_y по жестам')\nplt.xticks(rotation=90)\n\nplt.subplot(1, 3, 3)\nsns.boxplot(x='gesture', y='acc_z', data=train_df)\nplt.title('acc_z по жестам')\nplt.xticks(rotation=90)\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:38:02.482236Z","iopub.execute_input":"2025-06-24T20:38:02.482546Z","iopub.status.idle":"2025-06-24T20:38:05.261323Z","shell.execute_reply.started":"2025-06-24T20:38:02.482525Z","shell.execute_reply":"2025-06-24T20:38:05.260340Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Анализ ToF сенсоров (выборка первых пикселей для каждого сенсора)\ntof_sample_cols = ['tof_1_v0', 'tof_2_v0', 'tof_3_v0', 'tof_4_v0', 'tof_5_v0']\nplt.figure(figsize=(18, 6))\n\nfor i, col in enumerate(tof_sample_cols, 1):\n    plt.subplot(1, 5, i)\n    # Исключаем -1 (отсутствие отражения)\n    valid_data = train_df[train_df[col] != -1][col]\n    sns.histplot(valid_data, kde=True)\n    plt.title(f'Распределение {col} (без -1)')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:39:08.603429Z","iopub.execute_input":"2025-06-24T20:39:08.603785Z","iopub.status.idle":"2025-06-24T20:39:18.652264Z","shell.execute_reply.started":"2025-06-24T20:39:08.603757Z","shell.execute_reply":"2025-06-24T20:39:18.650842Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Визуализация данных ToF для одного примера\ndef visualize_tof_sensor(df, sequence_id, sensor_num, frame_idx=0):\n    \"\"\"\n    Визуализирует данные ToF сенсора для конкретного примера\n    \n    Args:\n        df: DataFrame с данными\n        sequence_id: ID последовательности\n        sensor_num: Номер сенсора (1-5)\n        frame_idx: Индекс кадра в последовательности\n    \"\"\"\n    # Выбираем данные для конкретной последовательности и кадра\n    seq_data = df[(df['sequence_id'] == sequence_id)]\n    if len(seq_data) == 0:\n        print(f\"Последовательность {sequence_id} не найдена\")\n        return\n    \n    frame_data = seq_data.iloc[frame_idx]\n    \n    # Получаем все пиксели для выбранного сенсора\n    tof_cols = [f'tof_{sensor_num}_v{i}' for i in range(64)]\n    tof_values = frame_data[tof_cols].values\n    \n    # Преобразуем в числовой формат и заменяем -1 на NaN\n    tof_values = tof_values.astype(float)\n    tof_values = np.where(tof_values == -1, np.nan, tof_values)\n    \n    # Формируем матрицу 8x8\n    tof_data = tof_values.reshape(8, 8)\n    \n    plt.figure(figsize=(8, 6))\n    \n    # Используем imshow вместо heatmap для лучшей работы с NaN значениями\n    im = plt.imshow(tof_data, cmap='viridis')\n    plt.colorbar(im, label='Значение')\n    \n    # Добавляем аннотации (только для непустых значений)\n    for i in range(8):\n        for j in range(8):\n            value = tof_data[i, j]\n            if not np.isnan(value):\n                plt.text(j, i, f'{int(value)}', ha='center', va='center', \n                         color='white' if value > 100 else 'black')\n    \n    # Добавляем информацию о жесте, если доступна\n    title = f'ToF сенсор {sensor_num}, последовательность {sequence_id}, кадр {frame_idx}'\n    if 'gesture' in df.columns:\n        gesture = frame_data.get('gesture', 'Н/Д')\n        title += f', жест: {gesture}'\n    \n    plt.title(title)\n    plt.show()\n\n# Визуализируем данные ToF для первой последовательности в train_df\nfirst_sequence = train_df['sequence_id'].iloc[0]\nfor sensor in range(1, 6):\n    visualize_tof_sensor(train_df, first_sequence, sensor)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T21:04:07.305984Z","iopub.execute_input":"2025-06-24T21:04:07.307154Z","iopub.status.idle":"2025-06-24T21:04:09.699221Z","shell.execute_reply.started":"2025-06-24T21:04:07.307104Z","shell.execute_reply":"2025-06-24T21:04:09.697903Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Анализ временных рядов для одной последовательности\ndef plot_sequence_timeseries(df, sequence_id):\n    \"\"\"\n    Строит временные ряды для одной последовательности\n    \n    Args:\n        df: DataFrame с данными\n        sequence_id: ID последовательности\n    \"\"\"\n    seq_data = df[df['sequence_id'] == sequence_id].copy()\n    if len(seq_data) == 0:\n        print(f\"Последовательность {sequence_id} не найдена\")\n        return\n    \n    seq_data = seq_data.sort_values('sequence_counter')\n    \n    # Информация о последовательности\n    if 'gesture' in seq_data.columns:\n        gesture = seq_data['gesture'].iloc[0]\n        print(f\"Последовательность {sequence_id}, жест: {gesture}\")\n    \n    # График акселерометра\n    plt.figure(figsize=(14, 10))\n    \n    plt.subplot(2, 1, 1)\n    plt.plot(seq_data['sequence_counter'], seq_data['acc_x'], label='acc_x')\n    plt.plot(seq_data['sequence_counter'], seq_data['acc_y'], label='acc_y')\n    plt.plot(seq_data['sequence_counter'], seq_data['acc_z'], label='acc_z')\n    plt.title(f'Данные акселерометра для последовательности {sequence_id}')\n    plt.xlabel('Счетчик последовательности')\n    plt.ylabel('Ускорение (м/с²)')\n    plt.legend()\n    \n    # График вращения\n    plt.subplot(2, 1, 2)\n    plt.plot(seq_data['sequence_counter'], seq_data['rot_w'], label='rot_w')\n    plt.plot(seq_data['sequence_counter'], seq_data['rot_x'], label='rot_x')\n    plt.plot(seq_data['sequence_counter'], seq_data['rot_y'], label='rot_y')\n    plt.plot(seq_data['sequence_counter'], seq_data['rot_z'], label='rot_z')\n    plt.title(f'Данные вращения для последовательности {sequence_id}')\n    plt.xlabel('Счетчик последовательности')\n    plt.ylabel('Вращение')\n    plt.legend()\n    \n    plt.tight_layout()\n    plt.show()\n    \n    # График термопилей\n    plt.figure(figsize=(14, 6))\n    for col in thm_cols:\n        plt.plot(seq_data['sequence_counter'], seq_data[col], label=col)\n    plt.title(f'Данные термопилей для последовательности {sequence_id}')\n    plt.xlabel('Счетчик последовательности')\n    plt.ylabel('Температура (°C)')\n    plt.legend()\n    plt.tight_layout()\n    plt.show()\n\n# Визуализируем временные ряды для нескольких последовательностей\nif 'gesture' in train_df.columns:\n    # Выберем по одной последовательности для каждого жеста\n    for gesture in train_df['gesture'].unique():\n        seq_id = train_df[train_df['gesture'] == gesture]['sequence_id'].iloc[0]\n        plot_sequence_timeseries(train_df, seq_id)\n\n# Анализ зависимости между поведением и жестом\nif 'gesture' in train_df.columns and 'behavior' in train_df.columns:\n    plt.figure(figsize=(16, 12))\n    behavior_gesture = pd.crosstab(train_df['behavior'], train_df['gesture'], normalize='index')\n    sns.heatmap(behavior_gesture, annot=True, cmap='YlGnBu', fmt='.2f')\n    plt.title('Зависимость между поведением и жестом')\n    plt.tight_layout()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T20:45:33.697604Z","iopub.execute_input":"2025-06-24T20:45:33.698014Z","iopub.status.idle":"2025-06-24T20:45:55.428577Z","shell.execute_reply.started":"2025-06-24T20:45:33.697988Z","shell.execute_reply":"2025-06-24T20:45:55.427252Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# PCA для визуализации данных ToF\nfrom sklearn.decomposition import PCA\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.impute import SimpleImputer\n\ndef visualize_tof_pca(df, n_samples=1000):\n    \"\"\"\n    Применяет PCA к данным ToF для визуализации\n    \n    Args:\n        df: DataFrame с данными\n        n_samples: Количество образцов для анализа\n    \"\"\"\n    if len(df) > n_samples:\n        df_sample = df.sample(n_samples, random_state=42)\n    else:\n        df_sample = df\n    \n    # Собираем все данные ToF\n    tof_cols = [col for col in df.columns if col.startswith('tof_')]\n    \n    # Заменяем -1 на 0 для PCA\n    tof_data = df_sample[tof_cols].replace(-1, 0)\n    \n    # Проверяем наличие NaN и заменяем их на 0\n    if tof_data.isna().any().any():\n        print(\"Обнаружены пропущенные значения в данных ToF. Заменяем их на 0.\")\n        imputer = SimpleImputer(strategy='constant', fill_value=0)\n        tof_data = pd.DataFrame(\n            imputer.fit_transform(tof_data),\n            columns=tof_data.columns\n        )\n    \n    # Нормализация данных\n    scaler = StandardScaler()\n    tof_scaled = scaler.fit_transform(tof_data)\n    \n    # Применяем PCA\n    pca = PCA(n_components=2)\n    tof_pca = pca.fit_transform(tof_scaled)\n    \n    # Создаем DataFrame для визуализации\n    pca_df = pd.DataFrame({\n        'PC1': tof_pca[:, 0],\n        'PC2': tof_pca[:, 1]\n    })\n    \n    # Добавляем информацию о жесте, если доступна\n    if 'gesture' in df.columns:\n        pca_df['gesture'] = df_sample['gesture'].values\n        \n        plt.figure(figsize=(12, 10))\n        sns.scatterplot(x='PC1', y='PC2', hue='gesture', data=pca_df, palette='viridis', alpha=0.7)\n        plt.title('PCA данных ToF по жестам')\n        plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')\n        plt.tight_layout()\n        plt.show()\n    else:\n        plt.figure(figsize=(10, 8))\n        sns.scatterplot(x='PC1', y='PC2', data=pca_df, alpha=0.7)\n        plt.title('PCA данных ToF')\n        plt.tight_layout()\n        plt.show()\n    \n    print(f\"Объясненная дисперсия: {pca.explained_variance_ratio_}\")\n\n\n# Применяем PCA к данным ToF\nvisualize_tof_pca(train_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T21:09:08.692492Z","iopub.execute_input":"2025-06-24T21:09:08.692861Z","iopub.status.idle":"2025-06-24T21:09:10.071323Z","shell.execute_reply.started":"2025-06-24T21:09:08.692837Z","shell.execute_reply":"2025-06-24T21:09:10.069579Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Статистика по длине последовательностей\nsequence_lengths = train_df.groupby('sequence_id').size()\nplt.figure(figsize=(12, 6))\nsns.histplot(sequence_lengths, kde=True)\nplt.title('Распределение длин последовательностей')\nplt.xlabel('Длина последовательности')\nplt.ylabel('Количество')\nplt.show()\n\nprint(f\"Средняя длина последовательности: {sequence_lengths.mean():.2f}\")\nprint(f\"Минимальная длина последовательности: {sequence_lengths.min()}\")\nprint(f\"Максимальная длина последовательности: {sequence_lengths.max()}\")\n\n# Анализ зависимости длины последовательности от жеста\nif 'gesture' in train_df.columns:\n    # Получаем длину каждой последовательности и соответствующий жест\n    sequence_info = train_df.groupby('sequence_id').agg({\n        'gesture': 'first',\n        'sequence_id': 'count'\n    }).rename(columns={'sequence_id': 'length'})\n    \n    plt.figure(figsize=(14, 12))\n    sns.boxplot(x='gesture', y='length', data=sequence_info)\n    plt.title('Длина последовательности по жестам')\n    plt.xticks(rotation=90)\n    plt.tight_layout()\n    plt.show()\n\n# Сводная статистика по числовым признакам\nprint(\"\\nСводная статистика по числовым признакам:\")\nnumeric_cols = train_df.select_dtypes(include=['number']).columns\nprint(train_df[numeric_cols].describe().T)\n\n# Анализ пропущенных значений\nplt.figure(figsize=(12, 6))\nmissing_values = train_df.isna().sum().sort_values(ascending=False)\nmissing_values = missing_values[missing_values > 0]\nif len(missing_values) > 0:\n    sns.barplot(x=missing_values.index, y=missing_values.values)\n    plt.title('Количество пропущенных значений по столбцам')\n    plt.xticks(rotation=90)\n    plt.tight_layout()\n    plt.show()\nelse:\n    print(\"В датасете нет пропущенных значений.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T21:02:33.479131Z","iopub.execute_input":"2025-06-24T21:02:33.479473Z","iopub.status.idle":"2025-06-24T21:02:48.424397Z","shell.execute_reply.started":"2025-06-24T21:02:33.479450Z","shell.execute_reply":"2025-06-24T21:02:48.423023Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}