Не так давно я рассказывал о том, как создать простое облако тегов для сайта (блога) и думал, что обо всех основных принципах рассказал. Но неожиданно (для меня ) тема получила продолжение. Началось все с комментария автора блога От новичка до профессионала (имени я, к сожалению, не нашел). Он рассказал, что написал похожий пост и от Сергея Олейника получил ссылку на очень интересную статью. Я кратко поясню, в чем основной недостаток облака тегов. Представьте, что у вас есть парочка тегов, которые вы используете очень часто и несколько других тегов, которые встречаются от случая к случаю. Каким шрифтом будут написаны имена тегов? Очевидно, что самые популярные теги будут написаны самым большим шрифтом, а остальные – самым мелким. Чтобы наглядно проиллюстрировать проблему я изменил частоту появления тегов в прошлом примере и сделал скриншот (число в скобках указываем количество использований тега). Как видите, тег PHP встречается в 2 раза чаще, чем JAVA, но отображаются они практически одинаковым шрифтом. И если убрать цифры в скобках, то будет очень сложно сказать, что тег PHP в два раза популярнее. Естественно, у этой проблемы существует решение и называется оно – кластеризация. Идея следующая. Нужно разбить все теги на группы (кластеры) по частоте их использования и изменять размер шрифта для каждой группы отдельно. Сами группы нужно будет как-нибудь визуально разделить. Например, показывать в отдельных блоках или выделить цветом. Вариантов масса. Для нашего примера очевидно, что теги AJAX и JavaScript должны находиться в одной группе, а PHP, Java и HTML – в другой. Кроме того, это разбиение на группы можно использовать и в SEO’шных целях.
Например, есть у вас в блоге 20 постов. Допустим, для каждого вы задали по 2-3 общих тега и по 5 уникальных. Разбиваем все теги на две группы (общие теги будут сгруппированы отдельно от уникальных, т. к. встречаются значительно чаще) и формируем два облака. Естественно, облака нужно показывать в табах и, по-умолчанию, должен быть открыт таб с общими тегами. Пример табов можно посмотреть у меня в сайдбаре. Таким образом, получается более 100 ссылок на страницы второго уровня, но посетитель (модератор) видит только общие теги (маленькое облако) такое же, как на большинстве «белых» сайтов. Чтобы увидеть остальные ссылки ему придется кликнуть по заголовку таба с уникальными тегами (большим облаком). Вроде бы идея простая, но, алгоритм разделения немного сложнее. В данном случае удобнее всего использовать т. н. K-means algorithm (алгоритм k-means (иногда называют k-средних)).
Принцип работы алгоритма изображен на диаграмме. 1) Задаем количество кластеров (групп). 2) Для каждой группы создаем центр масс. Это обычное число, которое связано с параметрами группы, по которым выполняется разбиение. В данном случае параметр один – частота использования тега. Для первой и последней групп в качестве начального значения центра масс я задал минимальную и максимальную частоту использования тегов, соответственно. Все остальные центры масс (если групп больше двух) я равномерно распределил между первым и последним. 3) Определяем расстояния от каждого центра масс до каждого тега. Нет, линейку брать не нужно . Достаточно отнять количество использований тега от центра масс. 4) Группируем теги в кластеры. Принцип простой.
Находим, какой центр масс находится ближе всего от заданного тега. В этот кластер тег и добавляем. 5) Пересчитываем значения центров масс. Для этого определяем среднее значение частоты использования всех тегов, которые вошли в кластер на предыдущем этапе. 6) Повторяем пункты 3-5. 7) Алгоритм завершается, когда распределение тегов по кластерам перестает изменяться. Подробнее об этом алгоритме можно почитать в этой статье. О недостатках этого алгоритма я расскажу чуть ниже, а сейчас взгляните на исходный код: