Решение учебной задачи по кластеризации сигналов сцинтилляционного детектора для Kaggle-соревнования Signal types classification.
Дан набор из 23 479 сигналов, полученных со сцинтилляционного детектора. Каждый сигнал представлен набором временных отсчётов. Нужно без использования размеченных ответов разделить сигналы на 3 кластера:
- два кластера соответствуют двум основным физическим типам сигналов, например гамма-квантам и нейтронам;
- третий кластер соответствует аномальным, смешанным или неоднозначным сигналам.
Так как задача решается методами обучения без учителя, номера кластеров условны. В ноутбуке отдельно объясняется, как интерпретировать полученные группы и почему требуется согласование номеров кластеров для корректного Kaggle submission.
Финальное решение: aligned_tail15_pca7_kmeans
Public score на Kaggle: 0.84083
Финальный pipeline:
- Загрузка данных из
Run200_Wave_0_1.txt. - Отделение служебных столбцов от временных отсчётов сигнала.
- Вычитание baseline по первым 50 отсчётам.
- Разворот импульсов вверх.
- Выделение 15 отсчётов хвоста, начиная с максимума сигнала.
- Нормировка хвоста на собственный максимум.
- Масштабирование через
StandardScaler. - PCA на 7 компонент.
- KMeans на 3 кластера.
- Согласование номеров кластеров с устойчивым reference-решением.
- Формирование одного финального
submission.csv.
.
├── Run200_Wave_0_1.txt # исходные данные
├── signal_clustering.ipynb # финальный ноутбук с решением
├── submission.csv # итоговый файл для Kaggle
├── pyproject.toml # зависимости проекта
├── uv.lock # lock-файл окружения
└── scripts/ # вспомогательные скрипты экспериментов
Основной файл для проверки: signal_clustering.ipynb.
Ноутбук приведён к финальной линейной структуре:
- Постановка задачи.
- Импорты и настройки.
- Загрузка данных.
- EDA.
- Предобработка данных.
- Feature Engineering и подготовка признаков.
- PCA.
- Сравнение моделей.
- Финальная модель.
- Интерпретация кластеров.
- Создание
submission.csv. - Общие выводы.
В ноутбуке оставлены только те шаги, которые нужны для объяснения и воспроизведения финального решения. Черновые переборы и альтернативные submission-файлы не используются в финальной секции.
В ходе анализа проверены:
- размерность данных;
- пропуски и дубликаты;
- базовые статистики временных отсчётов;
- распределение baseline и амплитуды;
- примеры исходных и обработанных сигналов;
- корреляции между временными отсчётами;
- диагностические признаки формы сигнала.
Основной вывод EDA: временные отсчёты сильно коррелируют, а полезная информация для разделения сигналов находится не только в амплитуде, но и в форме хвоста после максимума. Поэтому в финальном решении используется компактное PCA-представление нормированного хвоста сигнала.
В работе сравнивались несколько подходов:
- KMeans на ручных признаках формы;
- KMeans на PCA-признаках хвоста;
- Gaussian Mixture Model;
- двухэтапная кластеризация с выделением аномалий.
Лучшим по сочетанию простоты, устойчивости, интерпретируемости и результата на Kaggle оказался KMeans на PCA-представлении хвоста сигнала. GMM и двухэтапная схема дали хуже результат на leaderboard, поэтому в финальную модель не вошли.
Полученные группы интерпретируются осторожно, так как истинных меток в данных нет:
- два крупных кластера можно рассматривать как два основных типа сигналов;
- меньший кластер можно рассматривать как группу аномальных, смешанных или неоднозначных сигналов;
- различия между кластерами видны по средней форме хвоста и PSD-like диагностическим признакам.
В работе не утверждается, что конкретный номер кластера строго соответствует гамма-квантам или нейтронам. Такая физическая привязка требует размеченных данных или дополнительной экспертной проверки.
Проект использует Python >=3.10 и зависимости из pyproject.toml.
Установка зависимостей:
uv syncЗапуск Jupyter:
uv run jupyter labВыполнение ноутбука из командной строки:
uv run jupyter nbconvert --to notebook --execute signal_clustering.ipynb --output signal_clustering_executed.ipynbПосле выполнения ноутбука в корне проекта создаётся файл:
submission.csv
Он содержит две колонки:
index, cluster
Задача кластеризации сигналов решена методами обучения без учителя. Финальное решение использует форму хвоста сигнала после максимума, PCA для снижения размерности и KMeans для разбиения на три группы. Такой подход даёт воспроизводимый результат, хорошо согласуется с физической постановкой задачи и позволяет содержательно интерпретировать два основных типа сигналов и отдельную группу неоднозначных объектов.
