Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Кластеризация физической активности по данным IMU-сенсоров

Проект решает задачу безразметочной кластеризации временных сенсорных данных: каждой строке исходного датасета присваивается метка типа физической активности (activityID) на основе паттернов движения, зафиксированных тремя IMU-модулями (hand, chest, ankle).

Основной артефакт — Jupyter Notebook solved.ipynb с полным пайплайном: EDA, feature engineering, сравнение моделей и формирование файла submission.csv для отправки на Kaggle.

Задача

  • Вход: последовательные измерения аксelerometра, гироскопа, magnetometer, orientation и температуры с трёх точек тела.
  • Выход: CSV с колонками Index и activityID для всех 534 601 строк.
  • Особенность: активность определяется не одним измерением, а локальным временным паттерном, поэтому кластеризация выполняется на окнах из 64 строк, после чего метки переносятся обратно на исходные строки.

Структура репозитория

clustering_ml/
├── solved.ipynb                              # основной ноутбук с решением
├── Physical_Activity_Monitoring_unlabeled.csv # исходные данные (не в git, см. ниже)
├── submission.csv                            # итоговая разметка
├── image.png                                 # скриншот результата на Kaggle
├── pyproject.toml                            # зависимости проекта
├── uv.lock                                   # lock-файл uv
└── README.md

Данные

Параметр Значение
Файл Physical_Activity_Monitoring_unlabeled.csv
Строк 534 601
Столбцов 53 (+ технический Index после загрузки)
Участники 8 (subject_id от 1 до 8)
Сенсоры hand, chest, ankle (acc ±16g/±6g, gyro, magne, orientation, temperature)

Файл не включён в репозиторий (230+ MB, лимит GitHub — 100 MB). Скачайте его с Kaggle и положите в корень проекта, либо подключите датасет в Kaggle Notebook — ноутбук ищет файл локально и в /kaggle/input.

Пайплайн

flowchart LR
    A[CSV 534k строк] --> B[Feature engineering]
    B --> C[Интерполяция пропусков]
    C --> D[Окна 64 строки]
    D --> E[RobustScaler + PCA]
    E --> F[MiniBatchKMeans k=12]
    F --> G[Сглаживание сегментов]
    G --> H[submission.csv]
Loading
  1. Предобработка: сортировка по времени, интерполяция пропусков внутри subject_id, обработка ±inf.
  2. Feature engineering: 3D-нормы acc/gyro/magne/orientation, временные разности, rolling mean/std (окна 16 и 64), протокольные признаки (позиция в записи, номер сессии).
  3. Оконная агрегация: 8 374 окна × 1 171 признак (mean, std, min, max, median).
  4. Масштабирование: VarianceThreshold → RobustScaler → PCA (32 компоненты, 95.7% дисперсии) + StandardScaler для временных признаков.
  5. Кластеризация: MiniBatchKMeans, n_clusters=12.
  6. Постобработка: сглаживание одиночных коротких сегментов, перенос меток на строки, перенумерация в activityID 1–10.

Модели

На подвыборке 3 000 окон сравнивались:

Алгоритм Silhouette (k=12) Примечание
KMeans 0.292 лучший silhouette среди partition-моделей
MiniBatchKMeans 0.254 финальная модель — масштабируется на все окна
Agglomerative (average) 0.519 высокий silhouette, но O(n²) по памяти
DBSCAN до 0.905 до 99.3% точек помечены как шум
GaussianMixture 0.191 наихудший результат на subsample

Метрики финальной модели (8 374 окна, sample 5 000):

  • Silhouette: 0.270
  • Calinski–Harabasz: 6538
  • Davies–Bouldin: 1.241

Ключевые гиперпараметры

Задаются в начале solved.ipynb:

Параметр Значение Назначение
EXPECTED_N_CLUSTERS 12 число кластеров модели
WINDOW_SIZE 64 размер временного окна (строк)
PCA_N_COMPONENTS 32 число PCA-компонент
TIME_FEATURE_WEIGHT 1.5 вес протокольных признаков
MIN_SEGMENT_WINDOWS 2 порог сглаживания коротких сегментов
RANDOM_STATE 42 воспроизводимость

Установка и запуск

Требуется Python ≥ 3.12.10.

Через uv (рекомендуется)

# установка uv: https://docs.astral.sh/uv/
uv sync
uv pip install ipykernel jupyter   # для запуска ноутбука
uv run jupyter notebook solved.ipynb

Через pip

python -m venv .venv
.venv\Scripts\activate          # Windows
# source .venv/bin/activate     # Linux / macOS

pip install -e .
pip install ipykernel jupyter
jupyter notebook solved.ipynb

Запустите все ячейки ноутбука сверху вниз. В конце будет создан или перезаписан submission.csv.

Формат submission

Index,activityID
0,1
1,2
...
  • Index — порядковый номер строки в исходном CSV (0 … 534 600).
  • activityID — метка кластера, целое число от 1 до 10.

Результат на Kaggle

Файл submission.csv отправлен на соревнование Kaggle. Лучший результат:

Показатель Значение
Score 0.69634
Место в leaderboard 16
Участник Ryabov Alexandr
Число отправок 13

Результат на Kaggle — место 16, score 0.69634

Ограничения

  • В обучающих данных нет ground-truth меток — качество оценивается только внутренними метриками и на Kaggle leaderboard.
  • Модель обучается с k = 12, но после постобработки в submission остаётся 10 устойчивых кластеров (singleton-сегменты сглаживаются).
  • «Спокойные» кластеры схожи по сырым нормам acc; разделение опирается на оконные rolling-статистики и PCA-признаки.
  • Колонка пульсометра в текущем CSV отсутствует, хотя упоминается в описании задачи.

Зависимости

Полный список — в pyproject.toml.

About

Безразметочная кластеризация физической активности по IMU-сенсорам: 534k строк, оконная агрегация, PCA + MiniBatchKMeans. 16 место на Kaggle

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages