Перейти к содержимому

UsedCarsPrice

UsedCarsPrice — встроенный датасет с данными о подержанных автомобилях.

Он подходит для задач табличной регрессии: по характеристикам автомобиля нужно предсказать его цену.

Файл данных:

used_cars_price.csv

В программе датасет доступен так:

var ds := Datasets.UsedCarsPrice;
var df := ds.Data;

Целевая переменная — price_k_rub, цена автомобиля в тысячах рублей.

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

Цена автомобиля зависит сразу от нескольких факторов: года выпуска, пробега, модели, типа топлива, коробки передач, объёма двигателя и других признаков.

В датасете есть числовые и категориальные признаки.

Например, в моделях можно использовать:

  • model — модель автомобиля;
  • year — год выпуска;
  • transmission — коробка передач;
  • mileage_km — пробег в километрах;
  • fuelType — тип топлива;
  • l_100km — расход топлива в литрах на 100 км;
  • engineSize — объём двигателя;
  • Make — марка автомобиля.

Часть признаков уже числовая, а часть содержит категории. Поэтому этот датасет удобен для демонстрации DataPipeline: в одной цепочке можно закодировать категориальные признаки, масштабировать числовые значения и обучить модель.

Посмотрим общую информацию о датасете и схему таблицы:

uses MLABC;
begin
var ds := Datasets.UsedCarsPrice;
ds.Info;
var df := ds.Data;
df.PrintInfo;
end.

ds.Info показывает описание датасета, тип задачи, число строк, признаки и целевой столбец.

df.PrintInfo показывает типы столбцов и наличие пропущенных значений.

Вывод:

Датасет: used_cars_price
Описание:
Цены на автомобили с пробегом по модели, году выпуска, пробегу, двигателю, топливу и типу коробки передач.
Целевая переменная — цена в тыс. руб.
Задача: регрессия
Строк: 10000
Признаков: 8
Категориальные признаки: model, transmission, fuelType, Make
Целевой столбец:
price_k_rub → цена в тыс. руб.
Признаки:
model → модель
year → год выпуска
transmission → коробка передач
mileage_km → пробег в километрах
fuelType → тип топлива
l_100km → расход в литрах на 100 км
engineSize → объём двигателя в литрах
Make → марка
Строк : 10000
Столбцов : 10
=======================================================
Id : int (10000 без пропусков)
model : string (categorical) (10000 без пропусков)
year : int (10000 без пропусков)
price_k_rub : int (10000 без пропусков)
transmission : string (categorical) (10000 без пропусков)
mileage_km : int (10000 без пропусков)
fuelType : string (categorical) (10000 без пропусков)
l_100km : float (10000 без пропусков)
engineSize : float (10000 без пропусков)
Make : string (categorical) (10000 без пропусков)

По этому выводу видно, что UsedCarsPrice — достаточно большой табличный датасет: в нём 10000 автомобилей и 8 признаков для обучения модели. Целевой столбец price_k_rub содержит цену в тысячах рублей. Пропущенных значений нет, но есть несколько категориальных признаков, поэтому для модели их нужно преобразовать в числовой вид.

Перед обучением модели полезно построить график распределения цен.

В этом примере берём автомобили дешевле 6000 тыс. рублей, чтобы редкие очень дорогие автомобили не растягивали график.

uses MLABC, PlotML;
begin
var ds := Datasets.UsedCarsPrice;
var df := ds.Data.Filter(r -> r.Float('price_k_rub') <= 6000);
var price := df.ToVector('price_k_rub');
Plot.Hist(price, bins := 30);
Plot.XLabel := 'Цена, тыс. руб.';
Plot.YLabel := 'Число автомобилей';
Plot.Title := 'UsedCars: распределение цен до 6000 тыс. руб.';
end.

Вывод:

Распределение цен подержанных автомобилей до 6000 тыс. руб.

По графику видно, что основная часть автомобилей стоит примерно до 2000 тыс. руб. Более дорогие автомобили встречаются заметно реже: справа остаётся длинный хвост распределения. Поэтому при визуальном анализе мы ограничили график ценой до 6000 тыс. руб., чтобы основная часть данных была видна лучше.

В этом примере сразу используем и числовые, и категориальные признаки.

Категориальные признаки нужно преобразовать в числа. Для этого в конвейере используются OrdinalEncoder и OneHotEncoder.

uses MLABC;
begin
var ds := Datasets.UsedCarsPrice;
var df := ds.Data;
var features := [
'model',
'year',
'transmission',
'mileage_km',
'fuelType',
'l_100km',
'engineSize',
'Make'
];
var target := 'price_k_rub';
var (trainDf, testDf) := df.TrainTestSplit(0.2, seed := 42);
var pipe :=
DataPipeline.BuildRegression(
target,
features,
new OrdinalEncoder('model'),
new OneHotEncoder('transmission'),
new OneHotEncoder('fuelType'),
new OneHotEncoder('Make'),
new StandardScaler,
new DecisionTreeRegressor(10)
);
pipe.Fit(trainDf);
var pred := pipe.Predict(testDf);
var y := testDf.ToVector(target);
Println($'MAE = {Metrics.MAE(y, pred):F0}');
Println($'RMSE = {Metrics.RMSE(y, pred):F0}');
Println($'R² = {Metrics.R2(y, pred):F3}');
end.

Вывод:

MAE = 217
RMSE = 399
R² = 0.843

TrainTestSplit делит таблицу на обучающую и тестовую части.

OrdinalEncoder('model') преобразует название модели автомобиля в числовой признак.

OneHotEncoder применяется к признакам transmission, fuelType и Make. Для каждого категориального признака он создаёт набор числовых столбцов.

StandardScaler масштабирует признаки.

DecisionTreeRegressor обучается предсказывать цену автомобиля.

В конце программа выводит три метрики регрессии:

  • MAE — средняя абсолютная ошибка в тысячах рублей;
  • RMSE — ошибка, сильнее реагирующая на крупные промахи;
  • — насколько хорошо модель объясняет разброс цен.

Для первого знакомства обычно удобнее смотреть на : чем оно ближе к 1, тем лучше модель объясняет различия между ценами автомобилей.

UsedCarsPrice удобно использовать:

  • для задач регрессии на табличных данных;
  • для примеров с числовыми и категориальными признаками;
  • для демонстрации DataPipeline;
  • для сравнения разных моделей регрессии.