Модели случайных лесов очень надежны и будут работать с большинством наборов данных. Этот пост помогает интерпретировать его вывод, что поможет нам улучшить производительность модели.

Прежде чем вдаваться в подробности, если вам интересно, вы можете ознакомиться с постом, который я написал, объясняя работу случайных лесов здесь. Для целей этого поста я буду использовать набор данных Синяя книга для бульдозера. Цель здесь состоит в том, чтобы предсказать цену продажи конкретной единицы тяжелой техники на аукционе на основе ее использования, типа оборудования и конфигурации.

Важность функции

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

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

Ниже приведен график важности признаков (только 15 лучших), полученный из случайного леса в наборе данных Синяя книга для бульдозеров. Теперь, используя эту важность функции, мы можем попытаться удалить некоторые функции, которые никак не помогали модели делать прогнозы, и сосредоточиться на важных функциях и попытаться обогатить их. Как мы видим, год изготовления является наиболее важной характеристикой, и это имеет смысл, поскольку самые последние модели будут стоить дороже, поскольку они новые.

Удаление избыточных функций с помощью Дендрограммы

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

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

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

Горизонтальная ось дендрограммы представляет собой расстояние или несходство между признаками. Вертикальная ось представляет функции. Горизонтальное положение разделения, показанное короткой вертикальной чертой, дает расстояние (несходство) между двумя функциями. Дендрограмма интуитивно понятна. На графике выше мы можем сказать, что SaleYear и SaleElapsed похожи. Аналогично, Grouser_Tracks, Hydraulics_Flow и Coupler_System кажутся похожими, равно как и fiBaseModel и fiModelDesc.

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

Интерпретатор дерева

Представьте ситуацию, когда мы использовали случайный лес для построения модели оценки цены продукта. Учитывая продукт, наша модель оценивает некоторую цену, но затем, если кто-то спросит, почему модель дала эту цену, то есть, насколько каждая функция повлияла на результат? Неплохо ли иметь под рукой инструмент в таких ситуациях? Вот тут и приходит на помощь Tree Interpreter. Это позволяет нам узнать, насколько каждая функция повлияла на прогнозируемое значение.

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

Предположим, мы используем только две функции ProductSize и fitBaseModel для прогнозирования значения. Если продукт имеет значения этих характеристик как 1,0 и 32,0, мы бы предсказали его значение как 54016,27 (можно получить, следуя пути дерева на рисунке выше). Теперь давайте попробуем выяснить, как значения характеристик повлияли на окончательную цену. Среднее значение цены во всем наборе данных составляет 31132,56 (среднее значение корневого узла).

  • Поскольку ProductSize меньше 1,5, значение уменьшилось до 23865,101 с 31132,56.
  • Но поскольку fiBaseModel этого больше 30,5, его значение увеличилось с 23865,101 до 54016,277.

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

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

[('ProductSize', 'Mini', -10711.476138131464),
 ('fiProductClassDesc',
  'Hydraulic Excavator, Track - 3.0 to 4.0 Metric Tons',
  -2649.14348062972),
 ('saleElapsed', 1284595200, -1683.9341310699049),
 ('Enclosure', 'EROPS', -1377.9297130991024),
 ('saleYear', 2010, -1023.9973954073218),
 ('fiModelDescriptor', nan, -893.4251635183798),
 ('SalesID', 4364751, -841.8769367770632),
 ('fiBaseModel', 'KX121', -824.3615641477994),
 ('fiModelDesc', 'KX1212', -451.67046975023675),
 ('saleDayofyear', 259, -396.7574060509695),
 ('fiSecondaryDesc', nan, -382.5772399901316),
 ('Tire_Size', nan, -347.40121901413283),
 ('MachineID', 2300944, -344.1756379740019),
 ('Blade_Type', nan, -211.418896998982),
 ('saleWeek', 37, -37.30072767993065),
 ('saleDay', 16, -34.155274963846026),
 ('Ripper', nan, -25.3176179137301),
 ('Blade_Extension', nan, 0.0),
 ('Hydraulics_Flow', nan, 0.0),
 ('Blade_Width', nan, 0.0),
 ('Hydraulics', 'Standard', 51.52887544603082),
 ('state', 'Ohio', 94.42013245805178),
 ('Grouser_Tracks', nan, 127.84089954337814),
 ('Coupler_System', nan, 228.59995699361053),
 ('fiModelSeries', '2', 248.62146227924796),
 ('ModelID', 665, 1829.0961287686841),
 ('YearMade', 1999, 2014.078071794381)]

Таким образом, используя Tree Interpreter, мы можем сказать, как модель делает прогноз на уровне одной отдельной строки. Многие люди говорят, что случайный лес — это модель черного ящика, но, как мы видели, с помощью правильных методов мы можем интерпретировать его выходные данные. Это все для этого. Если вам нужна дополнительная информация, см. ссылки, приведенные ниже. Спасибо за чтение!!!.

Весь код, использованный в этом посте, можно найти здесь.

Дальнейшее чтение

  1. https://medium.com/@srnghn/the-mathematics-of-decision-trees-random-forest-and-feature-importance-in-scikit-learn-and-spark-f2861df67e3
  2. http://docs.h2o.ai/h2o/latest-stable/h2o-docs/variable-importance.html
  3. https://github.com/andosa/treeinterpreter