Недавно было проведено исследование взрослых, которые много играли в игры про покемонов в детстве. МРТ-сканирование выявило целую область в их мозгу, предназначенную для распознавания покемонов. По словам первого автора исследования Джесси Гомеса, игры про покемонов вознаграждают вас за индивидуализацию сотен персонажей, что было бы невозможно без специального региона.

Правда в том, что у каждого покемона есть свои характеристики, такие как способности, внешний вид, имя и многое другое. Это создает огромную проблему для осмысленной группировки данных о покемонах. Техники уменьшения размерности — отличная альтернатива для визуализации данных и проверки правильности нашего выбора для группировки.

В этой статье я собираюсь использовать RStudio, чтобы применить несколько методов уменьшения размерности и попытаться создать осмысленные низкоразмерные визуализации данных о покемонах. Полный код доступен на GitHub. Во-первых, нам нужно скачать Набор данных покемонов на Kaggle.

Нам нужно загрузить некоторые библиотеки, которые мы будем использовать во время этой работы.

А затем прочитайте и исследуйте набор данных.

OUTPUT
 abilities          against_bug      against_dark   against_dragon  
 Length:801         Min.   :0.2500   Min.   :0.250   Min.   :0.0000  
 Class :character   1st Qu.:0.5000   1st Qu.:1.000   1st Qu.:1.0000  
 Mode  :character   Median :1.0000   Median :1.000   Median :1.0000  
                    Mean   :0.9963   Mean   :1.057   Mean   :0.9688  
                    3rd Qu.:1.0000   3rd Qu.:1.000   3rd Qu.:1.0000  
                    Max.   :4.0000   Max.   :4.000   Max.   :2.0000  
                                                                     
 against_electric against_fairy   against_fight    against_fire  
 Min.   :0.000    Min.   :0.250   Min.   :0.000   Min.   :0.250  
 1st Qu.:0.500    1st Qu.:1.000   1st Qu.:0.500   1st Qu.:0.500  
 Median :1.000    Median :1.000   Median :1.000   Median :1.000  
 Mean   :1.074    Mean   :1.069   Mean   :1.066   Mean   :1.135  
 3rd Qu.:1.000    3rd Qu.:1.000   3rd Qu.:1.000   3rd Qu.:2.000  
 Max.   :4.000    Max.   :4.000   Max.   :4.000   Max.   :4.000  
                                                                 
 against_flying  against_ghost   against_grass   against_ground 
 Min.   :0.250   Min.   :0.000   Min.   :0.250   Min.   :0.000  
 1st Qu.:1.000   1st Qu.:1.000   1st Qu.:0.500   1st Qu.:1.000  
 Median :1.000   Median :1.000   Median :1.000   Median :1.000  
 Mean   :1.193   Mean   :0.985   Mean   :1.034   Mean   :1.098  
 3rd Qu.:1.000   3rd Qu.:1.000   3rd Qu.:1.000   3rd Qu.:1.000  
 Max.   :4.000   Max.   :4.000   Max.   :4.000   Max.   :4.000  
                                                                
  against_ice    against_normal  against_poison   against_psychic
 Min.   :0.250   Min.   :0.000   Min.   :0.0000   Min.   :0.000  
 1st Qu.:0.500   1st Qu.:1.000   1st Qu.:0.5000   1st Qu.:1.000  
 Median :1.000   Median :1.000   Median :1.0000   Median :1.000  
 Mean   :1.208   Mean   :0.887   Mean   :0.9753   Mean   :1.005  
 3rd Qu.:2.000   3rd Qu.:1.000   3rd Qu.:1.0000   3rd Qu.:1.000  
 Max.   :4.000   Max.   :1.000   Max.   :4.0000   Max.   :4.000  
                                                                 
  against_rock  against_steel    against_water       attack      
 Min.   :0.25   Min.   :0.2500   Min.   :0.250   Min.   :  5.00  
 1st Qu.:1.00   1st Qu.:0.5000   1st Qu.:0.500   1st Qu.: 55.00  
 Median :1.00   Median :1.0000   Median :1.000   Median : 75.00  
 Mean   :1.25   Mean   :0.9835   Mean   :1.058   Mean   : 77.86  
 3rd Qu.:2.00   3rd Qu.:1.0000   3rd Qu.:1.000   3rd Qu.:100.00  
 Max.   :4.00   Max.   :4.0000   Max.   :4.000   Max.   :185.00  
                                                                 
 base_egg_steps  base_happiness     base_total    capture_rate      
 Min.   : 1280   Min.   :  0.00   Min.   :180.0   Length:801        
 1st Qu.: 5120   1st Qu.: 70.00   1st Qu.:320.0   Class :character  
 Median : 5120   Median : 70.00   Median :435.0   Mode  :character  
 Mean   : 7191   Mean   : 65.36   Mean   :428.4                     
 3rd Qu.: 6400   3rd Qu.: 70.00   3rd Qu.:505.0                     
 Max.   :30720   Max.   :140.00   Max.   :780.0                     
                                                                    
 classfication         defense       experience_growth
 Length:801         Min.   :  5.00   Min.   : 600000  
 Class :character   1st Qu.: 50.00   1st Qu.:1000000  
 Mode  :character   Median : 70.00   Median :1000000  
                    Mean   : 73.01   Mean   :1054996  
                    3rd Qu.: 90.00   3rd Qu.:1059860  
                    Max.   :230.00   Max.   :1640000  
                                                      
    height_m            hp         japanese_name     
 Min.   : 0.100   Min.   :  1.00   Length:801        
 1st Qu.: 0.600   1st Qu.: 50.00   Class :character  
 Median : 1.000   Median : 65.00   Mode  :character  
 Mean   : 1.164   Mean   : 68.96                     
 3rd Qu.: 1.500   3rd Qu.: 80.00                     
 Max.   :14.500   Max.   :255.00                     
 NA's   :20                                          
     name           percentage_male  pokedex_number   sp_attack     
 Length:801         Min.   :  0.00   Min.   :  1    Min.   : 10.00  
 Class :character   1st Qu.: 50.00   1st Qu.:201    1st Qu.: 45.00  
 Mode  :character   Median : 50.00   Median :401    Median : 65.00  
                    Mean   : 55.16   Mean   :401    Mean   : 71.31  
                    3rd Qu.: 50.00   3rd Qu.:601    3rd Qu.: 91.00  
                    Max.   :100.00   Max.   :801    Max.   :194.00  
                    NA's   :98                                      
   sp_defense         speed           type1          
 Min.   : 20.00   Min.   :  5.00   Length:801        
 1st Qu.: 50.00   1st Qu.: 45.00   Class :character  
 Median : 66.00   Median : 65.00   Mode  :character  
 Mean   : 70.91   Mean   : 66.33                     
 3rd Qu.: 90.00   3rd Qu.: 85.00                     
 Max.   :230.00   Max.   :180.00                     
                                                     
    type2             weight_kg        generation    is_legendary    
 Length:801         Min.   :  0.10   Min.   :1.00   Min.   :0.00000  
 Class :character   1st Qu.:  9.00   1st Qu.:2.00   1st Qu.:0.00000  
 Mode  :character   Median : 27.30   Median :4.00   Median :0.00000  
                    Mean   : 61.38   Mean   :3.69   Mean   :0.08739  
                    3rd Qu.: 64.80   3rd Qu.:5.00   3rd Qu.:0.00000  
                    Max.   :999.90   Max.   :7.00   Max.   :1.00000  
                    NA's   :20

Виды покемонов имеют разные атрибуты:

  • Базовые соревновательные числовые атрибуты (Базовая статистика): атрибуты, влияющие на эффективность покемонов в бою. Они соответствуют функциям атака, защита, особая атака, особая защита, скорость. и очки здоровья (HP) в нашем наборе данных. Кроме того, base_total представляет собой сумму всех предыдущих столбцов и в целом указывает на силу покемонов.

  • Биологические числовые атрибуты (физические атрибуты):это вес, рост, скорость захвата (я рассматриваю это как биологическая особенность покемонов), процент мужского пола среди видов, рост опыта, base_happiness и базовые шаги по яйцу (количество шагов, которые дрессировщик нужно взять, чтобы яйцо вылупилось.)
  • Атрибуты типа: покемоны могут быть 18 различных типов — травяные, огненные, водяные, насекомые, обычные, ядовитые, электрические, земляные феи, боевые, психические, каменные, призрачные, ледяные, драконьи, темный, стальнойи летающий. Типы покемонов влияют на урон, который они получают от атак других покемонов. Например, огненные покемоны получают двойной урон от движений водного типа и только половину урона от движений травяного типа. Характеристики type1, type2 содержат типы, а характеристики против_* определяются как множитель урона, полученного покемоном против хода данного тип.
  • Номинальные атрибуты категории: например, их имя на любом языке и номер покедекса, их особые способности и их классификация как вид, который представляет собой описание реального эквивалента покемона (это не всегда имеет смысл, например, Horsea явно является морским коньком, но, согласно покедексу, это «дракон покемон»).

  • Поколение: категориальный порядковый атрибут, соответствующий поколению франшизы, в которой был представлен покемон.

Подготовка данных

Согласно сводке, в некоторых атрибутах отсутствуют данные. Есть много способов справиться с ними, когда больше нет доступных данных, которые в основном будут зависеть от типа переменной. Доступно много дополнительных данных для покемонов, и мы будем работать с ними.

Отсутствующие данные о росте и весе соответствуют покемонам, имеющим более одной формы (в зависимости от региона их обнаружения). Для этих случаев я заменил отсутствующие данные значениями, которые они предполагают для региона, из которого они родом (источник: Булбапедия). Кроме того, скорость захвата импортируется как символ, поэтому мы должны преобразовать его в числовое значение.

Warning message:
NAs introduced by coercion

NA вводится для учета Minior (номер 771), представляющего собой покемона-метеора, который имеет две формы с разными значениями коэффициента поимки: 30 и 255. Здесь я приму значение 30 для этого покемона, так как это не сильно повлияет на наши результаты. У нас также есть NA для атрибута percentage_male. Некоторые покемоны не являются ни мужчинами, ни женщинами (например, Магнемайт, покемон-магнит). Для всех этих случаев я приму нулевой процент самцов для вида.

Я добавлю дополнительную функцию, состоящую из эволюционного ранга покемонов. Он варьируется от 1 (первая форма дерева эволюции покемонов) до 3 (третий уровень). Кроме того, мы предполагаем, что легендарные покемоны занимают отдельный ранг.

Я также сохраню переменную с именами покемонов для дальнейшего использования.

Отображение с использованием конкурентных числовых атрибутов

Во-первых, я определю функцию для построения 2D-карты, которая будет использоваться для всех представлений, и функцию для получения легенды из графика, которая поможет нам получить единую легенду для сетки подграфиков.

Мы выберем несколько покемонов, которых мы рассмотрим более подробно в ходе нашего анализа:

Стартеры: (ранг 1) Бульбазавр, Чармандер, Сквиртл, (ранг 2) Ивизавр, Чармелеон, Вартортл, (ранг 3) Венусар, Чаризард, Бластойз;

Слабаки: Катерпи, Пиджи, Мэджикарп (все покемоны 1 ранга);

Сильные:Генгар (ранг 3), Дратини (ранг 1), Драгонэйр (ранг 2), Драгонайт (ранг 3), Мьюту (легендарный) и Мью (легендарный);

И Пикачу (ранг 2), потому что это Пикачу

Поскольку я буду использовать методы, основанные на расстояниях, я исключим все категориальные признаки. В качестве первого предположения мы можем предположить, что конкурентные числовые атрибуты являются основными характеристиками, относящимися к нашей проблеме.

Мы сравним семь различных вариантов уменьшения размерности, и это поможет нам оценить эффективность ранга покемонов для разделения нашего набора данных. Мы также оцениваем, как выбранные нами покемоны размещаются в созданных проекциях. Синтаксис большинства из них очень похож, с некоторыми отличиями, которые я буду выделять по всему коду.

В качестве первого подхода мы можем выбрать две из исходных функций для построения наших данных. Учитывая, что ранг представляет собой интересующую нас переменную, мы можем использовать случайный лес, чтобы выбрать две наиболее важные переменные для классификации ранга покемонов.

Особая атака и очки здоровья — две наиболее важные переменные для прогнозирования ранга покемонов. В качестве первого варианта мы сопоставим наш набор данных, используя только эти две переменные.

Мы видим переход от ранга 1 к легендарному, с очень смешанной областью в центре, содержащей все классификации рангов. Преимущество этого метода в том, что мы можем напрямую связать каждую ось нашей карты с особенностью наших данных. Недостатком, однако, является то, что наше представление отбрасывает много информации, которая может быть важна для классификации наших данных.

В R доступно множество методов уменьшения размерности, которые позволят нам сохранить больше информации. Я продолжу использовать шесть: PCA, LLE, Sammon Mapping, MDS, t-SNE и UMAP.

Анализ основных компонентов (АПК)

PCA является наиболее известным методом уменьшения размерности. Основной принцип, лежащий в основе этого, состоит в том, чтобы разложить матрицу, представляющую данные, на ее основные компоненты, каждый из которых сохраняет часть дисперсии исходных данных. Если вы не привыкли к концепции PCA, я бы порекомендовал эту замечательную статью Мэтта Бремса.

Локальное линейное встраивание (LLE)

Этот метод направлен на локальное сохранение расстояний между парами точек, для чего требуется несколько входных параметров:

  • внутреннее измерение m для визуализации, которое мы можем установить равным 2 для нашего сопоставления
  • количество соседей k, которое можно оптимизировать с помощью приведенной ниже функции calc_k:

Функция calc_k обеспечивает наилучшее значение k за счет минимизации показателя 1-ρ². Для наших данных оптимально полученное значение равно 20.

Отображение Саммона

Sammon Mapping — это метод уменьшения размерности, который работает путем минимизации функции, соответствующей разнице между расстояниями в исходных измерениях и в новых проецируемых измерениях. В качестве входных данных доступны несколько параметров, таких как начальная точка оптимизации, количество итераций и устойчивость к нагрузкам.

Неметрическое многомерное шкалирование (IsoMDS)

Функция isoMDS на R использует очень интересный подход для нелинейного многомерного отображения. На основе функции напряжений Крускала он пытается сохранить порядки расстояний между парами точек в новом представлении. Как и в случае с Sammon Mapping, вы можете включить параметры для настройки процесса оптимизации.

t-распределенное стохастическое встраивание соседей (t-SNE)

t-SNE работает путем моделирования расстояний между парами как нормализованного распределения вероятностей t-Стьюдента, так что более близкие точки имеют более высокие вероятности, а удаленные точки - более низкие. t-SNE имеет параметр недоумения, который соответствует ожидаемой плотности вокруг точек и, таким образом, связан с количеством ближайших соседей для каждой точки.

Отличное объяснение этого метода можно найти в этом видео на YouTube, а также в этом удивительном интерактивном сообщении Ваттенберга и др., 2016. Параметр Perplexity имеет первостепенное значение и должен быть оптимизирован в процессе. Перед принятием решения рекомендуется создавать визуализации с использованием нескольких значений этого атрибута. Здесь я представлю результаты для значения по умолчанию 30, но во время разработки я тестировал другие более низкие и более высокие значения.

Аппроксимация и проекция равномерного коллектора (UMAP)

В настоящее время UMAP, вероятно, является любимым методом уменьшения размерности среди специалистов по данным. Он показал себя как мощный инструмент для визуализации данных, как с точки зрения результатов, так и с точки зрения вычислительной эффективности. Подробное обсуждение метода UMAP и его отличий от t-SNE доступно в отличной статье Николая Осколкова: Как именно работает UMAP.

После сохранения всех выбранных представлений мы можем создать карты, используя функцию, которую мы определили ранее.

Теперь мы построим все результаты в одной сетке.

Все шесть методов уменьшения размерности генерировали визуализации, которые имеют смысл, когда мы рассматриваем ранг покемонов. На всех картах мы видим, что регионы последовательно прогрессируют от покемонов ранга 1 до легендарных. Покемоны, которые считаются «слабыми» или слишком распространенными, такие как Катерпи, Пиджи и Мэджикарп, всегда группируются вместе. Точно так же стартеры 3-го ранга и драконы (считающиеся сильными покемонами) относятся к аналогичному региону.

PCA, LLE, Sammon Mapping и isoMDS показали схожие результаты с некоторыми небольшими отличиями. Мы можем видеть Magikarp очень отделенным от кластера в Sammon Mapping. Любой, кто когда-либо играл в покемонов, наверняка согласится с тем, что Мэджикарп действительно является исключением с точки зрения боевых характеристик.

В данных нет явного кластера, но t-SNE и UMAP делят данные на то, что можно интерпретировать как область покемонов 1-го ранга и другую область эволюционировавших покемонов, с несколькими исключениями, относящимися к каждому кластеру. Для всех представлений окончательные формы стартовых покемонов едва ли отличаются от легендарных покемонов с точки зрения их боевых качеств.

Пикачу для каждой проекции ставится очень близко к слабакам, хотя это покемон 2-го ранга. Может Эшу просто повезло с ним :)

Картирование, включая биологические и конкурентные числовые атрибуты

Сначала мы изменим наш выбор функций.

После этого мы применяем все шаги для выполнения нашего анализа уменьшения размерности.

Случайный лес теперь показывает очень разные результаты по важности признаков. Когда мы включаем биологические атрибуты, три наиболее важные характеристики для классификации покемонов в соответствии с рангом являются биологическими: capture_rate, base_egg_steps и рост!

Построив данные по двум наиболее важным характеристикам (capture_rate x base_egg_steps), мы получим график, показанный на рисунке ниже.

Результаты довольно сгруппированы и их трудно анализировать. Повторно применяя методы уменьшения размерности, мы получаем следующие графики.

Опять же, покемоны разделяются по их рангу прогрессивным образом. Кажется, что теперь представления более целесообразно разделить между рангами 3 и 2. Ранг 1 снова очень четко разделен для большинства методов уменьшения размерности.

Для PCA, isoMDS и Sammon Mapping мы видим очень сгруппированный регион с переходом для покемонов с ранга 1 на ранг 3 и большой рассредоточенный регион, содержащий легендарных покемонов. Это также верно для метода LLE, но там покемоны с 1-го по 3-й ранг еще более сгруппированы, всего несколько точек вне кластера.

Для всех методов включения биологических числовых признаков было достаточно, чтобы легендарные покемоны стали очень хорошо разделены. В LLE, UMAP и t-SNE легендарные покемоны делятся на два кластера: один содержит сильных боевых покемонов, таких как Мьюту. Другой, меньший, легкий, обычно мифический покемон, такой как Мью. Деревья эволюции сгруппированы вместе, при этом стартеры 1 и 2 ранга сосредоточены в одном отдельном регионе.

Как для UMAP, так и для t-SNE стартеры ранга 1 и ранга 2 образуют два четко разделенных кластера. Стартовые формы ранга 3 ближе к их соответствующим рангам 1 и 2. В UMAP Dragonite ближе к Dragonair и Dratini, показывая, что метод смог сохранить эволюционные отношения этих покемонов в новом представлении. Это не так очевидно для t-SNE.

В конце концов, сопоставление подтверждает ранг, который мы определили как значимую меру для представления важных аспектов нашего набора данных о покемонах. О, и снова Пикачу находится там, совсем рядом с Мэджикарпом и Катерпи — бедняжка :(

Итак, какой метод уменьшения размерности следует использовать?

Это сложный вопрос. Если бы у ученого было достаточно времени, все эти методы плюс многие другие можно было бы применить. Однако это не так. В целом, UMAP и t-SNE показали наилучшие результаты для данных о покемонах, и поэтому они кажутся отличной отправной точкой для визуализации вашего набора данных.

Предложения приветствуются! Полный код этой статьи доступен на GitHub :)!