warm_start у RandomForest: добавляем деревья, сохраняя старые
Лес из двадцати деревьев уже обучен. Хочется довести ансамбль до сорока, не строя первые двадцать заново. warm_start позволяет такой сценарий, но не означает, что старые деревья научатся на новой порции данных.
Наращивание ансамбля имеет конкретную форму
У RandomForest с warm_start=True повторный fit при увеличенном n_estimators сохраняет уже построенные деревья и добавляет новые. Старое дерево не перестраивает пороги и листья. Поэтому безопасный понятный сценарий — тот же обучающий набор и те же параметры деревьев, но большее число деревьев.
Если передать только новые данные, в ансамбле окажутся деревья, обученные на разных наборах. Это может быть отдельным сознательно выбранным методом, но не является обычным обновлением всего леса. Если нужно переучить каждый компонент на обновлённом снимке, создайте новый лес и выполните полный fit.
Убедиться, что старые объекты сохранились
Пример сохраняет ссылки на первые четыре дерева и их пороги. После увеличения n_estimators до семи первые деревья остаются теми же объектами, а всего их становится семь. Проверка показывает механизм напрямую; по одному предсказанному классу такое различие увидеть трудно.
Перед новым fit меняем только n_estimators. Произвольное изменение max_depth или другого параметра не преобразует уже построенные деревья в новые. Для независимой конфигурации используйте новый estimator.
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
X, y = load_iris(return_X_y=True)
forest = RandomForestClassifier(n_estimators=4, max_depth=3,
warm_start=True, random_state=9,
n_jobs=1).fit(X, y)
old_trees = list(forest.estimators_)
old_thresholds = [tree.tree_.threshold.tolist() for tree in old_trees]
forest.set_params(n_estimators=7)
forest.fit(X, y)
assert len(forest.estimators_) == 7
assert all(forest.estimators_[i] is old for i, old in enumerate(old_trees))
assert [tree.tree_.threshold.tolist() for tree in old_trees] == old_thresholds
assert len(forest.predict(X[:3])) == 3
print("retained:", len(old_trees), "total:", len(forest.estimators_))Как сохранить понятный эксперимент
Запишите исходное число деревьев, итоговое число и идентификатор обучающего снимка. Если увеличение ансамбля выполняется частями после перезапуска процесса, сохраняйте промежуточный estimator целиком. Не восстанавливайте его только по параметрам: конструктор с warm_start=True ещё не содержит ни одного старого дерева.
Уменьшить n_estimators ниже числа сохранённых деревьев таким способом нельзя. Если хотите исследовать несколько независимых размеров ансамбля, заранее решите, сравниваете ли вы вложенные наборы деревьев или отдельные обучения. Тогда порядок запусков не станет скрытым параметром результата.
Закрепить базовую операцию
Открытый урок показывает, где настройки estimator превращаются в обученное состояние после fit. Повторите базовый цикл, затем проверьте сохранность деревьев в примере статьи. Откройте урок «Первый fit и predict на своих данных». Затем вернитесь к сценарию статьи и проверьте его на своём небольшом наборе. Посмотрите программу курса первой ML-модели, чтобы пройти путь от обучения к использованию результата.
Продолжить на практике
- Машинное обучение с нуля на Python: первая модель ↗
Бесплатный курс машинного обучения на Python: обучите первую модель в scikit-learn, проверьте её качество и решите 106 задач в браузере.
