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