Новые примеры ML и исправление старых
This commit is contained in:
parent
15f45c258f
commit
9e36ff2abc
|
|
@ -43,10 +43,10 @@ begin
|
|||
var labels := model.PredictLabels(X);
|
||||
|
||||
// Получаем названия городов
|
||||
var cities := df.GetStrColumn('city');
|
||||
var cities := df.Str('city');
|
||||
|
||||
// Получаем численность населения городов
|
||||
var populations := df.GetFloatColumn('population');
|
||||
var populations := df.Float('population');
|
||||
|
||||
// Выводим, сколько кластеров нашёл алгоритм
|
||||
Println($'Число кластеров: {model.ClustersCount}');
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Пример табличной предобработки:
|
||||
// Пример табличной предобработки:
|
||||
// сначала заполняем пропуски в числовом столбце,
|
||||
// затем кодируем категориальный столбец числами.
|
||||
uses MLABC;
|
||||
|
|
@ -18,13 +18,13 @@ city,population,region
|
|||
Println;
|
||||
|
||||
// Заполняем пропуск в числовом столбце средним значением
|
||||
var imputer := new Imputer(['population']);
|
||||
df := imputer.FitTransform(df);
|
||||
var imp := new Imputer(['population']);
|
||||
df := imp.FitTransform(df);
|
||||
|
||||
// Кодируем названия регионов числами 0, 1, 2, ...
|
||||
var encoder := new OrdinalEncoder('region');
|
||||
df := encoder.FitTransform(df);
|
||||
|
||||
Println('После Imputer и LabelEncoder:');
|
||||
Println('После Imputer и OrdinalEncoder:');
|
||||
df.Print;
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
// Confusion matrix для классификации датасета Iris.
|
||||
|
||||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.Iris;
|
||||
|
||||
var (train, test) := ds.StratifiedTrainTestSplit(0.2, 42);
|
||||
|
||||
var Xtrain := train.Data.ToMatrix(train.Features);
|
||||
var Xtest := test.Data.ToMatrix(test.Features);
|
||||
|
||||
var scaler := new StandardScaler;
|
||||
Xtrain := scaler.FitTransform(Xtrain);
|
||||
Xtest := scaler.Transform(Xtest);
|
||||
|
||||
var encoder := new LabelEncoder;
|
||||
var ytrain := encoder.FitTransform(train);
|
||||
var ytest := encoder.Transform(test);
|
||||
|
||||
var model := new LogisticRegression;
|
||||
model.Fit(Xtrain, ytrain);
|
||||
|
||||
var pred := model.Predict(Xtest);
|
||||
|
||||
var cm := new ConfusionMatrix(ytest, pred);
|
||||
var acc := Metrics.Accuracy(ytest, pred);
|
||||
|
||||
Plot.ConfusionMatrix(cm, encoder.Classes{, normalize := MatrixNormalization.Rows});
|
||||
Plot.Title := $'Iris: LogisticRegression, accuracy = {acc:F3}';
|
||||
Plot.XLabel := 'Предсказанный класс';
|
||||
Plot.YLabel := 'Истинный класс';
|
||||
end.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Confusion matrix для Iris с использованием DataPipeline.
|
||||
// Рекомендуемый стиль - он проще и явно показывает намерения
|
||||
|
||||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.Iris;
|
||||
var (train, test) := ds.StratifiedTrainTestSplit(0.2, 42);
|
||||
|
||||
var pipe := DataPipeline.Build(
|
||||
TaskKind.tkClassification,
|
||||
ds.Target,
|
||||
ds.Features,
|
||||
new StandardScaler,
|
||||
new LogisticRegression
|
||||
);
|
||||
|
||||
pipe.Fit(train.Data);
|
||||
|
||||
var pred := pipe.Predict(test.Data);
|
||||
var ytest := pipe.GetEncodedLabels(test.Data);
|
||||
var cm := new ConfusionMatrix(ytest, pred);
|
||||
var acc := Metrics.Accuracy(ytest, pred);
|
||||
|
||||
Plot.ConfusionMatrix(cm, pipe.GetClassLabels{, normalize := MatrixNormalization.Rows});
|
||||
Plot.Title := $'Iris: DataPipeline, accuracy = {acc:F3}';
|
||||
Plot.XLabel := 'Предсказанный класс';
|
||||
Plot.YLabel := 'Истинный класс';
|
||||
end.
|
||||
|
|
@ -8,6 +8,6 @@ begin
|
|||
|
||||
Plot.Hist(price, bins := 40);
|
||||
Plot.Title := 'Распределение цен на квартиры в Москве';
|
||||
Plot.XLabel('Цена (руб)');
|
||||
Plot.YLabel('Количество');
|
||||
Plot.XLabel := 'Цена (руб)';
|
||||
Plot.YLabel := 'Количество';
|
||||
end.
|
||||
|
|
@ -9,7 +9,7 @@ begin
|
|||
|
||||
Plot.Points(area, price, size := 3);
|
||||
|
||||
Plot.XLabel('Площадь (м²)');
|
||||
Plot.YLabel('Цена (руб)');
|
||||
Plot.XLabel := 'Площадь (м²)';
|
||||
Plot.YLabel := 'Цена (руб)';
|
||||
Plot.Title := 'Цена квартиры vs площадь';
|
||||
end.
|
||||
|
|
@ -9,7 +9,7 @@ begin
|
|||
|
||||
Plot.Points(metro.Data.ConvertAll(x -> x*1.0), price.Data, size := 3);
|
||||
|
||||
Plot.XLabel('Минуты до метро');
|
||||
Plot.YLabel('Цена (руб)');
|
||||
Plot.XLabel := 'Минуты до метро';
|
||||
Plot.YLabel := 'Цена (руб)';
|
||||
Plot.Title := 'Зависимость цены квартиры от расстояния до метро';
|
||||
end.
|
||||
|
|
@ -8,5 +8,7 @@ begin
|
|||
df.Schema.Println;
|
||||
df.PrintInfo;
|
||||
Println;
|
||||
ds.Info;
|
||||
Println;
|
||||
df.Print;
|
||||
end.
|
||||
|
|
@ -32,7 +32,7 @@ begin
|
|||
marker := MarkerType.Circle
|
||||
);
|
||||
|
||||
Plot.XLabel('Долгота');
|
||||
Plot.YLabel('Широта');
|
||||
Plot.XLabel := 'Долгота';
|
||||
Plot.YLabel := 'Широта';
|
||||
Plot.Title := 'Кластеры городов России';
|
||||
end.
|
||||
|
|
@ -76,9 +76,7 @@ begin
|
|||
|
||||
var labels := model.PredictLabels(X);
|
||||
|
||||
var counts := new Dictionary<integer, integer>();
|
||||
foreach var l in labels do
|
||||
counts[l] := counts.Get(l, 0) + 1;
|
||||
var counts := labels.EachCount;
|
||||
|
||||
var n := df.RowCount;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ begin
|
|||
|
||||
var age := df.ToVector('Возраст');
|
||||
var fare := df.ToVector('ЦенаБилета');
|
||||
var y := df.GetIntColumn('Выжил');
|
||||
var y := df.Int('Выжил');
|
||||
|
||||
Plot.Points(age, fare, y, size := 5);
|
||||
Plot.XLabel('Возраст');
|
||||
Plot.YLabel('Цена билета');
|
||||
Plot.XLabel := 'Возраст';
|
||||
Plot.YLabel := 'Цена билета';
|
||||
Plot.Title := 'Титаник: возраст, цена билета и выживание';
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@ begin
|
|||
|
||||
Plot.HistMany([diedAges,survivedAges], bins := 20, colors := [Colors.IndianRed, Colors.SteelBlue], alpha := 0.45, legend := ['не выжили','выжили']);
|
||||
Plot.Title := 'Титаник: возраст выживших (голубой) и невыживших (красный)';
|
||||
Plot.XLabel('Возраст');
|
||||
Plot.YLabel('Число пассажиров');
|
||||
Plot.XLabel := 'Возраст';
|
||||
Plot.YLabel := 'Число пассажиров';
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -4,45 +4,39 @@ begin
|
|||
var ds := Datasets.TitanicRu;
|
||||
var df := ds.Data.Drop(['Id', 'Имя']);
|
||||
|
||||
// Заполняем пропуски.
|
||||
var ageImputer := new Imputer(['Возраст']);
|
||||
df := ageImputer.FitTransform(df);
|
||||
|
||||
var portImputer := new Imputer('Саутгемптон', ['ПортПосадки']);
|
||||
df := portImputer.FitTransform(df);
|
||||
|
||||
// Кодируем категориальные признаки числами.
|
||||
var sexEncoder := new OrdinalEncoder('Пол');
|
||||
df := sexEncoder.FitTransform(df);
|
||||
|
||||
var portEncoder := new OrdinalEncoder('ПортПосадки');
|
||||
df := portEncoder.FitTransform(df);
|
||||
|
||||
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги', 'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
|
||||
var X := df.ToMatrix(features);
|
||||
var y := df.GetIntColumn('Выжил');
|
||||
var target := 'Выжил';
|
||||
|
||||
var (Xtrain, Xtest, ytrain, ytest) := Validation.TrainTestSplit(X, y, testRatio := 0.2, seed := 42);
|
||||
var (trainDf, testDf) :=
|
||||
df.StratifiedTrainTestSplit(ds.Target, testRatio := 0.2, seed := 42);
|
||||
|
||||
var scaler := new StandardScaler;
|
||||
scaler.Fit(Xtrain);
|
||||
var XtrainScaled := scaler.Transform(Xtrain);
|
||||
var XtestScaled := scaler.Transform(Xtest);
|
||||
var prep :=
|
||||
DataPipeline.BuildPreprocessing(
|
||||
TaskKind.tkClassification,
|
||||
target,
|
||||
features,
|
||||
new Imputer(['Возраст']),
|
||||
new Imputer('Саутгемптон', ['ПортПосадки']),
|
||||
new OneHotEncoder('Пол'),
|
||||
new OneHotEncoder('ПортПосадки'),
|
||||
new StandardScaler
|
||||
);
|
||||
|
||||
var lr := new LogisticRegression(learningRate := 0.01, epochs := 2000);
|
||||
lr.Fit(XtrainScaled, ytrain);
|
||||
var predLR := lr.Predict(XtestScaled);
|
||||
var pipeLR := prep.WithModel(new LogisticRegression(learningRate := 0.01, epochs := 2000));
|
||||
pipeLR.Fit(trainDf);
|
||||
var predLR := pipeLR.Predict(testDf);
|
||||
var y := pipeLR.GetEncodedLabels(testDf);
|
||||
|
||||
var tree := new DecisionTreeClassifier(maxDepth := 5, minSamplesLeaf := 3, minSamplesSplit := 6);
|
||||
tree.Fit(Xtrain, ytrain);
|
||||
var predTree := tree.Predict(Xtest);
|
||||
var pipeTree := prep.WithModel(new DecisionTreeClassifier(maxDepth := 5, minSamplesLeaf := 3, minSamplesSplit := 6));
|
||||
pipeTree.Fit(trainDf);
|
||||
var predTree := pipeTree.Predict(testDf);
|
||||
|
||||
var forest := new RandomForestClassifier(nTrees := 100, maxDepth := 6, minSamplesLeaf := 3, minSamplesSplit := 6);
|
||||
forest.Fit(Xtrain, ytrain);
|
||||
var predForest := forest.Predict(Xtest);
|
||||
var pipeForest := prep.WithModel(new RandomForestClassifier(nTrees := 100, maxDepth := 6, minSamplesLeaf := 3, minSamplesSplit := 6));
|
||||
pipeForest.Fit(trainDf);
|
||||
var predForest := pipeForest.Predict(testDf);
|
||||
|
||||
Println('Сравнение моделей на TitanicRu');
|
||||
Println($'LogisticRegression: Accuracy = {Metrics.Accuracy(ytest, predLR):F3}');
|
||||
Println($'DecisionTreeClassifier: Accuracy = {Metrics.Accuracy(ytest, predTree):F3}');
|
||||
Println($'RandomForestClassifier: Accuracy = {Metrics.Accuracy(ytest, predForest):F3}');
|
||||
Println($'LogisticRegression: Accuracy = {Metrics.Accuracy(y, predLR):F3}');
|
||||
Println($'DecisionTreeClassifier: Accuracy = {Metrics.Accuracy(y, predTree):F3}');
|
||||
Println($'RandomForestClassifier: Accuracy = {Metrics.Accuracy(y, predForest):F3}');
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ begin
|
|||
var testAccuracy := Metrics.Accuracy(y, pred);
|
||||
|
||||
var total := 0.0;
|
||||
var folds := Validation.StratifiedKFold(df.GetIntColumn('Выжил'), 5, seed := 1);
|
||||
var folds := Validation.StratifiedKFold(df.Int('Выжил'), 5, seed := 1);
|
||||
var foldsCount := 0;
|
||||
|
||||
foreach var (trainIdx, testIdx) in folds do
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ begin
|
|||
|
||||
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги', 'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
|
||||
var X := df.ToMatrix(features);
|
||||
var y := df.GetIntColumn('Выжил');
|
||||
var y := df.Int('Выжил');
|
||||
|
||||
var model := new RandomForestClassifier(nTrees := 100, maxDepth := 6, minSamplesLeaf := 3, minSamplesSplit := 6, seed := 42);
|
||||
model.Fit(X, y);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ uses MLABC;
|
|||
|
||||
function SurvivalRate(df: DataFrame): real;
|
||||
begin
|
||||
Result := df.GetIntColumn('Выжил').Average;
|
||||
Result := df.Int('Выжил').Average;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.TitanicRu;
|
||||
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги', 'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
|
||||
var df := ds.Data.Drop(['Id', 'Имя']);
|
||||
|
||||
var (trainDf, testDf) :=
|
||||
df.StratifiedTrainTestSplit(ds.Target, testRatio := 0.2, seed := 42);
|
||||
|
||||
var pipe :=
|
||||
DataPipeline.Build(
|
||||
TaskKind.tkClassification,
|
||||
ds.Target,
|
||||
features,
|
||||
new Imputer(['Возраст']),
|
||||
new Imputer('Саутгемптон', ['ПортПосадки']),
|
||||
new OneHotEncoder('Пол'),
|
||||
new OneHotEncoder('ПортПосадки'),
|
||||
new StandardScaler,
|
||||
new LogisticRegression(learningRate := 0.1, epochs := 2000)
|
||||
);
|
||||
|
||||
pipe.Fit(trainDf);
|
||||
|
||||
var pred := pipe.Predict(testDf);
|
||||
var y := pipe.GetEncodedLabels(testDf);
|
||||
var cm := new ConfusionMatrix(y, pred);
|
||||
var acc := Metrics.Accuracy(y, pred);
|
||||
|
||||
Plot.ConfusionMatrix(cm, ['не выжил', 'выжил']);
|
||||
Plot.Title := $'TitanicRu: DataPipeline, accuracy = {acc:F3}';
|
||||
Plot.XLabel := 'Предсказанный класс';
|
||||
Plot.YLabel := 'Истинный класс';
|
||||
end.
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
uses MLABC;
|
||||
|
||||
begin
|
||||
var ds := Datasets.TitanicRu;
|
||||
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги', 'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
|
||||
var df := ds.Data.Drop(['Id', 'Имя']);
|
||||
|
||||
var (trainDf, testDf) :=
|
||||
df.StratifiedTrainTestSplit(ds.Target, testRatio := 0.2, seed := 42);
|
||||
|
||||
var pipe :=
|
||||
DataPipeline.Build(
|
||||
TaskKind.tkClassification,
|
||||
ds.Target,
|
||||
features,
|
||||
new Imputer(['Возраст']),
|
||||
new Imputer('Саутгемптон', ['ПортПосадки']),
|
||||
new OneHotEncoder('Пол'),
|
||||
new OneHotEncoder('ПортПосадки'),
|
||||
new StandardScaler,
|
||||
new RandomForestClassifier(nTrees := 100, maxDepth := 6, minSamplesLeaf := 3, minSamplesSplit := 6)
|
||||
);
|
||||
|
||||
pipe.Fit(trainDf);
|
||||
|
||||
var pred := pipe.Predict(testDf);
|
||||
var y := pipe.GetEncodedLabels(testDf);
|
||||
|
||||
Println('TitanicRu: Precision, Recall и F1');
|
||||
Println;
|
||||
Println('Precision — какая доля пассажиров, предсказанных как "выжил", действительно выжила.');
|
||||
Println('Recall — какую долю реально выживших пассажиров модель нашла.');
|
||||
Println('F1 — общий баланс между Precision и Recall.');
|
||||
Println;
|
||||
Println($'Accuracy = {Metrics.Accuracy(y, pred):F3}');
|
||||
Println($'Precision = {Metrics.Precision(y, pred):F3}');
|
||||
Println($'Recall = {Metrics.Recall(y, pred):F3}');
|
||||
Println($'F1 = {Metrics.F1(y, pred):F3}');
|
||||
end.
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
uses MLABC;
|
||||
|
||||
function LabelText(v: integer): string;
|
||||
begin
|
||||
Result := if v = 1 then 'выжил' else 'не выжил';
|
||||
end;
|
||||
|
||||
begin
|
||||
var ds := Datasets.TitanicRu;
|
||||
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги', 'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
|
||||
|
||||
var fullDf := ds.Data;
|
||||
var (trainFull, testFull) :=
|
||||
fullDf.StratifiedTrainTestSplit(ds.Target, testRatio := 0.2, seed := 42);
|
||||
|
||||
var trainDf := trainFull.Drop(['Id', 'Имя']);
|
||||
var testDf := testFull.Drop(['Id', 'Имя']);
|
||||
|
||||
var pipe :=
|
||||
DataPipeline.Build(
|
||||
TaskKind.tkClassification,
|
||||
ds.Target,
|
||||
features,
|
||||
new Imputer(['Возраст']),
|
||||
new Imputer('Саутгемптон', ['ПортПосадки']),
|
||||
new OneHotEncoder('Пол'),
|
||||
new OneHotEncoder('ПортПосадки'),
|
||||
new StandardScaler,
|
||||
new RandomForestClassifier(nTrees := 100, maxDepth := 6, minSamplesLeaf := 3, minSamplesSplit := 6)
|
||||
);
|
||||
|
||||
pipe.Fit(trainDf);
|
||||
|
||||
var pred := pipe.Predict(testDf);
|
||||
var y := pipe.GetEncodedLabels(testDf);
|
||||
var predInt := pred.ToIntArray;
|
||||
var yInt := y.ToIntArray;
|
||||
var cur := testFull.GetCursor;
|
||||
|
||||
Println('TitanicRu: пассажиры, классифицированные неправильно');
|
||||
Println;
|
||||
|
||||
var shown := 0;
|
||||
while cur.MoveNext do
|
||||
begin
|
||||
var i := cur.Position;
|
||||
if yInt[i] <> predInt[i] then
|
||||
begin
|
||||
var id := cur.Int('Id');
|
||||
var name := cur.Str('Имя');
|
||||
var sex := cur.Str('Пол');
|
||||
var pclass := cur.Int('Класс');
|
||||
var age := cur.Float('Возраст');
|
||||
var fare := cur.Float('ЦенаБилета');
|
||||
|
||||
Println($'Id={id}, {name}');
|
||||
Println($' Пол={sex}, класс={pclass}, возраст={age:F1}, билет={fare:F1}');
|
||||
Println($' Истина: {LabelText(yInt[i])}, прогноз: {LabelText(predInt[i])}');
|
||||
Println;
|
||||
|
||||
shown += 1;
|
||||
if shown >= 10 then break;
|
||||
end;
|
||||
end;
|
||||
end.
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
uses MLABC;
|
||||
|
||||
function BuildPipe(features: array of string): DataPipeline;
|
||||
begin
|
||||
Result :=
|
||||
DataPipeline.Build(
|
||||
TaskKind.tkClassification,
|
||||
'Выжил',
|
||||
features,
|
||||
new Imputer(['Возраст']),
|
||||
new Imputer('Саутгемптон', ['ПортПосадки']),
|
||||
new OneHotEncoder('Пол'),
|
||||
new OneHotEncoder('ПортПосадки'),
|
||||
new StandardScaler,
|
||||
new RandomForestClassifier(nTrees := 100, maxDepth := 6, minSamplesLeaf := 3, minSamplesSplit := 6)
|
||||
);
|
||||
end;
|
||||
|
||||
function TestAccuracy(df: DataFrame; features: array of string): real;
|
||||
begin
|
||||
var (trainDf, testDf) :=
|
||||
df.StratifiedTrainTestSplit('Выжил', testRatio := 0.2, seed := 42);
|
||||
|
||||
var pipe := BuildPipe(features);
|
||||
pipe.Fit(trainDf);
|
||||
|
||||
var pred := pipe.Predict(testDf);
|
||||
var y := pipe.GetEncodedLabels(testDf);
|
||||
Result := Metrics.Accuracy(y, pred);
|
||||
end;
|
||||
|
||||
begin
|
||||
var ds := Datasets.TitanicRu;
|
||||
var df := ds.Data.Drop(['Id', 'Имя']);
|
||||
|
||||
var allFeatures :=
|
||||
SetOf('Класс', 'Пол', 'Возраст', 'БратьяИСупруги', 'РодителиИДети', 'ЦенаБилета', 'ПортПосадки');
|
||||
var noSex := (allFeatures - ['Пол']).ToArray;
|
||||
var noClass := (allFeatures - ['Класс']).ToArray;
|
||||
|
||||
var accAll := TestAccuracy(df, allFeatures.ToArray);
|
||||
var accNoSex := TestAccuracy(df, noSex);
|
||||
var accNoClass := TestAccuracy(df, noClass);
|
||||
|
||||
Println('TitanicRu: влияние признаков на качество модели');
|
||||
Println;
|
||||
Println('Идея примера: убираем один важный признак и смотрим, насколько хуже становится классификация.');
|
||||
Println;
|
||||
Println($'Все признаки: Accuracy = {accAll:F3}');
|
||||
Println($'Без признака "Пол": Accuracy = {accNoSex:F3}');
|
||||
Println($'Без признака "Класс": Accuracy = {accNoClass:F3}');
|
||||
end.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
uses MLABC;
|
||||
|
||||
begin
|
||||
Datasets.Language := 'ru';
|
||||
|
||||
var ds := Datasets.UsedCarsPrice;
|
||||
ds.Info;
|
||||
Println;
|
||||
|
||||
ds.Data.Print(20);
|
||||
end.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
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.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.UsedCarsPrice;
|
||||
var df := ds.Data.Filter(r -> r.Float('price_k_rub') <= 6000);
|
||||
|
||||
var mileage := df.ToVector('mileage_km');
|
||||
var price := df.ToVector('price_k_rub');
|
||||
|
||||
Plot.Points(mileage, price, size := 4);
|
||||
Plot.XLabel := 'Пробег, км';
|
||||
Plot.YLabel := 'Цена, тыс. руб.';
|
||||
Plot.Title := 'UsedCars: цена и пробег';
|
||||
end.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.UsedCarsPrice;
|
||||
var df := ds.Data.Filter(r -> r.Float('price_k_rub') <= 6000);
|
||||
|
||||
var names := Arr('year', 'mileage_1000km', 'l_100km', 'engineSize');
|
||||
var X := df.ToMatrix(Arr('year', 'mileage_km', 'l_100km', 'engineSize'));
|
||||
|
||||
for var i := 0 to X.RowCount - 1 do
|
||||
X[i, 1] := X[i, 1] / 1000.0;
|
||||
|
||||
var price := df.ToVector('price_k_rub');
|
||||
|
||||
Plot.PairPlot(X.Data, price.Data, names, bins := 6, maxPoints := 2000);
|
||||
Plot.Title := 'UsedCars: признаки, окрашенные по цене';
|
||||
end.
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.UsedCarsPrice;
|
||||
var df := ds.Data.Filter(r -> r.Float('price_k_rub') <= 6000);
|
||||
|
||||
var year := df.ToVector('year');
|
||||
var price := df.ToVector('price_k_rub');
|
||||
var make := df.EncodeLabels('Make');
|
||||
|
||||
Plot.Points(year, price, make, size := 4);
|
||||
Plot.XLabel := 'Год выпуска';
|
||||
Plot.YLabel := 'Цена, тыс. руб.';
|
||||
Plot.Title := 'UsedCars: цена по годам и маркам';
|
||||
end.
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
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.Build(
|
||||
TaskKind.tkRegression,
|
||||
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('Прогнозирование цены автомобилей (DecisionTreeRegressor)');
|
||||
Println($'MAE = {Metrics.MAE(y, pred):F0}');
|
||||
Println($'RMSE = {Metrics.RMSE(y, pred):F0}');
|
||||
Println($'R² = {Metrics.R2(y, pred):F3}');
|
||||
end.
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
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 prep :=
|
||||
DataPipeline.BuildPreprocessing(
|
||||
TaskKind.tkRegression,
|
||||
target,
|
||||
features,
|
||||
new OrdinalEncoder('model'),
|
||||
new OneHotEncoder('transmission'),
|
||||
new OneHotEncoder('fuelType'),
|
||||
new OneHotEncoder('Make'),
|
||||
new StandardScaler
|
||||
);
|
||||
|
||||
var pipeTree := prep.WithModel(new DecisionTreeRegressor(12));
|
||||
|
||||
pipeTree.Fit(trainDf);
|
||||
var predTree := pipeTree.Predict(testDf);
|
||||
|
||||
var pipeForest := prep.WithModel(new RandomForestRegressor(12, 50));
|
||||
|
||||
pipeForest.Fit(trainDf);
|
||||
var predForest := pipeForest.Predict(testDf);
|
||||
|
||||
var y := testDf.ToVector(target);
|
||||
|
||||
Println('Сравнение моделей регрессии');
|
||||
Println($'DecisionTreeRegressor: R² = {Metrics.R2(y, predTree):F3}');
|
||||
Println($'RandomForestRegressor: R² = {Metrics.R2(y, predForest):F3}');
|
||||
end.
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
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 prep :=
|
||||
DataPipeline.BuildPreprocessing(
|
||||
TaskKind.tkRegression,
|
||||
target,
|
||||
features,
|
||||
new OrdinalEncoder('model'),
|
||||
new OneHotEncoder('transmission'),
|
||||
new OneHotEncoder('fuelType'),
|
||||
new OneHotEncoder('Make'),
|
||||
new StandardScaler
|
||||
);
|
||||
|
||||
var pipe := prep.WithModel(new RandomForestRegressor(12, 50));
|
||||
pipe.Fit(trainDf);
|
||||
|
||||
var pred := pipe.Predict(testDf);
|
||||
var y := testDf.ToVector(target);
|
||||
var testR2 := Metrics.R2(y, pred);
|
||||
|
||||
var total := 0.0;
|
||||
var folds := Validation.KFold(df.RowCount, 5, seed := 1);
|
||||
var foldsCount := 0;
|
||||
|
||||
foreach var (trainIdx, testIdx) in folds do
|
||||
begin
|
||||
var foldTrain := df.TakeRows(trainIdx);
|
||||
var foldTest := df.TakeRows(testIdx);
|
||||
|
||||
var foldPipe := prep.WithModel(new RandomForestRegressor(12, 50));
|
||||
foldPipe.Fit(foldTrain);
|
||||
|
||||
var foldPred := foldPipe.Predict(foldTest);
|
||||
var foldY := foldTest.ToVector(target);
|
||||
|
||||
total += Metrics.R2(foldY, foldPred);
|
||||
foldsCount += 1;
|
||||
end;
|
||||
|
||||
var cvR2 := total / foldsCount;
|
||||
|
||||
Println('Оценка RandomForestRegressor двумя способами');
|
||||
Println($'R² на тестовой выборке: {testR2:F3}');
|
||||
Println($'Средний R² по кросс-валидации: {cvR2:F3}');
|
||||
end.
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
uses MLABC;
|
||||
|
||||
begin
|
||||
var ds := Datasets.UsedCarsPrice;
|
||||
var df := ds.Data;
|
||||
|
||||
// В этом примере смотрим не только на R²,
|
||||
// но и на конкретные ошибки модели для отдельных автомобилей.
|
||||
// Остаток = истинная цена - предсказанная цена.
|
||||
// Если остаток положительный, модель занизила цену.
|
||||
// Если отрицательный, модель завысила цену.
|
||||
|
||||
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.Build(
|
||||
TaskKind.tkRegression,
|
||||
target,
|
||||
features,
|
||||
new OrdinalEncoder('model'),
|
||||
new OneHotEncoder('transmission'),
|
||||
new OneHotEncoder('fuelType'),
|
||||
new OneHotEncoder('Make'),
|
||||
new StandardScaler,
|
||||
new RandomForestRegressor(12, 50)
|
||||
);
|
||||
|
||||
pipe.Fit(trainDf);
|
||||
|
||||
var pred := pipe.Predict(testDf);
|
||||
var y := testDf.ToVector(target);
|
||||
|
||||
var models := testDf.Str('model');
|
||||
var makes := testDf.Str('Make');
|
||||
var years := testDf.Int('year');
|
||||
|
||||
var idx := Arr(0..pred.Length - 1);
|
||||
idx := idx.OrderByDescending(i -> Abs(y[i] - pred[i])).ToArray;
|
||||
|
||||
Println('UsedCars: самые большие ошибки модели');
|
||||
Println;
|
||||
Println('Остаток = истинная цена - предсказанная цена.');
|
||||
Println('Положительный остаток означает, что модель занизила цену.');
|
||||
Println('Отрицательный остаток означает, что модель завысила цену.');
|
||||
Println;
|
||||
|
||||
for var k := 0 to Min(9, idx.Length - 1) do
|
||||
begin
|
||||
var i := idx[k];
|
||||
var residual := y[i] - pred[i];
|
||||
|
||||
Println($'{makes[i]} {models[i]}, {years[i]}');
|
||||
Println($' Истинная цена: {y[i]:F0} тыс. руб.');
|
||||
Println($' Прогноз: {pred[i]:F0} тыс. руб.');
|
||||
Println($' Остаток: {residual:F0} тыс. руб.');
|
||||
Println;
|
||||
end;
|
||||
end.
|
||||
|
|
@ -13,8 +13,8 @@ begin
|
|||
|
||||
// --- визуализация
|
||||
Plot.Title('MakeRegression синтетический датасет');
|
||||
Plot.XLabel('признак');
|
||||
Plot.YLabel('целевая переменная');
|
||||
Plot.XLabel := 'признак';
|
||||
Plot.YLabel := 'целевая переменная';
|
||||
|
||||
Plot.Points(X.Col(0), y.ToArray, size := 3);
|
||||
end.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// В этом примере строится scatter plot для двух признаков датасета Iris.
|
||||
// В этом примере строится scatter plot для двух признаков датасета Iris.
|
||||
//
|
||||
// По оси X откладывается длина чашелистика,
|
||||
// по оси Y — ширина чашелистика.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.Iris;
|
||||
var X := ds.Data.ToMatrix(ds.Features);
|
||||
var y := ds.Data.EncodeLabels(ds.Target);
|
||||
|
||||
var scaler := new StandardScaler;
|
||||
scaler.Fit(X);
|
||||
X := scaler.Transform(X);
|
||||
|
||||
var pca := new PCATransformer(2);
|
||||
pca.Fit(X);
|
||||
var X2 := pca.Transform(X);
|
||||
|
||||
Plot.Points(X2.Col(0), X2.Col(1), y, size := 5);
|
||||
Plot.XLabel := 'Первая главная компонента';
|
||||
Plot.YLabel := 'Вторая главная компонента';
|
||||
Plot.Title := 'Iris: проекция на две главные компоненты';
|
||||
end.
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
uses PlotML;
|
||||
|
||||
begin
|
||||
var fig := Plot.Grid(2, 2);
|
||||
|
||||
var labels := ['sedan', 'suv', 'hatchback', 'wagon'];
|
||||
|
||||
fig[0, 0].Bar(labels, [120.0, 95.0, 70.0, 40.0]);
|
||||
fig[0, 0].Title := 'Cars A';
|
||||
fig[0, 0].XLabel := 'count';
|
||||
|
||||
fig[0, 1].Bar(labels, [80.0, 110.0, 55.0, 30.0]);
|
||||
fig[0, 1].Title := 'Cars B';
|
||||
fig[0, 1].XLabel := 'count';
|
||||
|
||||
fig[1, 0].Bar(labels, [45.0, 65.0, 100.0, 25.0]);
|
||||
fig[1, 0].Title := 'Cars C';
|
||||
fig[1, 0].XLabel := 'count';
|
||||
|
||||
fig[1, 1].Bar(labels, [30.0, 50.0, 75.0, 90.0]);
|
||||
fig[1, 1].Title := 'Cars D';
|
||||
fig[1, 1].XLabel := 'count';
|
||||
|
||||
Plot.Title := 'Bar plots 2x2';
|
||||
end.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// В этом примере строится confusion matrix для классификации Iris.
|
||||
|
||||
uses MLABC, PlotML;
|
||||
|
||||
begin
|
||||
var ds := Datasets.Iris;
|
||||
|
||||
var (train, test) := ds.StratifiedTrainTestSplit(0.2, 42);
|
||||
|
||||
var Xtrain := train.Data.ToMatrix(train.Features);
|
||||
var Xtest := test.Data.ToMatrix(test.Features);
|
||||
|
||||
var encoder := new LabelEncoder;
|
||||
var ytrain := encoder.FitTransform(train);
|
||||
var ytest := encoder.Transform(test);
|
||||
|
||||
var model := new LogisticRegression;
|
||||
model.Fit(Xtrain, ytrain);
|
||||
|
||||
var pred := model.Predict(Xtest);
|
||||
var cm := new ConfusionMatrix(ytest, pred);
|
||||
var acc := Metrics.Accuracy(ytest, pred);
|
||||
|
||||
Plot.ConfusionMatrix(cm, encoder.Classes, normalize := MatrixNormalization.Rows);
|
||||
Plot.Title := $'Iris: LogisticRegression, accuracy = {acc:F3}';
|
||||
Plot.XLabel := 'Predicted';
|
||||
Plot.YLabel := 'Actual';
|
||||
end.
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
uses PlotML;
|
||||
|
||||
begin
|
||||
var labels := ['cat', 'dog', 'fox'];
|
||||
|
||||
var m1 := Matr(
|
||||
[3.0, 0, 0],
|
||||
[1.0, 2, 1],
|
||||
[0.0, 1, 2]
|
||||
);
|
||||
|
||||
var m2 := Matr(
|
||||
[4.0, 1, 0],
|
||||
[0.0, 3, 1],
|
||||
[1.0, 0, 2]
|
||||
);
|
||||
|
||||
var m3 := Matr(
|
||||
[2.0, 1, 1],
|
||||
[0.0, 4, 0],
|
||||
[1.0, 1, 3]
|
||||
);
|
||||
|
||||
var m4 := Matr(
|
||||
[5.0, 0, 1],
|
||||
[1.0, 3, 0],
|
||||
[0.0, 2, 4]
|
||||
);
|
||||
|
||||
var fig := Plot.Grid(2, 2);
|
||||
|
||||
fig[0, 0].ConfusionMatrix(m1, labels);
|
||||
fig[0, 0].Title := 'Model A';
|
||||
fig[0, 0].YLabel := 'Actual';
|
||||
|
||||
fig[0, 1].ConfusionMatrix(m2, labels);
|
||||
fig[0, 1].Title := 'Model B';
|
||||
|
||||
fig[1, 0].ConfusionMatrix(m3, labels);
|
||||
fig[1, 0].Title := 'Model C';
|
||||
fig[1, 0].XLabel := 'Predicted';
|
||||
fig[1, 0].YLabel := 'Actual';
|
||||
|
||||
fig[1, 1].ConfusionMatrix(m4, labels);
|
||||
fig[1, 1].Title := 'Model D';
|
||||
fig[1, 1].XLabel := 'Predicted';
|
||||
|
||||
Plot.Title := 'Confusion Matrices';
|
||||
end.
|
||||
Loading…
Reference in a new issue