Вы можете использовать Кластерный анализ .
Кластеризация - это способ разделения набора данных на похожие компоненты (подмножества). Концепция «сходства» предполагает некоторое определение «расстояния» между точками. Существует много обычных формул для расстояния, в том числе обычное евклидово расстояние.
Практический кейс
Прежде чем указать вам на причину сделки, давайте покажем практический пример вашей проблемы, чтобы вы могли принять участие в алгоритмах и пакетах или отказаться от них заранее.
Для простоты я смоделировал проблему в Mathematica, потому что Cluster Analysis включен в программное обеспечение и очень прост в настройке.
Сначала сгенерируйте данные. Формат: {ДЕНЬ, ВРЕМЯ НАЧАЛА, ВРЕМЯ КОНЦА}.
Для времени начала и окончания добавлена случайная величина (+ полчаса, ноль, -полчаса}, чтобы показать способность алгоритма справляться с "шумом".
Есть три дня, три смены в день и одна дополнительная (последняя) «аномальная» смена, которая начинается в 7 часов утра и заканчивается в 9 часов утра (бедные парни!).
В каждом "нормальном" изменении есть 150 событий и только два в исключительном.
Как видите, некоторые сдвиги не очень далеки друг от друга.
Я включаю код в Mathematica на случай, если у вас есть доступ к программному обеспечению. Я стараюсь избегать использования функционального синтаксиса, чтобы облегчить чтение кода для «иностранцев».
Вот код генерации данных:
Rn[] := 0.5 * RandomInteger[{-1, 1}];
monshft1 = Table[{ 1 , 10 + Rn[] , 15 + Rn[] }, {150}]; // 1
monshft2 = Table[{ 1 , 12 + Rn[] , 17 + Rn[] }, {150}]; // 2
wedshft1 = Table[{ 3 , 10 + Rn[] , 15 + Rn[] }, {150}]; // 3
wedshft2 = Table[{ 3 , 14 + Rn[] , 17 + Rn[] }, {150}]; // 4
frishft1 = Table[{ 5 , 10 + Rn[] , 15 + Rn[] }, {150}]; // 5
frishft2 = Table[{ 5 , 11 + Rn[] , 15 + Rn[] }, {150}]; // 6
monexcp = Table[{ 1 , 7 + Rn[] , 9 + Rn[] }, {2}]; // 7
Теперь мы объединяем данные, получая один большой набор данных:
data = Join[monshft1, monshft2, wedshft1, wedshft2, frishft1, frishft2, monexcp];
Давайте запустим кластерный анализ для данных:
clusters = FindClusters[data, 7, Method->{"Agglomerate","Linkage"->"Complete"}]
«Agglomerate» и «Linkage» -> «Complete» - это два варианта тонкой настройки методов кластеризации, реализованных в Mathematica. Они просто указывают, что мы пытаемся найти очень компактные кластеры.
Я указал, чтобы попытаться обнаружить 7 кластеров. Если нужное количество смен неизвестно, вы можете попробовать несколько приемлемых значений и посмотреть результаты или позволить алгоритму выбрать более подходящее значение.
Мы можем получить диаграмму с результатами, каждый кластер другого цвета (не обращайте внимания на код)
ListPointPlot3D[ clusters,
PlotStyle->{{PointSize[Large], Pink}, {PointSize[Large], Green},
{PointSize[Large], Yellow}, {PointSize[Large], Red},
{PointSize[Large], Black}, {PointSize[Large], Blue},
{PointSize[Large], Purple}, {PointSize[Large], Brown}},
AxesLabel -> {"DAY", "START TIME", "END TIME"}]
И результат:
альтернативный текст http://i28.tinypic.com/2hmdlab.png
Где вы можете видеть наши семь кластеров четко друг от друга.
Это решает часть вашей проблемы: определение данных. Теперь вы также хотите иметь возможность пометить его.
Итак, мы возьмем каждый кластер и возьмем среднее значение (округлено):
Table[Round[Mean[clusters[[i]]]], {i, 7}]
Результат:
Day Start End
{"1", "10", "15"},
{"1", "12", "17"},
{"3", "10", "15"},
{"3", "14", "17"},
{"5", "10", "15"},
{"5", "11", "15"},
{"1", "7", "9"}
И с этим вы снова получаете свои семь классов.
Теперь, возможно, вы хотите классифицировать смены, независимо от дня. Если одни и те же люди выполняют одно и то же задание каждый день в одно и то же время, то бесполезно называть это «смена понедельника с 10 до 15», потому что это происходит также по субботам и пятницам (как в нашем примере).
Давайте проанализируем данные без учета первого столбца:
clusters=
FindClusters[Take[data, All, -2],Method->{"Agglomerate","Linkage"->"Complete"}];
В этом случае мы не выбираем количество кластеров для извлечения, оставляя решение за пакетом.
Результат
изображение http://i27.tinypic.com/mise9.png
Вы можете видеть, что пять кластеров были идентифицированы.
Давайте попробуем «пометить» их, как раньше:
Grid[Table[Round[Mean[clusters[[i]]]], {i, 5}]]
Результат:
START END
{"10", "15"},
{"12", "17"},
{"14", "17"},
{"11", "15"},
{ "7", "9"}
Что именно мы и подозревали: каждый день в одно и то же время происходят повторяющиеся события, которые можно сгруппировать.
Редактировать: Ночные смены и нормализация
Если у вас есть (или вы планируете иметь) смены, которые начинаются один день и заканчиваются в следующий, лучше смоделировать
{Start-Day Start-Hour Length} // Correct!
чем
{Start-Day Start-Hour End-Day End-Hour} // Incorrect!
Это потому, что, как и в любом статистическом методе, корреляция между переменными должна быть сделана явной, иначе метод потерпит неудачу. Принцип может запускать что-то вроде «сохранить данные вашего кандидата в норме». Обе концепции почти одинаковы (атрибуты должны быть независимыми).
--- Редактировать конец ---
К настоящему времени, я думаю, вы прекрасно понимаете, какие вещи вы можете делать с таким анализом.
Некоторые ссылки
- Конечно, Википедия , ее "ссылки" и "дальнейшее чтение" являются хорошим руководством.
- Хорошее видео здесь , показывающее возможности Statsoft, но вы можете получить много идей о других вещах, которые вы можете сделать с помощью алгоритма.
- Здесь - основное объяснение задействованных алгоритмов
- Здесь вы можете найти впечатляющую функциональность R для ClusterАнализ ( R - ОЧЕНЬ хороший вариант)
- Наконец, здесь вы можете найти длинный список бесплатных и коммерческих программ для статистики в целом, включая кластеризацию.
HTH!