ML небольшие изменения
This commit is contained in:
parent
18e4c5ba79
commit
d588671441
|
|
@ -111,6 +111,8 @@ type
|
|||
function ColumnCount: integer;
|
||||
/// Возвращает тип столбца по номеру
|
||||
function GetColumnType(colIndex: integer): ColumnType;
|
||||
/// Возвращает тип столбца по имени
|
||||
function GetColumnType(name: string): ColumnType := GetColumnType(ColumnIndex(name));
|
||||
/// Возвращает индекс столбца по имени
|
||||
function ColumnIndex(name: string): integer;
|
||||
|
||||
|
|
|
|||
|
|
@ -262,12 +262,27 @@ begin
|
|||
Result := Data.ToMatrix(Features);
|
||||
end;
|
||||
|
||||
function Dataset.ToY(): Vector;
|
||||
function Dataset.ToY: Vector;
|
||||
begin
|
||||
if Task = Clustering then
|
||||
ArgumentError(ER_DATASET_NO_TARGET);
|
||||
|
||||
Result := Data.ToVector(Target);
|
||||
var t := Data.GetColumnType(Target);
|
||||
case t of
|
||||
ColumnType.ctInt:
|
||||
Result := new Vector(Data.GetIntColumn(Target));
|
||||
ColumnType.ctFloat:
|
||||
Result := Data.ToVector(Target);
|
||||
ColumnType.ctStr:
|
||||
Result := new Vector(EncodeLabels(Data.GetStrColumn(Target)));
|
||||
ColumnType.ctBool:
|
||||
begin
|
||||
var b := Data.GetBoolColumn(Target);
|
||||
var v := new Vector(b.Length);
|
||||
|
||||
for var i := 0 to b.Length - 1 do
|
||||
v[i] := if b[i] then 1.0 else 0.0;
|
||||
|
||||
Result := v;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function Dataset.ToXY(): (Matrix, Vector);
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ type
|
|||
|
||||
public
|
||||
/// Создает классификационное дерево:
|
||||
/// • maxDepth — максимальная глубина дерева.
|
||||
/// • maxDepth — максимальная глубина дерева (-1 означает без ограничения).
|
||||
/// • minSamplesSplit — минимальное число объектов для разбиения узла.
|
||||
/// • minSamplesLeaf — минимальное число объектов в листе
|
||||
constructor Create(maxDepth: integer := 10; minSamplesSplit: integer := 2; minSamplesLeaf: integer := 1; seed: integer := -1);
|
||||
|
|
@ -489,7 +489,7 @@ type
|
|||
|
||||
public
|
||||
/// Создает регрессионное дерево:
|
||||
/// • maxDepth — максимальная глубина.
|
||||
/// • maxDepth — максимальная глубина (-1 означает без ограничения).
|
||||
/// • minSamplesSplit — минимальное число объектов для разбиения.
|
||||
/// • minSamplesLeaf — минимальное число объектов в листе.
|
||||
/// • leafL2 — коэффициент L2-регуляризации значения листа
|
||||
|
|
@ -622,12 +622,12 @@ type
|
|||
public
|
||||
/// Создает регрессионный случайный лес:
|
||||
/// • nTrees — число деревьев в ансамбле.
|
||||
/// • maxDepth — максимальная глубина деревьев.
|
||||
/// • maxDepth — максимальная глубина деревьев (-1 означает без ограничения).
|
||||
/// • minSamplesSplit — минимальное число объектов для разбиения узла.
|
||||
/// • minSamplesLeaf — минимальное число объектов в листе.
|
||||
/// • maxFeaturesMode — режим выбора числа признаков, рассматриваемых при поиске разбиения
|
||||
constructor Create(nTrees: integer := 100;
|
||||
maxDepth: integer := integer.MaxValue;
|
||||
maxDepth: integer := -1;
|
||||
minSamplesSplit: integer := 2;
|
||||
minSamplesLeaf: integer := 1;
|
||||
maxFeaturesMode: TMaxFeaturesMode := TMaxFeaturesMode.HalfFeatures;
|
||||
|
|
@ -669,13 +669,13 @@ type
|
|||
public
|
||||
/// Создает классификационный случайный лес:
|
||||
/// • nTrees — число деревьев в ансамбле.
|
||||
/// • maxDepth — максимальная глубина каждого дерева.
|
||||
/// • maxDepth — максимальная глубина каждого дерева (-1 означает без ограничения).
|
||||
/// • minSamplesSplit — минимальное число объектов для разбиения узла.
|
||||
/// • minSamplesLeaf — минимальное число объектов в листе.
|
||||
/// • maxFeaturesMode — режим выбора числа признаков при поиске разбиения, по умолчанию используется sqrt(p),
|
||||
/// что является стандартом для классификации
|
||||
constructor Create(nTrees: integer := 100;
|
||||
maxDepth: integer := integer.MaxValue;
|
||||
maxDepth: integer := -1;
|
||||
minSamplesSplit: integer := 2;
|
||||
minSamplesLeaf: integer := 1;
|
||||
maxFeaturesMode: TMaxFeaturesMode := TMaxFeaturesMode.SqrtFeatures;
|
||||
|
|
@ -2777,7 +2777,7 @@ constructor DecisionTreeBase.Create(
|
|||
minSamplesLeaf: integer;
|
||||
seed: integer);
|
||||
begin
|
||||
if maxDepth <= 0 then
|
||||
if maxDepth < -1 then
|
||||
ArgumentOutOfRangeError(ER_MAX_DEPTH_INVALID, maxDepth);
|
||||
|
||||
if maxDepth > MAX_ALLOWED_TREE_DEPTH then
|
||||
|
|
@ -2898,7 +2898,7 @@ end;
|
|||
function DecisionTreeBase.BuildTree(X: Matrix; y: Vector;
|
||||
indices: array of integer; depth: integer): DecisionTreeNode;
|
||||
begin
|
||||
if (fMaxDepth > 0) and (depth >= fMaxDepth) then
|
||||
if (fMaxDepth >= 0) and (depth >= fMaxDepth) then
|
||||
exit(LeafNode(LeafValue(y, indices)));
|
||||
|
||||
if indices.Length < fMinSamplesSplit then
|
||||
|
|
@ -3298,7 +3298,7 @@ begin
|
|||
if fMinSamplesLeaf < 1 then
|
||||
ArgumentOutOfRangeError(ER_MINSAMPLESLEAF_INVALID, fMinSamplesLeaf);
|
||||
|
||||
if (fMaxDepth < 0) then
|
||||
if fMaxDepth < -1 then
|
||||
ArgumentOutOfRangeError(ER_MAX_DEPTH_INVALID, fMaxDepth);
|
||||
|
||||
if fMaxDepth > 10000 then
|
||||
|
|
@ -3530,7 +3530,7 @@ begin
|
|||
if fLeafL2 < 0 then
|
||||
ArgumentOutOfRangeError(ER_L2_NEGATIVE, fLeafL2);
|
||||
|
||||
if fMaxDepth < 0 then
|
||||
if fMaxDepth < -1 then
|
||||
ArgumentOutOfRangeError(ER_MAX_DEPTH_INVALID, fMaxDepth);
|
||||
|
||||
if fMaxDepth > 10000 then
|
||||
|
|
@ -3651,7 +3651,7 @@ begin
|
|||
if nTrees <= 0 then
|
||||
ArgumentOutOfRangeError(ER_NTREES_INVALID, nTrees);
|
||||
|
||||
if maxDepth <= 0 then
|
||||
if maxDepth < -1 then
|
||||
ArgumentOutOfRangeError(ER_MAX_DEPTH_INVALID, maxDepth);
|
||||
|
||||
if minSamplesSplit < 2 then
|
||||
|
|
@ -3759,7 +3759,7 @@ begin
|
|||
if fMinSamplesLeaf >= fMinSamplesSplit then
|
||||
ArgumentError(ER_MIN_LEAF_GE_SPLIT, fMinSamplesLeaf, fMinSamplesSplit);
|
||||
|
||||
if fMaxDepth < 0 then
|
||||
if fMaxDepth < -1 then
|
||||
ArgumentOutOfRangeError(ER_MAX_DEPTH_INVALID, fMaxDepth);
|
||||
|
||||
if fMaxDepth > MAX_ALLOWED_TREE_DEPTH then
|
||||
|
|
@ -3940,7 +3940,7 @@ end;
|
|||
function RandomForestRegressor.ToString: string;
|
||||
begin
|
||||
var depthStr :=
|
||||
if fMaxDepth = integer.MaxValue then '∞'
|
||||
if fMaxDepth = -1 then '∞'
|
||||
else fMaxDepth.ToString;
|
||||
|
||||
var seedPart :=
|
||||
|
|
@ -4003,7 +4003,7 @@ begin
|
|||
if fMinSamplesLeaf >= fMinSamplesSplit then
|
||||
ArgumentError(ER_MIN_LEAF_GE_SPLIT, fMinSamplesLeaf, fMinSamplesSplit);
|
||||
|
||||
if fMaxDepth < 0 then
|
||||
if fMaxDepth < -1 then
|
||||
ArgumentOutOfRangeError(ER_MAX_DEPTH_INVALID, fMaxDepth);
|
||||
|
||||
if fMaxDepth > MAX_ALLOWED_TREE_DEPTH then
|
||||
|
|
@ -4274,9 +4274,12 @@ begin
|
|||
rf.fHasOOBScore := fHasOOBScore;
|
||||
|
||||
// --- trees ---
|
||||
SetLength(rf.fTrees, fTrees.Length);
|
||||
for var i := 0 to fTrees.Length - 1 do
|
||||
rf.fTrees[i] := DecisionTreeClassifier(fTrees[i].Clone);
|
||||
if fTrees <> nil then
|
||||
begin
|
||||
SetLength(rf.fTrees, fTrees.Length);
|
||||
for var i := 0 to fTrees.Length - 1 do
|
||||
rf.fTrees[i] := DecisionTreeClassifier(fTrees[i].Clone);
|
||||
end;
|
||||
|
||||
Result := rf;
|
||||
end;
|
||||
|
|
@ -4300,7 +4303,7 @@ end;
|
|||
function RandomForestClassifier.ToString: string;
|
||||
begin
|
||||
var depthStr :=
|
||||
if fMaxDepth = integer.MaxValue then '∞'
|
||||
if fMaxDepth = -1 then '∞'
|
||||
else fMaxDepth.ToString;
|
||||
|
||||
var seedPart :=
|
||||
|
|
|
|||
|
|
@ -523,7 +523,27 @@ end;
|
|||
|
||||
static function Metrics.Accuracy(yTrue, yPred: Vector): real;
|
||||
begin
|
||||
Result := ConfusionMatrix.Create(yTrue, yPred).Accuracy;
|
||||
if yTrue = nil then
|
||||
ArgumentNullError(ER_ARG_NULL, 'yTrue');
|
||||
|
||||
if yPred = nil then
|
||||
ArgumentNullError(ER_ARG_NULL, 'yPred');
|
||||
|
||||
var n := yTrue.Length;
|
||||
|
||||
if n <> yPred.Length then
|
||||
DimensionError(ER_DIM_MISMATCH, yTrue.Length, yPred.Length);
|
||||
|
||||
if n = 0 then
|
||||
ArgumentError(ER_EMPTY_DATA, 'Accuracy');
|
||||
|
||||
var correct := 0;
|
||||
|
||||
for var i := 0 to n - 1 do
|
||||
if yTrue[i] = yPred[i] then
|
||||
correct += 1;
|
||||
|
||||
Result := correct / n;
|
||||
end;
|
||||
|
||||
static function Metrics.Precision(yTrue, yPred: Vector): real;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ type
|
|||
BrushWPF = System.Windows.Media.SolidColorBrush;
|
||||
Colors = System.Windows.Media.Colors;
|
||||
ColorWPF = System.Windows.Media.Color;
|
||||
|
||||
|
||||
const DefaultColor = default(ColorWPF);
|
||||
|
||||
type
|
||||
MarkerType = (Circle, Box, Triangle, Diamond, Cross);
|
||||
|
||||
Palettes = static class
|
||||
|
|
@ -60,14 +63,19 @@ type
|
|||
public
|
||||
constructor Create(g: GridWPF; r,c: integer);
|
||||
|
||||
procedure LineGraph(x, y: array of real; color: ColorWPF? := nil;
|
||||
procedure LineGraph(x, y: array of real; color: ColorWPF := DefaultColor;
|
||||
thickness: real := 2; legend: string := nil);
|
||||
|
||||
procedure Points(x, y: array of real; color: ColorWPF? := nil;
|
||||
procedure Points(x, y: array of real; color: ColorWPF := DefaultColor;
|
||||
size: real := 6; marker: MarkerType := MarkerType.Circle; legend: string := nil);
|
||||
|
||||
procedure Points(x, y: array of real; labels: array of integer;
|
||||
size: real := 6; marker: MarkerType := MarkerType.Circle);
|
||||
|
||||
procedure Heatmap(m: array[,] of real);
|
||||
|
||||
procedure Text(s: string; x: real := 0.5; y: real := 0.5);
|
||||
|
||||
procedure SetPalette(name: string);
|
||||
procedure Title(s: string);
|
||||
procedure XLabel(s: string);
|
||||
|
|
@ -99,6 +107,8 @@ type
|
|||
|
||||
static procedure DrawLine(chart: ChartWPF; x, y: array of real;
|
||||
color: ColorWPF; thickness: real; legend: string);
|
||||
|
||||
static procedure DrawText(chart: ChartWPF; s: string; x, y: real);
|
||||
|
||||
static procedure DrawPoints(chart: ChartWPF; x, y: array of real;
|
||||
color: ColorWPF; size: real; marker: MarkerType; legend: string);
|
||||
|
|
@ -109,11 +119,11 @@ type
|
|||
static procedure AddSeries(chart: ChartWPF; series: UIElement);
|
||||
|
||||
static procedure LineGraph(x, y: array of real;
|
||||
color: ColorWPF? := nil; thickness: real := 2; legend: string := nil);
|
||||
color: ColorWPF := DefaultColor; thickness: real := 2; legend: string := nil);
|
||||
static procedure Points(x, y: array of real;
|
||||
color: ColorWPF? := nil; size: real := 6; marker: MarkerType := MarkerType.Circle; legend: string := nil);
|
||||
color: ColorWPF := DefaultColor; size: real := 6; marker: MarkerType := MarkerType.Circle; legend: string := nil);
|
||||
static procedure Points(x, y: array of real;
|
||||
labels: array of integer; color: ColorWPF? := nil; size: real := 6; marker: MarkerType := MarkerType.Circle);
|
||||
labels: array of integer; color: ColorWPF := DefaultColor; size: real := 6; marker: MarkerType := MarkerType.Circle);
|
||||
|
||||
static procedure Heatmap(m: array[,] of real);
|
||||
|
||||
|
|
@ -418,32 +428,59 @@ begin
|
|||
parentGrid.Children.Add(chart);
|
||||
end;
|
||||
|
||||
procedure Cell.LineGraph(x, y: array of real; color: ColorWPF?;
|
||||
procedure Cell.LineGraph(x, y: array of real; color: ColorWPF;
|
||||
thickness: real; legend: string);
|
||||
begin
|
||||
Plot.RunUI(() ->
|
||||
begin
|
||||
EnsureChart;
|
||||
|
||||
var clr := if color.HasValue then color.Value else NextColor;
|
||||
var clr := if color<>DefaultColor then color else NextColor;
|
||||
|
||||
Plot.DrawLine(chart, x, y, clr, thickness, legend);
|
||||
end);
|
||||
end;
|
||||
|
||||
procedure Cell.Points(x, y: array of real; color: ColorWPF?;
|
||||
procedure Cell.Points(x, y: array of real; color: ColorWPF;
|
||||
size: real; marker: MarkerType; legend: string);
|
||||
begin
|
||||
Plot.RunUI(() ->
|
||||
begin
|
||||
EnsureChart;
|
||||
|
||||
var clr := if color.HasValue then color.Value else NextColor;
|
||||
var clr := if color<>DefaultColor then color else NextColor;
|
||||
|
||||
Plot.DrawPoints(chart, x, y, clr, size, marker, legend);
|
||||
end);
|
||||
end;
|
||||
|
||||
procedure Cell.Points(x, y: array of real; labels: array of integer;
|
||||
size: real; marker: MarkerType);
|
||||
begin
|
||||
if (x = nil) or (y = nil) or (labels = nil) then
|
||||
raise new System.ArgumentNullException;
|
||||
|
||||
if (x.Length <> y.Length) or (x.Length <> labels.Length) then
|
||||
raise new System.ArgumentException('Points: array sizes mismatch');
|
||||
|
||||
var classes := labels.Distinct.ToArray;
|
||||
&Array.Sort(classes);
|
||||
|
||||
var pal := CurrentPalette;
|
||||
|
||||
foreach var c in classes do
|
||||
begin
|
||||
var ind := labels.Indices(v -> v = c).ToArray;
|
||||
|
||||
var xs := ind.ConvertAll(i -> x[i]);
|
||||
var ys := ind.ConvertAll(i -> y[i]);
|
||||
|
||||
var clr := pal.Colors[c mod pal.Colors.Length];
|
||||
|
||||
self.Points(xs, ys, clr, size, marker, nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Cell.Heatmap(m: array[,] of real);
|
||||
begin
|
||||
Plot.RunUI(() ->
|
||||
|
|
@ -453,6 +490,16 @@ begin
|
|||
end);
|
||||
end;
|
||||
|
||||
procedure Cell.Text(s: string; x: real; y: real);
|
||||
begin
|
||||
Plot.RunUI(() ->
|
||||
begin
|
||||
EnsureChart;
|
||||
|
||||
Plot.DrawText(chart, s, x, y);
|
||||
end);
|
||||
end;
|
||||
|
||||
constructor Figure.Create(rows,cols: integer);
|
||||
begin
|
||||
grid := new GridWPF;
|
||||
|
|
@ -628,6 +675,25 @@ begin
|
|||
AddSeries(chart, g);
|
||||
end;
|
||||
|
||||
static procedure Plot.DrawText(chart: ChartWPF; s: string; x, y: real);
|
||||
begin
|
||||
var tb := new System.Windows.Controls.TextBlock;
|
||||
tb.Text := s;
|
||||
tb.FontSize := 14;
|
||||
tb.FontWeight := System.Windows.FontWeights.Bold;
|
||||
|
||||
tb.HorizontalAlignment := System.Windows.HorizontalAlignment.Center;
|
||||
tb.VerticalAlignment := System.Windows.VerticalAlignment.Center;
|
||||
|
||||
var grid := chart.Parent as System.Windows.Controls.Grid;
|
||||
if grid <> nil then
|
||||
begin
|
||||
tb.HorizontalAlignment := System.Windows.HorizontalAlignment.Center;
|
||||
tb.VerticalAlignment := System.Windows.VerticalAlignment.Center;
|
||||
grid.Children.Add(tb);
|
||||
end;
|
||||
end;
|
||||
|
||||
static procedure Plot.DrawPoints(chart: ChartWPF; x, y: array of real;
|
||||
color: ColorWPF; size: real; marker: MarkerType; legend: string);
|
||||
begin
|
||||
|
|
@ -671,29 +737,29 @@ begin
|
|||
end;
|
||||
|
||||
class procedure Plot.LineGraph(x, y: array of real;
|
||||
color: ColorWPF?; thickness: real; legend: string);
|
||||
color: ColorWPF; thickness: real; legend: string);
|
||||
begin
|
||||
RunUI(() ->
|
||||
begin
|
||||
var clr := if color.HasValue then color.Value else NextRootColor;
|
||||
var clr := if color<>DefaultColor then color else NextRootColor;
|
||||
|
||||
DrawLine(rootChart, x, y, clr, thickness, legend);
|
||||
end);
|
||||
end;
|
||||
|
||||
static procedure Plot.Points(x, y: array of real;
|
||||
color: ColorWPF?; size: real; marker: MarkerType; legend: string);
|
||||
color: ColorWPF; size: real; marker: MarkerType; legend: string);
|
||||
begin
|
||||
RunUI(() ->
|
||||
begin
|
||||
var clr := if color.HasValue then color.Value else NextRootColor;
|
||||
var clr := if color<>DefaultColor then color else NextRootColor;
|
||||
|
||||
DrawPoints(rootChart, x, y, clr, size, marker, legend);
|
||||
end);
|
||||
end;
|
||||
|
||||
static procedure Plot.Points(x, y: array of real; labels: array of integer;
|
||||
color: ColorWPF?; size: real; marker: MarkerType);
|
||||
color: ColorWPF; size: real; marker: MarkerType);
|
||||
begin
|
||||
if (x = nil) or (y = nil) or (labels = nil) then
|
||||
raise new System.ArgumentNullException;
|
||||
|
|
@ -701,16 +767,24 @@ begin
|
|||
if (x.Length <> y.Length) or (x.Length <> labels.Length) then
|
||||
raise new System.ArgumentException('Points: array sizes mismatch');
|
||||
|
||||
var k := labels.Max + 1;
|
||||
var classes := labels.Distinct.ToArray;
|
||||
&Array.Sort(classes);
|
||||
|
||||
for var c := 0 to k-1 do
|
||||
var pal := CurrentPalette;
|
||||
|
||||
foreach var c in classes do
|
||||
begin
|
||||
var ind := labels.Indices(v -> v = c).ToArray;
|
||||
|
||||
var xs := ind.ConvertAll(i -> x[i]);
|
||||
var ys := ind.ConvertAll(i -> y[i]);
|
||||
|
||||
Points(xs, ys, color, size, marker, 'cluster ' + c);
|
||||
var clr :=
|
||||
if color<>DefaultColor
|
||||
then color
|
||||
else pal.Colors[c mod pal.Colors.Length];
|
||||
|
||||
Points(xs, ys, clr, size, marker, nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue