DecisionTreeRegressor
DecisionTreeRegressor — модель дерева решений для задач регрессии.
Принцип работы похож на DecisionTreeClassifier: модель строит дерево условий. Но классификатор предсказывает класс, а регрессор предсказывает числовое значение.
Идея дерева решений
Заголовок раздела «Идея дерева решений»Дерево решений задаёт последовательность проверок. На каждом шаге модель проверяет один признак: например, площадь квартиры или расстояние до метро.
Условия могут выглядеть так:
area <= 57.5metro_minutes <= 10rooms <= 2.5Если условие выполняется, мы переходим по одной ветке дерева, иначе по другой. Далее мы либо проверяем новое условие, либо доходим до листа дерева, в котором записан ответ. Этот ответ и есть числовой прогноз модели. Обычно это среднее значение целевой переменной среди обучающих примеров, которые попали в тот же конечный лист дерева.
Отличие от DecisionTreeClassifier
Заголовок раздела «Отличие от DecisionTreeClassifier»| Модель | Что предсказывает | Что хранится в листе |
|---|---|---|
DecisionTreeClassifier | класс | метка класса |
DecisionTreeRegressor | число | числовой прогноз |
Например, классификатор может ответить бульдог или спаниель, а регрессор может предсказать цену квартиры 14.7.
Когда использовать
Заголовок раздела «Когда использовать»DecisionTreeRegressor полезен, когда зависимость между признаками и ответом нелинейная, но хочется сохранить понятную модель.
Например, цена квартиры может зависеть от площади, числа комнат, этажа и расстояния до метро не по одной прямой формуле, а по набору условий.
Пример: цена квартиры
Заголовок раздела «Пример: цена квартиры»В примере модель предсказывает цену квартиры по нескольким числовым признакам из датасета MoscowHousing.
uses MLABC;
begin var df := Datasets.MoscowHousing.Data;
var features := [ 'rooms', 'area', 'kitchen_area', 'floor', 'floors_total', 'metro_minutes' ];
var X := df.ToMatrix(features); var y := df.ToVector('price');
var (Xtrain, Xtest, ytrain, ytest) := Validation.TrainTestSplit(X, y, testRatio := 0.2, seed := 42);
var model := new DecisionTreeRegressor( maxDepth := 4, minSamplesSplit := 10, minSamplesLeaf := 5, seed := 42 );
model.Fit(Xtrain, ytrain);
var pred := model.Predict(Xtest); Println('R2:', Metrics.R2(ytest, pred):0:3);end.Вывод и смысл результата
Заголовок раздела «Вывод и смысл результата»Вывод:
R2: 0.690R2 — безразмерная метрика качества регрессии. Она показывает, насколько хорошо модель объясняет разброс целевого значения.
R2 = 0.690 показывает, что даже дерево небольшой глубины нашло заметную часть зависимости в данных.
Это означает, что модель объясняет примерно 69% разброса цен на тестовой выборке. Значит, дерево явно нашло полезные зависимости: площадь, число комнат, этаж, расстояние до метро и другие признаки. Но примерно 31% вариативности остаётся необъяснённой выбранными признаками и самой простой структурой дерева.
Обучение и прогноз
Заголовок раздела «Обучение и прогноз»Сначала дерево обучается на обучающей выборке:
model.Fit(Xtrain, ytrain);В процессе обучения модель строит дерево, используя признаки Xtrain и известные ответы ytrain.
После обучения дерево можно применить к тестовой выборке:
var pred := model.Predict(Xtest);В переменной pred находятся прогнозы модели для всех объектов из Xtest.
Для одного объекта используется PredictOne:
var price := model.PredictOne(Vector([2.0, 45.0, 8.0, 5.0, 12.0, 10.0]));Здесь числа идут в том же порядке, что и признаки в массиве features: rooms, area, kitchen_area, floor, floors_total, metro_minutes.
Это означает, что мы предсказываем стоимость квартиры с двумя комнатами, с площадью 45 квадратных метров, площадью кухни 8 квадратных метров и т.д.
Как читать дерево
Заголовок раздела «Как читать дерево»Выведем дерево регрессии с помощью команды:
Println(model.Tree(features));Получим:
area ≤ 110.8?├── да: area ≤ 51.15?│ ├── да: area ≤ 40.23?│ │ ├── да: 11153677.42│ │ └── нет: 19990225.82│ └── нет: area ≤ 88.9?│ ├── да: 32870095.1│ └── нет: 47883661.03└── нет: area ≤ 166.4? ├── да: rooms ≤ 4.5? │ ├── да: 88784846.53 │ └── нет: 54035762.92 └── нет: floor ≤ 7.5? ├── да: 146355239.93 └── нет: 92208129.97Чтение начинается с корня дерева — с самого первого вопроса:
area ≤ 110.8?Если площадь квартиры меньше или равна 110.8, идём по ветке да. Если больше — по ветке нет.
Дальше дерево задаёт следующий вопрос. Например, для квартиры с площадью 45:
area ≤ 110.8? даarea ≤ 51.15? даarea ≤ 40.23? нетПосле этого мы попадаем в лист:
19990225.82Это и есть прогноз дерева: примерно 19.99 млн рублей.
Основные гиперпараметры
Заголовок раздела «Основные гиперпараметры»var model := new DecisionTreeRegressor( maxDepth := 4, minSamplesSplit := 2, minSamplesLeaf := 1, maxFeatures := -1, seed := 42);maxDepth — максимальная глубина дерева.
Если глубина слишком большая, дерево может переобучиться. Если слишком маленькая — модель может оказаться слишком простой.
minSamplesSplit — минимальное число объектов, при котором узел можно разделять.
minSamplesLeaf — минимальное число объектов в листе.
maxFeatures — сколько признаков рассматривать при разбиении.
seed — начальное значение генератора случайных чисел.
Для первых экспериментов обычно достаточно настроить maxDepth и minSamplesLeaf.
Преимущества
Заголовок раздела «Преимущества»- модель легко объяснить;
- не требует масштабирования признаков;
- умеет описывать нелинейные зависимости.
Ограничения
Заголовок раздела «Ограничения»- легко переобучается при большой глубине;
- прогноз получается кусочно-постоянным;
- одно дерево может быть нестабильным.
Практические советы
Заголовок раздела «Практические советы»- начинайте с небольшой глубины дерева;
- не делайте
minSamplesLeafслишком маленьким; - сравнивайте качество с
RandomForestRegressorиGradientBoostingRegressor.