Содержание курса 17 / 27

17 / 27 · Деревья и ансамбли

Бэггинг и случайный лес

Усреднение многих деревьев, выращенных на бутстрэп-выборках: почему смещение остаётся, а разброс падает, дисперсия среднего коррелированных моделей, выведенная по закону полной дисперсии, случайный лес и случайные подмножества признаков, ошибка out-of-bag и 63.2% точек в каждой бутстрэп-выборке, важность по неоднородности и перестановочная важность и их ловушки, а также экстремально рандомизированные деревья.

На этой странице 12

Заметка о смещении и разбросе нашла слабое место глубокого дерева: его смещение мало, а разброс велик: порядка шума, когда обучающие точки расположены плотно, и во много раз больше, когда редко. Она же нашла и принципиальное лекарство. Среднее моделей, обученных одной и той же процедурой, имеет то же математическое ожидание, что и каждая из них, поэтому сохраняет малое смещение, а его разброс может быть гораздо меньше. Трудность практическая: усреднение по независимым обучающим выборкам требует многих обучающих выборок, а у нас одна. В этой заметке бутстрэп изготавливает обучающие выборки из той, что у нас есть (бэггинг, bagging), выводится, какую часть дисперсии сохраняет среднее, когда его члены коррелированы, и показывается, как случайный лес (random forest) снижает эту корреляцию.

Обозначения. DD — обучающая выборка из nn точек. T(x;Θ)T(x; \Theta) — дерево, выращенное на DD со случайностью Θ\Theta: бутстрэп-выборкой и, для леса, признаками, выбранными в каждом разбиении. Деревья ансамбля используют независимые при данном DD реализации Θ1,…,ΘB\Theta_1, \dots, \Theta_B, и ансамбль предсказывает f^B(x)=1B∑b=1BT(x;Θb)\hat f_B(x) = \frac1B \sum_{b=1}^B T(x; \Theta_b) в регрессии или усредняет вероятности классов, выданные деревьями, в классификации. В фиксированной точке xx τ2(x)\tau^2(x) — дисперсия предсказания одного дерева (не σ2\sigma^2 — это дисперсия шума в заметке о смещении и разбросе), а ρ(x)\rho(x) — корреляция предсказаний двух деревьев, обе по случайности DD и Θ\Theta.

Бутстрэп-агрегирование#

Бэггинг (bootstrap aggregation, Breiman, 1996):

  1. Сгенерировать BB бутстрэп-выборок: nn точек из DD с возвращением, BB раз.
  2. Вырастить на каждой дерево, обычно до полной глубины, без обрезки.
  3. Усреднить предсказания: среднее в регрессии, среднее вероятностей классов (или голосование большинством) в классификации.

Бутстрэп-выборка заменяет свежую обучающую выборку из того же распределения, поэтому предсказатель с бэггингом приближает среднюю модель ED[f^D(x)]E_D[\hat f_D(x)] из предыдущей заметки, используя повторные выборки вместо новых данных. Поскольку деревья одинаково распределены, математическое ожидание их среднего равно математическому ожиданию одного бутстрэп-дерева: бэггинг не меняет смещения, если не считать небольшого роста из-за того, что каждое дерево видит только около 63% различных точек (Hastie, Tibshirani and Friedman, 2009, разделы 15.2 и 15.4.2). Весь выигрыш — в разбросе, поэтому бэггинг помогает именно неустойчивым (unstable) методам, чей результат сильно меняется при небольших изменениях данных: деревьям, отбору подмножества признаков, нейросетям. Для устойчивых методов, таких как ближайшие соседи, выигрыш мал, а иногда бэггинг слегка вредит (Breiman, 1996, раздел 1). Для метода наименьших квадратов или выборочного среднего он почти ничего не меняет: среднее бутстрэп-средних — это выборочное среднее.

Какую часть дисперсии сохраняет среднее?#

Если бы BB деревьев были независимы, дисперсия их среднего была бы равна τ2/B\tau^2 / B. Но они зависимы: все выращены по одной и той же DD. При попарной корреляции ρ\rho дисперсия среднего равна

Var⁡(f^B(x))=ρτ2+1−ρB τ2.\operatorname{Var}\big(\hat f_B(x)\big) = \rho \tau^2 + \frac{1 - \rho}{B}\, \tau^2 .

Прямой вывод суммирует BB дисперсий и B(B−1)B(B-1) ковариаций ρτ2\rho\tau^2, как в заметке о совместных распределениях. Для деревьев второй вывод говорит больше: он показывает, откуда берётся корреляция. Возьмём условие по обучающей выборке и применим закон полной дисперсии:

Var⁡(f^B(x))=Var⁡D(E[f^B(x)∣D])+ED[Var⁡(f^B(x)∣D)].\operatorname{Var}\big(\hat f_B(x)\big) = \operatorname{Var}_D\Big(E\big[\hat f_B(x) \mid D\big]\Big) + E_D\Big[\operatorname{Var}\big(\hat f_B(x) \mid D\big)\Big] .

При данном DD деревья — независимые реализации Θ\Theta, поэтому E[f^B(x)∣D]=E[T(x;Θ)∣D]E[\hat f_B(x) \mid D] = E[T(x; \Theta) \mid D] и Var⁡(f^B(x)∣D)=Var⁡(T(x;Θ)∣D)/B\operatorname{Var}(\hat f_B(x) \mid D) = \operatorname{Var}(T(x; \Theta) \mid D) / B. Тот же закон для одного дерева раскладывает его дисперсию на те же две части:

τ2=Var⁡D(E[T∣D])⏟от обучающей выборки+ED[Var⁡(T∣D)]⏟от повторной выборки.\tau^2 = \underbrace{\operatorname{Var}_D\big(E[T \mid D]\big)}_{\text{от обучающей выборки}} + \underbrace{E_D\big[\operatorname{Var}(T \mid D)\big]}_{\text{от повторной выборки}} .

В ковариации двух деревьев нет части от повторной выборки, потому что при данном DD они независимы: Cov⁡(T1,T2)=ED[Cov⁡(T1,T2∣D)]+Cov⁡D(E[T1∣D],E[T2∣D])=0+Var⁡D(E[T∣D])\operatorname{Cov}(T_1, T_2) = E_D[\operatorname{Cov}(T_1, T_2 \mid D)] + \operatorname{Cov}_D(E[T_1 \mid D], E[T_2 \mid D]) = 0 + \operatorname{Var}_D(E[T \mid D]). Значит, ρτ2=Var⁡D(E[T∣D])\rho\tau^2 = \operatorname{Var}_D(E[T \mid D]) — часть дисперсии дерева, которая идёт от обучающей выборки, (1−ρ)τ2(1 - \rho)\tau^2 — часть, которая идёт от повторной выборки (resampling), а подстановка обеих частей даёт формулу (Hastie, Tibshirani and Friedman, 2009, раздел 15.4.1, формулы 15.5 и 15.9).

Разобранный пример с игрушечными числами: при τ2=1\tau^2 = 1 и ρ=0.3\rho = 0.3 у одного дерева дисперсия 11, у десяти деревьев 0.3+0.07=0.370.3 + 0.07 = 0.37, у ста деревьев 0.3070.307; нижняя граница равна 0.30.3. После нескольких десятков деревьев новые деревья почти ничего не дают, и помочь может только меньшее ρ\rho.

Случайный лес: декорреляция деревьев#

Деревья в бэггинге похожи, потому что выращиваются жадно по похожим выборкам: если один признак сильно предсказывает целевую переменную, почти каждое бутстрэп-дерево разбивает по нему корень, и у деревьев общая верхняя структура. Случайный лес (Breiman, 2001) меняет одну строку алгоритма выращивания дерева: в каждом разбиении случайно выбрать mm из dd признаков и искать лучшее разбиение только среди этих mm. Разные деревья и разные узлы одного дерева вынуждены использовать разные признаки, поэтому деревья меньше коррелированы. Отдельные деревья становятся хуже — с бо́льшим смещением и бо́льшей дисперсией, — так что mm обменивает ρ\rho на τ2\tau^2 и смещение. Рекомендуемые значения по умолчанию — m=⌊d⌋m = \lfloor \sqrt d \rfloor с листьями размера 1 для классификации и m=⌊d/3⌋m = \lfloor d/3 \rfloor с листьями размера 5 для регрессии, но mm — настраиваемый параметр (Hastie, Tibshirani and Friedman, 2009, раздел 15.3). Бэггинг — частный случай m=dm = d. Значения по умолчанию в библиотеках другие: RandomForestClassifier из scikit-learn выбирает d\sqrt d признаков, а RandomForestRegressor — все dd, так что его регрессионный лес по умолчанию — это бэггинг.

На функции Фридмана в 10 измерениях (постановка из предыдущей заметки) оценка двух частей дисперсии по 40 обучающим выборкам с 25 деревьями на каждой даёт для одного дерева:

τ2\tau^2ρ\rhoнижняя граница ρτ2\rho\tau^2смещение²дисперсия при B=25B = 25
бэггинг, m=10m = 1011.110.1051.173.831.57
лес, m=3m = 315.520.0430.665.261.25

Деревья леса по отдельности хуже (τ2\tau^2 растёт с 11.111.1 до 15.515.5), но их корреляция падает с 0.1050.105 до 0.0430.043, и нижняя граница дисперсии ансамбля падает с 1.171.17 до 0.660.66. Здесь половина признаков не влияет на целевую переменную, ограниченный поиск часто пропускает влияющие, и большее смещение съедает выигрыш: при неограниченном числе деревьев ожидаемая ошибка бэггинга на тесте около 1+3.83+1.17=6.01 + 3.83 + 1.17 = 6.0, а леса — около 1+5.26+0.66=6.91 + 5.26 + 0.66 = 6.9. Когда сигнал распределён по многим признакам, обмен идёт в другую сторону:

Рисунок

Ошибка ансамбля и число деревьев

Кривые ошибки бэггинга и лесаОбе кривые быстро падают и выходят на полку; кривая леса начинается выше, но заканчивается ниже; пунктир out-of-bag идёт рядом с кривой леса.0.10.20.30.4150100150число деревьев Bдоля ошибокбэггинг (30 признаков): 17.9%лес (5 признаков): 14.9%лес, out-of-bag: 15.7%Кривые ошибки бэггинга и лесаОбе кривые быстро падают и выходят на полку; кривая леса начинается выше, но заканчивается ниже; пунктир out-of-bag идёт рядом с кривой леса.0.10.20.30.4150100150число деревьев Bдоля ошибокбэггинг (30 признаков): 17.9%лес (5 признаков): 14.9%лес, out-of-bag: 15.7%
Два гауссовских класса в 30 измерениях, 300 обучающих точек, ошибка на 2000 новых точках. Одно дерево ошибается в 32% (бэггинг) и 39.5% (лес) случаев: дерево леса хуже, потому что в каждом узле видит только 5 случайных признаков из 30. Но деревья леса меньше коррелированы, и их среднее уходит ниже: после 150 деревьев 17.9% у бэггинга и 14.9% у леса. Обе кривые выходят на полку, а не растут: добавление деревьев не переобучает. Ошибка out-of-bag (пунктир), посчитанная по одной обучающей выборке, — 15.7%.

Каждый из 30 признаков несёт немного информации, как пиксели изображения. Одно дерево леса, ограниченное 5 признаками на разбиение, заметно хуже одного дерева бэггинга, но деревья леса декоррелируются, и лес заканчивает ниже. Обе кривые выходят на полку. Добавление деревьев не переобучает ансамбль так, как это делает лишняя глубина: f^B\hat f_B с ростом BB сходится к своему пределу E[T∣D]E[T \mid D] (Breiman, 2001, теорема 1.2 и раздел 11), и новые деревья лишь убирают случайные колебания вокруг этого предела. Для квадратичной ошибки ошибка на тесте, усреднённая по случайности деревьев, убывает с ростом BB, как показывает формула для разброса выше; кривая одного конкретного леса всё же может колебаться или ненадолго немного расти, а доля ошибок голосования большинством не обязана падать при каждом BB. Сам этот предел всё же может переобучиться, поэтому иногда настраивают и глубину или размер листа (Hastie, Tibshirani and Friedman, 2009, раздел 15.3.4).

У леса есть второе прочтение. В регрессии дерево предсказывает в xx среднее значение целевой переменной обучающих точек из листа, в который попала xx, поэтому лес предсказывает взвешенное среднее ∑iwi(x) yi\sum_i w_i(x) \, y_i, где wi(x)w_i(x) — среднее по деревьям величины [xi в одном листе с x ]/(размер листа)[x_i \text{ в одном листе с } x\text{ }] / (\text{размер листа}). Это правило ближайших соседей, окрестности которого выучены по целевой переменной: точки близки, если часто попадают в один лист, а признаки, которые не важны, не учитываются в расстоянии (Hastie, Tibshirani and Friedman, 2009, раздел 15.4.3).

Ошибка out-of-bag#

Бутстрэп-выборка пропускает некоторые точки. Данная точка не выбирается за одно извлечение с вероятностью 1−1/n1 - 1/n, а ни за одно из nn извлечений — с вероятностью

(1−1n)n⟶e−1≈0.368,\Big(1 - \frac1n\Big)^n \longrightarrow e^{-1} \approx 0.368 ,

поэтому каждая бутстрэп-выборка содержит в среднем долю 1−(1−1/n)n1 - (1 - 1/n)^n различных обучающих точек: 0.6510.651 при n=10n = 10, 0.6340.634 при n=100n = 100, 0.6320.632 в пределе. Моделирование при n=100n = 100 даёт 0.6340.634. Тот же расчёт объясняет, почему бутстрэп не работает для максимума, в курсе теории вероятностей.

Итак, каждая точка не попадает примерно в 36.8% деревьев, и эти деревья честно её проверяют. Предсказание out-of-bag (OOB) для xix_i усредняет только те деревья, в бутстрэп-выборку которых не вошла ii, а ошибка OOB — ошибка этих предсказаний по обучающей выборке (Breiman, 2001, раздел 3.1). Она оценивает ошибку на тесте без отложенной выборки и почти бесплатно, во многом как кросс-валидация (Hastie, Tibshirani and Friedman, 2009, раздел 15.3.1). При малом числе деревьев она немного пессимистична, потому что каждое OOB-предсказание усредняет лишь около B/eB/e из них. На рисунке ошибка OOB леса после 150 деревьев равна 15.7%15.7\% против ошибки на тесте 14.9%14.9\%; на данных о раке груди лес из 300 деревьев имеет долю правильных ответов (accuracy) OOB 0.9670.967 и на тесте 0.9530.953. В отличие от одного разбиения на обучение и валидацию, ничего не откладывалось: каждая точка использовалась и для обучения, и для оценки качества. Ошибка OOB честна только для самого леса. Выбор mm, размера листа или признаков сравнением ошибок OOB повторно использует те же точки для выбора, поэтому ошибка OOB выбранной настройки оптимистична, а шаг перед лесом, который использовал целевые значения всех точек, например отбор признаков по их корреляции с yy, уже видел метку каждой точки. Когда результаты OOB определяют такие решения, оставьте независимую тестовую выборку для итоговой оценки.

Важность признаков и её ловушки#

Лес нельзя прочитать так, как одно дерево, но он может ранжировать признаки. Распространены две меры.

  • Важность по неоднородности (impurity importance, mean decrease in impurity, MDI): сложить приросты всех разбиений по признаку jj во всех деревьях, взвешенные числом точек, которые видят эти разбиения, и нормировать (Hastie, Tibshirani and Friedman, 2009, раздел 15.3.2). Она бесплатна, поскольку приросты вычисляются во время обучения.
  • Перестановочная важность (permutation importance): перемешать значения признака jj в отложенных или OOB-данных, что разрывает его связь с целевой переменной и сохраняет его распределение, и измерить, насколько растёт ошибка (Breiman, 2001, раздел 10). Она работает для любой модели.

У обеих есть ловушки.

  • Важность по неоднородности вычисляется на обучающих данных и благоволит признакам с большим числом различных значений. Полностью выращенные деревья разбивают по всему, что снижает неоднородность на обучении, включая шум, а у непрерывного признака гораздо больше порогов для подгонки под шум, чем у бинарного (Strobl et al., 2007). В моделировании, где метка зависит только от x1x_1, чисто шумовой бинарный признак x2x_2 и чисто шумовой непрерывный признак x3x_3 получают важности по неоднородности 0.0080.008 и 0.3310.331 (против 0.6610.661 у x1x_1): лес приписывает непрерывному шуму треть важности. Перестановочная важность на отложенных данных даёт 0.2270.227 для x1x_1 и −0.016-0.016 и −0.008-0.008 для двух шумовых признаков — с точностью до шума правильный ноль.
  • Коррелированные признаки искажают ранжирование. Если добавить к данным о раке груди точную копию самого важного признака (worst perimeter, важность по неоднородности 0.1340.134), близнецы получат 0.1080.108 и 0.1240.124, вместе 0.2320.232: пара учтена с избытком, и копия теперь на первом месте. Когда в каждом разбиении выбирается mm признаков, две копии делают одну и ту же информацию доступной в большем числе разбиений, и пара забирает важность у остальных признаков. Когда каждое разбиение видит все признаки, как в бэггинге, близнецы лишь делят её: 0.2120.212 и 0.2040.204 против 0.4150.415 у одного признака. В обоих случаях оценки коррелированных признаков, прочитанные по одной, не говорят, насколько важна группа.
  • Перестановка признака, коррелированного с другими, создаёт невозможные входы, например большой радиус при малом периметре, и измеряет поведение модели там, где данных нет; такие перестановочные важности могут сильно завышать коррелированные признаки (Hooker, Mentch and Zhou, 2021).
  • Важность — не причинность. Обе меры описывают, что использует обученная модель, а не что произошло бы, если бы признак изменился.

Экстремально рандомизированные деревья#

Случайный лес рандомизирует признаки; экстремально рандомизированные деревья (extremely randomized trees, extra trees; Geurts, Ernst and Wehenkel, 2006) рандомизируют ещё и пороги. В каждом узле они выбирают KK признаков, для каждого выбирают одну точку разреза равномерно между его минимумом и максимумом в узле и оставляют лучшее из этих KK случайных разбиений. Каждое дерево выращивается на всей обучающей выборке, а не на бутстрэп-выборке, чтобы смещение оставалось малым, а разнообразие обеспечивают случайные точки разреза. Такие деревья дешевле выращивать, поскольку нет ни сортировки, ни перебора порогов, и они сильнее декоррелированы. На разбиении данных о раке груди 300 экстремально рандомизированных деревьев достигают доли правильных ответов на тесте 0.9420.942 против 0.9530.953 у леса: часто похоже, иногда лучше — в зависимости от данных.

Что изменилось#

Одно глубокое деревоБэггингСлучайный лес
Обучающие данные деревавсебутстрэп-выборкабутстрэп-выборка
Признаки в разбиениивсе ddвсе ddслучайные mm
Смещениемалое≈ как у одного дереванесколько выше
Дисперсияτ2\tau^2ρτ2+(1−ρ)τ2/B\rho\tau^2 + (1 - \rho)\tau^2/Bта же формула, меньшее ρ\rho
Валидацияотложенные данныеout-of-bagout-of-bag
Интерпретируемостьчитаемоеважностиважности

Ограничения#

  • Смещение остаётся. Усреднение не может исправить систематическую ошибку, общую для всех деревьев. Лес из пней имеет смещение одного случайного пня в среднем; это среднее может быть аддитивной функцией признаков, но взаимодействий в нём нет.
  • Нижняя граница остаётся. Коррелированные деревья оставляют ρτ2\rho\tau^2, сколько бы их ни усреднять; mm снижает ρ\rho ценой худших деревьев.
  • Размер и скорость. Сотни глубоких деревьев занимают память и время предсказания, и модель нельзя прочитать.
  • Нет экстраполяции. Лес усредняет средние по листьям, поэтому его предсказания остаются в диапазоне значений целевой переменной на обучении.
  • Важности вводят в заблуждение при шумовых признаках с большим числом значений, коррелированных признаках и причинных вопросах.

Что нужно запомнить#

  • Бэггинг выращивает деревья на бутстрэп-выборках и усредняет их; он сохраняет смещение и снижает разброс, поэтому помогает неустойчивым методам с малым смещением.
  • Var⁡(f^B)=ρτ2+(1−ρ)τ2/B\operatorname{Var}(\hat f_B) = \rho\tau^2 + (1 - \rho)\tau^2/B; по закону полной дисперсии ρτ2=Var⁡DE[T∣D]\rho\tau^2 = \operatorname{Var}_D E[T \mid D] — часть дисперсии, вызванная обучающей выборкой, которую усреднение убрать не может.
  • Случайный лес выбирает mm признаков на разбиение (рекомендуется d\sqrt d для классификации и d/3d/3 для регрессии; регрессор scikit-learn по умолчанию берёт все dd), чтобы снизить ρ\rho; деревья хуже, среднее лучше, когда сигнал распределён по многим признакам.
  • Больше деревьев не ведёт к переобучению: лес сходится к предельному лесу, и ошибка выходит на полку у нижней границы, с небольшими колебаниями по пути.
  • Каждая бутстрэп-выборка содержит долю 1−(1−1/n)n→1−1/e≈0.6321 - (1 - 1/n)^n \to 1 - 1/e \approx 0.632 точек; предсказания out-of-bag используют остальные 36.8% и бесплатно оценивают ошибку на тесте.
  • Важность по неоднородности благоволит признакам с большим числом значений и шумовым признакам; перестановочная важность на отложенных данных надёжнее, но вводит в заблуждение при коррелированных признаках.

Код#

Доля точек в бутстрэп-выборке, формула дисперсии, ρ\rho и τ2\tau^2 деревьев бэггинга и леса моделированием, доля правильных ответов out-of-bag, экстремально рандомизированные деревья и ловушки важности:

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier, ExtraTreesClassifier
from sklearn.inspection import permutation_importance
from sklearn.model_selection import train_test_split

rng = np.random.default_rng(0)

# доля обучающих точек в одной бутстрэп-выборке: 1 - (1 - 1/n)^n, и моделирование при n = 100
print([round(1 - (1 - 1 / n) ** n, 3) for n in (10, 100, 1000)], round(1 - np.exp(-1), 3))   # [0.651, 0.634, 0.632] 0.632
print(round(float(np.mean([len(np.unique(rng.integers(0, 100, 100))) / 100 for _ in range(20_000)])), 3))   # 0.634

# дисперсия среднего B моделей с дисперсией 1 и попарной корреляцией 0.3
print([round(0.3 + 0.7 / B, 3) for B in (1, 10, 100)])          # [1.0, 0.37, 0.307]

# tau^2 и rho отдельных деревьев на функции Фридмана, по 40 обучающим выборкам с 25 деревьями на каждой
f = lambda X: 10 * np.sin(np.pi * X[:, 0] * X[:, 1]) + 20 * (X[:, 2] - 0.5) ** 2 + 10 * X[:, 3] + 5 * X[:, 4]
Xtest = rng.random((300, 10))
for name, m in (('bagging', 1.0), ('forest', 1 / 3)):
    P = []
    for r in range(40):
        X = rng.random((200, 10)); y = f(X) + rng.normal(size=200)
        P.append([t.predict(Xtest) for t in RandomForestRegressor(25, max_features=m, random_state=r).fit(X, y).estimators_])
    P = np.array(P)                                            # обучающие выборки x деревья x тестовые точки
    within = P.var(1, ddof=1).mean()                           # E_D Var(T | D) = (1 - rho) tau^2
    between = P.mean(1).var(0, ddof=1).mean() - within / 25    # Var_D E(T | D) = rho tau^2
    bias2 = ((P.mean((0, 1)) - f(Xtest)) ** 2).mean()
    print(name, round(between + within, 2), round(between / (between + within), 3), round(bias2, 2), round(between + within / 25, 2), round(between, 2))
# bagging 11.11 0.105 3.83 1.57 1.17 | forest 15.52 0.043 5.26 1.25 0.66   (tau^2, rho, смещение^2, дисперсия при B = 25, нижняя граница)

# доля правильных ответов out-of-bag против тестовой выборки; экстремально рандомизированные деревья для сравнения
X, y = load_breast_cancer(return_X_y=True)
names = load_breast_cancer().feature_names
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)
rf = RandomForestClassifier(300, oob_score=True, random_state=0).fit(Xtr, ytr)
et = ExtraTreesClassifier(300, random_state=0).fit(Xtr, ytr)
print(round(rf.oob_score_, 3), round(rf.score(Xte, yte), 3), round(et.score(Xte, yte), 3))   # 0.967 0.953 0.942

# точная копия самого важного признака: при m признаках на разбиение близнецы вместе получают больше, чем исходный признак
top = int(np.argmax(rf.feature_importances_))
rf2 = RandomForestClassifier(300, random_state=0).fit(np.column_stack([Xtr, Xtr[:, top]]), ytr)
print(names[top], round(rf.feature_importances_[top], 3), round(rf2.feature_importances_[top], 3), round(rf2.feature_importances_[-1], 3))
# worst perimeter 0.134 0.108 0.124
# если каждое разбиение видит все признаки (бэггинг), близнецы, наоборот, делят важность исходного признака
bag = RandomForestClassifier(300, max_features=None, random_state=0).fit(Xtr, ytr)
bag2 = RandomForestClassifier(300, max_features=None, random_state=0).fit(np.column_stack([Xtr, Xtr[:, top]]), ytr)
print(round(bag.feature_importances_[top], 3), round(bag2.feature_importances_[top], 3), round(bag2.feature_importances_[-1], 3))   # 0.415 0.212 0.204

# важность по неоднородности против перестановочной: метка зависит только от x1; x2 — бинарный шум, x3 — непрерывный шум
Z = rng.random((1000, 3)); Z[:, 1] = Z[:, 1] < 0.5
yz = (Z[:, 0] + 0.3 * rng.normal(size=1000) > 0.5).astype(int)
rf3 = RandomForestClassifier(300, random_state=0).fit(Z[:500], yz[:500])
perm = permutation_importance(rf3, Z[500:], yz[500:], n_repeats=10, random_state=0).importances_mean
print(rf3.feature_importances_.round(3), perm.round(3))       # [0.661 0.008 0.331] [ 0.227 -0.016 -0.008]

Дальше#

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

Литература#