ML - добавки

This commit is contained in:
Mikhalkovich Stanislav 2026-02-19 09:33:09 +03:00
parent e9b999815f
commit 31aaf0d13d
14 changed files with 930 additions and 212 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3"; public const string Major = "3";
public const string Minor = "11"; public const string Minor = "11";
public const string Build = "1"; public const string Build = "1";
public const string Revision = "3756"; public const string Revision = "3761";
public const string MainVersion = Major + "." + Minor; public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=1
%REVISION%=3756
%MINOR%=11 %MINOR%=11
%REVISION%=3761
%COREVERSION%=1
%MAJOR%=3 %MAJOR%=3

View file

@ -1 +1 @@
3.11.1.3756 3.11.1.3761

View file

@ -1 +1 @@
!define VERSION '3.11.1.3756' !define VERSION '3.11.1.3761'

View file

@ -3185,8 +3185,8 @@ namespace PascalABCCompiler.TreeConverter
if (cfn is common_method_node && (cfn as common_method_node).is_constructor) if (cfn is common_method_node && (cfn as common_method_node).is_constructor)
return StringResources.Get("CONSTRUCTOR_PREDEFINITION_WITHOUT_DEFINITION"); return StringResources.Get("CONSTRUCTOR_PREDEFINITION_WITHOUT_DEFINITION");
if (cfn.return_value_type == null) if (cfn.return_value_type == null)
return StringResources.Get("PROCEDURE_PREDEFINITION_WITHOUT_DEFINITION"); return string.Format(StringResources.Get("PROCEDURE_PREDEFINITION_{0}_WITHOUT_DEFINITION"),cfn.name);
return StringResources.Get("FUNCTION_PREDEFINITION_WITHOUT_DEFINITION"); return string.Format(StringResources.Get("FUNCTION_PREDEFINITION_{0}_WITHOUT_DEFINITION"), cfn.name);
} }
} }

View file

@ -259,7 +259,18 @@ const
'Индекс {0} вне диапазона [0..{1})!!Index {0} out of range [0..{1})'; 'Индекс {0} вне диапазона [0..{1})!!Index {0} out of range [0..{1})';
ER_INDICES_NULL = ER_INDICES_NULL =
'indices не может быть nil!!indices is nil'; 'indices не может быть nil!!indices is nil';
ER_LEFT_SCHEMA_NULL =
'Left schema не может быть nil!!Left schema cannot be nil';
ER_RIGHT_SCHEMA_NULL =
'Right schema не может быть nil!!Right schema cannot be nil';
ER_JOIN_KEYS_LENGTH_MISMATCH =
'Длины leftKeys и rightKeys не совпадают!!join keys length mismatch';
ER_UNKNOWN_COLUMN_TYPE =
'Неизвестный тип столбца!!Unknown column type';
ER_ROW_INDEX_OUT_OF_RANGE =
'Индекс строки {0} вне диапазона [0..{1})!!' +
'Row index {0} out of range [0..{1})';
//----------------------------- //-----------------------------
// Сервисные функции // Сервисные функции
//----------------------------- //-----------------------------
@ -370,7 +381,7 @@ begin
begin begin
var k := indices[i]; var k := indices[i];
if (k < 0) or (k >= ColumnCount) then if (k < 0) or (k >= ColumnCount) then
raise new System.ArgumentOutOfRangeException('indices'); ArgumentOutOfRangeError(ER_INDEX_OUT_OF_RANGE, k, ColumnCount);
names[i] := fNames[k]; names[i] := fNames[k];
types[i] := fTypes[k]; types[i] := fTypes[k];
if cats <> nil then cats[i] := fIsCategorical[k]; if cats <> nil then cats[i] := fIsCategorical[k];
@ -416,7 +427,7 @@ end;
function DataFrameSchema.WithCategorical(name: string; value: boolean): DataFrameSchema; function DataFrameSchema.WithCategorical(name: string; value: boolean): DataFrameSchema;
begin begin
if not HasColumn(name) then if not HasColumn(name) then
raise new System.ArgumentException($'Column "{name}" does not exist'); ArgumentError(ER_COLUMN_NOT_EXISTS, name);
var cats := if fIsCategorical = nil then new boolean[ColumnCount] else Copy(fIsCategorical); var cats := if fIsCategorical = nil then new boolean[ColumnCount] else Copy(fIsCategorical);
cats[IndexOf(name)] := value; cats[IndexOf(name)] := value;
@ -428,17 +439,17 @@ class function DataFrameSchema.Merge(left, right: DataFrameSchema;
leftKeys, rightKeys: array of integer; rightPrefix: string): DataFrameSchema; leftKeys, rightKeys: array of integer; rightPrefix: string): DataFrameSchema;
begin begin
if left = nil then if left = nil then
raise new System.ArgumentException('left is nil'); ArgumentNullError(ER_LEFT_SCHEMA_NULL);
if right = nil then if right = nil then
raise new System.ArgumentException('right is nil'); ArgumentNullError(ER_RIGHT_SCHEMA_NULL);
if leftKeys.Length <> rightKeys.Length then if leftKeys.Length <> rightKeys.Length then
raise new System.ArgumentException('join keys length mismatch'); ArgumentError(ER_JOIN_KEYS_LENGTH_MISMATCH);
var skip := new boolean[right.ColumnCount]; var skip := new boolean[right.ColumnCount];
foreach var i in rightKeys do foreach var i in rightKeys do
begin begin
if (i < 0) or (i >= right.ColumnCount) then if (i < 0) or (i >= right.ColumnCount) then
raise new System.ArgumentOutOfRangeException('rightKeys'); ArgumentOutOfRangeError(ER_INDEX_OUT_OF_RANGE, i, right.ColumnCount);
skip[i] := true; skip[i] := true;
end; end;
@ -770,7 +781,7 @@ begin
boolAcc[i] := pos -> c.Data[pos]; boolAcc[i] := pos -> c.Data[pos];
end; end;
else raise new Exception('Unknown column type'); else Error(ER_UNKNOWN_COLUMN_TYPE);
end; end;
end; end;
end; end;
@ -826,7 +837,7 @@ end;
procedure DataFrameCursor.MoveTo(p: integer); procedure DataFrameCursor.MoveTo(p: integer);
begin begin
if (p < 0) or (p >= rowCnt) then if (p < 0) or (p >= rowCnt) then
raise new Exception('Cursor.MoveTo: index out of range'); ArgumentOutOfRangeError(ER_ROW_INDEX_OUT_OF_RANGE, p, rowCnt);
pos := p; pos := p;
end; end;

View file

@ -240,7 +240,54 @@ function SolveRidge(A: Matrix; b: Vector; lambda: real := 0): Vector;
implementation implementation
uses System; uses MLExceptions;
const
ER_VECTOR_LENGTH_NEGATIVE =
'Длина вектора должна быть неотрицательной!!Vector length must be non-negative';
ER_VALUES_NULL =
'values не может быть nil!!values cannot be nil';
ER_VECTOR_LENGTH_MISMATCH =
'Несоответствие длины векторов: {0} и {1}!!Vector length mismatch: {0} vs {1}';
ER_VECTOR_EMPTY =
'Вектор пуст!!Vector is empty';
ER_VECTOR_DIVIDE_BY_ZERO =
'Деление на ноль при делении вектора на скаляр!!Division by zero in Vector / scalar';
ER_DIM_MISMATCH =
'Несоответствие размерностей: {0} и {1}!!Dimension mismatch: {0} and {1}';
ER_MATRIX_SIZE_NEGATIVE =
'Размеры матрицы должны быть неотрицательными!!Matrix size must be non-negative';
ER_MATRIX_SIZE_MISMATCH =
'Несоответствие размеров матриц: {0}x{1} и {2}x{3}!!' +
'Matrix size mismatch: {0}x{1} vs {2}x{3}';
ER_MATRIX_MUL_SIZE_MISMATCH =
'Несоответствие размеров при умножении матриц: {0}x{1} * {2}x{3}!!' +
'Matrix multiply size mismatch: {0}x{1} * {2}x{3}';
ER_MATRIX_VECTOR_SIZE_MISMATCH =
'Несоответствие размеров при умножении матрицы на вектор: {0}x{1} * {2}!!' +
'Matrix-vector size mismatch: {0}x{1} * {2}';
ER_ROW_INDEX_OUT_OF_RANGE =
'Индекс строки {0} вне диапазона [0..{1})!!Row index {0} out of range [0..{1})';
ER_COL_INDEX_OUT_OF_RANGE =
'Индекс столбца {0} вне диапазона [0..{1})!!Column index {0} out of range [0..{1})';
ER_MATRIX_NOT_SQUARE =
'Матрица должна быть квадратной!!Matrix must be square';
ER_MATRIX_NOT_SYMMETRIC =
'Матрица должна быть симметричной!!Matrix must be symmetric';
ER_PCA_K_INVALID =
'k должно быть >= 1!!k must be >= 1';
ER_PCA_K_TOO_LARGE =
'k не может превышать число признаков!!k cannot exceed number of features';
ER_PCA_NEED_TWO_SAMPLES =
'Требуется как минимум два объекта!!At least two samples required';
ER_CHOLESKY_NOT_SQUARE =
'Матрица должна быть квадратной для Cholesky!!Matrix must be square for Cholesky';
ER_MATRIX_NOT_SPD =
'Матрица не является положительно определённой (SPD)!!Matrix is not SPD';
ER_MATRIX_SINGULAR =
'Матрица вырождена!!Matrix is singular';
ER_VECTOR_SIZE_MISMATCH =
'Несоответствие длины вектора: {0} и {1}!!Vector size mismatch: {0} and {1}';
//----------------------------- //-----------------------------
// Vector // Vector
@ -249,21 +296,21 @@ uses System;
constructor Vector.Create(n: integer); constructor Vector.Create(n: integer);
begin begin
if n < 0 then if n < 0 then
raise new ArgumentOutOfRangeException('n', 'Vector length must be non-negative'); ArgumentOutOfRangeError(ER_VECTOR_LENGTH_NEGATIVE);
data := new real[n]; data := new real[n];
end; end;
constructor Vector.Create(values: array of real); constructor Vector.Create(values: array of real);
begin begin
if values = nil then if values = nil then
raise new ArgumentNullException('values'); ArgumentNullError(ER_VALUES_NULL);
data := Copy(values); data := Copy(values);
end; end;
constructor Vector.Create(values: array of integer); constructor Vector.Create(values: array of integer);
begin begin
if values = nil then if values = nil then
raise new ArgumentNullException('values'); ArgumentNullError(ER_VALUES_NULL);
data := values.Select(x -> real(x)).ToArray; data := values.Select(x -> real(x)).ToArray;
end; end;
@ -275,14 +322,13 @@ end;
static procedure Vector.CheckSameLength(a, b: Vector); static procedure Vector.CheckSameLength(a, b: Vector);
begin begin
if a.Length <> b.Length then if a.Length <> b.Length then
raise new ArgumentException( ArgumentError(ER_VECTOR_LENGTH_MISMATCH, a.Length, b.Length);
$'Vector length mismatch: {a.Length} vs {b.Length}');
end; end;
static procedure Vector.CheckNonEmpty(v: Vector); static procedure Vector.CheckNonEmpty(v: Vector);
begin begin
if v.Length = 0 then if v.Length = 0 then
raise new ArgumentException('Vector is empty'); ArgumentError(ER_VECTOR_EMPTY);
end; end;
static function Vector.operator +(a, b: Vector): Vector; static function Vector.operator +(a, b: Vector): Vector;
@ -316,7 +362,7 @@ end;
static function Vector.operator /(v: Vector; alpha: real): Vector; static function Vector.operator /(v: Vector; alpha: real): Vector;
begin begin
if alpha = 0.0 then if alpha = 0.0 then
raise new DivideByZeroException('Division by zero in Vector / scalar'); raise new System.DivideByZeroException(GetTranslation(ER_VECTOR_DIVIDE_BY_ZERO));
Result := new Vector(v.Length); Result := new Vector(v.Length);
var inv := 1.0 / alpha; var inv := 1.0 / alpha;
for var i := 0 to v.Length - 1 do for var i := 0 to v.Length - 1 do
@ -388,7 +434,7 @@ function Vector.Min: real := data.Min;
function Vector.Dot(b: Vector): real; function Vector.Dot(b: Vector): real;
begin begin
if Length <> b.Length then if Length <> b.Length then
raise new Exception('Dimension mismatch in Dot'); DimensionError(ER_DIM_MISMATCH, Length, b.Length);
var s := 0.0; var s := 0.0;
for var i := 0 to Length - 1 do for var i := 0 to Length - 1 do
@ -410,14 +456,14 @@ end;
constructor Matrix.Create(r, c: integer); constructor Matrix.Create(r, c: integer);
begin begin
if (r < 0) or (c < 0) then if (r < 0) or (c < 0) then
raise new ArgumentOutOfRangeException('Matrix size must be non-negative'); ArgumentOutOfRangeError(ER_MATRIX_SIZE_NEGATIVE);
data := new real[r, c]; data := new real[r, c];
end; end;
constructor Matrix.Create(values: array[,] of real); constructor Matrix.Create(values: array[,] of real);
begin begin
if values = nil then if values = nil then
raise new ArgumentNullException('values'); ArgumentNullError(ER_VALUES_NULL);
data := Copy(values); data := Copy(values);
end; end;
@ -746,22 +792,19 @@ end;
static procedure Matrix.CheckSameSize(A, B: Matrix); static procedure Matrix.CheckSameSize(A, B: Matrix);
begin begin
if (A.Rows <> B.Rows) or (A.Cols <> B.Cols) then if (A.Rows <> B.Rows) or (A.Cols <> B.Cols) then
raise new ArgumentException( DimensionError(ER_MATRIX_SIZE_MISMATCH, A.Rows, A.Cols, B.Rows, B.Cols);
$'Matrix size mismatch: {A.Rows}x{A.Cols} vs {B.Rows}x{B.Cols}');
end; end;
static procedure Matrix.CheckMulSize(A, B: Matrix); static procedure Matrix.CheckMulSize(A, B: Matrix);
begin begin
if A.Cols <> B.Rows then if A.Cols <> B.Rows then
raise new ArgumentException( DimensionError(ER_MATRIX_MUL_SIZE_MISMATCH, A.Rows, A.Cols, B.Rows, B.Cols);
$'Matrix multiply size mismatch: {A.Rows}x{A.Cols} * {B.Rows}x{B.Cols}');
end; end;
static procedure Matrix.CheckVecSize(A: Matrix; x: Vector); static procedure Matrix.CheckVecSize(A: Matrix; x: Vector);
begin begin
if A.Cols <> x.Length then if A.Cols <> x.Length then
raise new ArgumentException( DimensionError(ER_MATRIX_VECTOR_SIZE_MISMATCH, A.Rows, A.Cols, x.Length);
$'Matrix-vector size mismatch: {A.Rows}x{A.Cols} * {x.Length}');
end; end;
@ -873,7 +916,7 @@ end;
function Matrix.GetRow(i: integer): Vector; function Matrix.GetRow(i: integer): Vector;
begin begin
if (i < 0) or (i >= Rows) then if (i < 0) or (i >= Rows) then
raise new ArgumentOutOfRangeException('i'); ArgumentOutOfRangeError(ER_ROW_INDEX_OUT_OF_RANGE, i, Rows);
Result := new Vector(Cols); Result := new Vector(Cols);
for var j := 0 to Cols - 1 do for var j := 0 to Cols - 1 do
Result[j] := data[i, j]; Result[j] := data[i, j];
@ -882,7 +925,7 @@ end;
function Matrix.GetCol(j: integer): Vector; function Matrix.GetCol(j: integer): Vector;
begin begin
if (j < 0) or (j >= Cols) then if (j < 0) or (j >= Cols) then
raise new ArgumentOutOfRangeException('j'); ArgumentOutOfRangeError(ER_COL_INDEX_OUT_OF_RANGE, j, Cols);
Result := new Vector(Rows); Result := new Vector(Rows);
for var i := 0 to Rows - 1 do for var i := 0 to Rows - 1 do
Result[i] := data[i, j]; Result[i] := data[i, j];
@ -891,7 +934,7 @@ end;
static function Matrix.Identity(n: integer): Matrix; static function Matrix.Identity(n: integer): Matrix;
begin begin
if n < 0 then if n < 0 then
raise new ArgumentOutOfRangeException('n', 'Matrix size must be non-negative'); ArgumentOutOfRangeError(ER_MATRIX_SIZE_NEGATIVE);
Result := new Matrix(n, n); Result := new Matrix(n, n);
for var i := 0 to n - 1 do for var i := 0 to n - 1 do
@ -931,10 +974,10 @@ end;
function Matrix.EigenSymmetric(tol: real; maxIter: integer): (Vector, Matrix); function Matrix.EigenSymmetric(tol: real; maxIter: integer): (Vector, Matrix);
begin begin
if Rows <> Cols then if Rows <> Cols then
raise new ArgumentException('Matrix must be square'); ArgumentError(ER_MATRIX_NOT_SQUARE);
if not IsSymmetric(tol) then if not IsSymmetric(tol) then
raise new ArgumentException('Matrix must be symmetric'); ArgumentError(ER_MATRIX_NOT_SYMMETRIC);
var n := Rows; var n := Rows;
@ -1075,13 +1118,13 @@ begin
var n := Cols; var n := Cols;
if k < 1 then if k < 1 then
raise new ArgumentException('k must be >= 1'); ArgumentError(ER_PCA_K_INVALID);
if k > n then if k > n then
raise new ArgumentException('k cannot exceed number of features'); ArgumentError(ER_PCA_K_TOO_LARGE);
if m < 2 then if m < 2 then
raise new ArgumentException('At least two samples required'); ArgumentError(ER_PCA_NEED_TWO_SAMPLES);
// --- Центрирование // --- Центрирование
var Xc := Clone; var Xc := Clone;
@ -1136,7 +1179,7 @@ end;
function Cholesky(A: Matrix): Matrix; function Cholesky(A: Matrix): Matrix;
begin begin
if A.Rows <> A.Cols then if A.Rows <> A.Cols then
raise new ArgumentException('Matrix must be square for Cholesky'); ArgumentError(ER_CHOLESKY_NOT_SQUARE);
var n := A.Rows; var n := A.Rows;
var L := new Matrix(n, n); var L := new Matrix(n, n);
@ -1151,7 +1194,7 @@ begin
if i = j then if i = j then
begin begin
if s <= 0.0 then if s <= 0.0 then
raise new InvalidOperationException('Matrix is not SPD'); Error(ER_MATRIX_NOT_SPD);
L[i, i] := Sqrt(s); L[i, i] := Sqrt(s);
end end
else else
@ -1165,7 +1208,7 @@ end;
function LUDecompose(A: Matrix): (Matrix, array of integer); function LUDecompose(A: Matrix): (Matrix, array of integer);
begin begin
if A.Rows <> A.Cols then if A.Rows <> A.Cols then
raise new ArgumentException('Matrix must be square for LU'); ArgumentError(ER_MATRIX_NOT_SQUARE);
var n := A.Rows; var n := A.Rows;
var LU := A.Clone; var LU := A.Clone;
@ -1187,7 +1230,7 @@ begin
end; end;
if maxVal = 0.0 then if maxVal = 0.0 then
raise new InvalidOperationException('Matrix is singular'); Error(ER_MATRIX_SINGULAR);
if maxRow <> k then if maxRow <> k then
begin begin
@ -1280,10 +1323,10 @@ end;
function Solve(A: Matrix; b: Vector): Vector; function Solve(A: Matrix; b: Vector): Vector;
begin begin
if A.Rows <> A.Cols then if A.Rows <> A.Cols then
raise new ArgumentException('Matrix A must be square'); ArgumentError(ER_MATRIX_NOT_SQUARE);
if b.Length <> A.Rows then if b.Length <> A.Rows then
raise new ArgumentException('Vector size mismatch in Solve'); DimensionError(ER_VECTOR_SIZE_MISMATCH, b.Length, A.Rows);
var (LU, p) := LUDecompose(A); var (LU, p) := LUDecompose(A);
var pb := Permute(b, p); var pb := Permute(b, p);
@ -1294,10 +1337,10 @@ end;
function SolveSPD(A: Matrix; b: Vector): Vector; function SolveSPD(A: Matrix; b: Vector): Vector;
begin begin
if A.Rows <> A.Cols then if A.Rows <> A.Cols then
raise new ArgumentException('Matrix A must be square'); ArgumentError(ER_MATRIX_NOT_SQUARE);
if b.Length <> A.Rows then if b.Length <> A.Rows then
raise new ArgumentException('Vector size mismatch in SolveSPD'); DimensionError(ER_VECTOR_SIZE_MISMATCH, b.Length, A.Rows);
var L := Cholesky(A); var L := Cholesky(A);
var y := SolveLowerTriangular(L, b); var y := SolveLowerTriangular(L, b);
@ -1316,13 +1359,13 @@ end;
function SolveRidge(A: Matrix; b: Vector; lambda: real): Vector; function SolveRidge(A: Matrix; b: Vector; lambda: real): Vector;
begin begin
if lambda < 0.0 then if lambda < 0.0 then
raise new ArgumentException('lambda must be >= 0'); ArgumentError(ER_LAMBDA_NEGATIVE);
var m := A.Rows; var m := A.Rows;
var n := A.Cols; var n := A.Cols;
if b.Length <> m then if b.Length <> m then
raise new ArgumentException('Vector length mismatch in SolveRidge'); DimensionError(ER_VECTOR_SIZE_MISMATCH, b.Length, m);
// ------------------------------------------------------------ // ------------------------------------------------------------
// 1. Compute AtA = A^T * A // 1. Compute AtA = A^T * A

View file

@ -41,10 +41,10 @@ type
LogisticRegression = MLModelsABC.LogisticRegression; LogisticRegression = MLModelsABC.LogisticRegression;
RidgeRegression = MLModelsABC.RidgeRegression; RidgeRegression = MLModelsABC.RidgeRegression;
ElasticNet = MLModelsABC.ElasticNet; ElasticNet = MLModelsABC.ElasticNet;
MulticlassLogisticRegression = MLModelsABC.MulticlassLogisticRegression; DecisionTreeClassifier = MLModelsABC.DecisionTreeClassifier;
DecisionTreeRegressor = MLModelsABC.DecisionTreeRegressor;
MLException = MLExceptions.MLException; MLException = MLExceptions.MLException;
MLArgumentException = MLExceptions.MLArgumentException;
MLNotFittedException = MLExceptions.MLNotFittedException; MLNotFittedException = MLExceptions.MLNotFittedException;
MLDimensionException = MLExceptions.MLDimensionException; MLDimensionException = MLExceptions.MLDimensionException;

View file

@ -32,7 +32,7 @@ type
/// вместо только итогового решения. /// вместо только итогового решения.
IProbabilisticClassifier = interface(IClassifier) IProbabilisticClassifier = interface(IClassifier)
/// Возвращает вероятность принадлежности к положительному классу для каждого объекта. /// Возвращает вероятность принадлежности к положительному классу для каждого объекта.
function PredictProba(X: Matrix): Vector; function PredictProba(X: Matrix): Matrix;
end; end;
/// Интерфейс регрессионной модели. /// Интерфейс регрессионной модели.

File diff suppressed because it is too large Load diff

View file

@ -180,6 +180,61 @@ const
'StandardScaler: столбцы не указаны!!StandardScaler: columns not specified'; 'StandardScaler: столбцы не указаны!!StandardScaler: columns not specified';
ER_SCALER_COLUMN_NOT_NUMERIC = ER_SCALER_COLUMN_NOT_NUMERIC =
'StandardScaler: столбец "{0}" не является числовым!!StandardScaler: column "{0}" is not numeric'; 'StandardScaler: столбец "{0}" не является числовым!!StandardScaler: column "{0}" is not numeric';
ER_SCALER_NO_VALID_VALUES =
'StandardScaler: столбец "{0}" не содержит допустимых значений!!' +
'StandardScaler: column "{0}" has no valid values';
ER_SCALER_ZERO_VARIANCE =
'StandardScaler: нулевая дисперсия в столбце "{0}"!!' +
'StandardScaler: zero variance in column "{0}"';
ER_MINMAX_NO_COLUMNS =
'MinMaxScaler: столбцы не указаны!!MinMaxScaler: columns not specified';
ER_MINMAX_COLUMN_NOT_NUMERIC =
'MinMaxScaler: столбец "{0}" не является числовым!!MinMaxScaler: column "{0}" is not numeric';
ER_MINMAX_NO_VALID_VALUES =
'MinMaxScaler: столбец "{0}" не содержит допустимых значений!!' +
'MinMaxScaler: column "{0}" has no valid values';
ER_MINMAX_CONSTANT_COLUMN =
'MinMaxScaler: постоянный столбец "{0}"!!MinMaxScaler: constant column "{0}"';
ER_LABELENCODER_NO_COLUMN =
'LabelEncoder: столбец не указан!!LabelEncoder: column not specified';
ER_LABELENCODER_NOT_STRING =
'LabelEncoder: столбец "{0}" не является строковым!!' +
'LabelEncoder: column "{0}" is not string';
ER_LABELENCODER_NA =
'LabelEncoder: NA значение не допускается!!LabelEncoder: NA value not allowed';
ER_LABELENCODER_UNSEEN_CATEGORY =
'LabelEncoder: неизвестная категория "{0}"!!' +
'LabelEncoder: unseen category "{0}"';
ER_ONEHOT_NO_COLUMN =
'OneHotEncoder: столбец не указан!!OneHotEncoder: column not specified';
ER_ONEHOT_NOT_STRING =
'OneHotEncoder: столбец "{0}" не является строковым или не содержит допустимых значений!!' +
'OneHotEncoder: column "{0}" is not string or has no valid values';
ER_ONEHOT_UNSEEN_CATEGORY =
'OneHotEncoder: неизвестная категория "{0}"!!' +
'OneHotEncoder: unseen category "{0}"';
ER_IMPUTER_INVALID_STRATEGY_MEAN =
'Imputer: данный конструктор предназначен для стратегии isMean!!' +
'Imputer: this constructor is for isMean';
ER_IMPUTER_INVALID_STRATEGY_CONSTANT =
'Imputer: данный конструктор предназначен для стратегии isConstant!!' +
'Imputer: this constructor is for isConstant';
ER_IMPUTER_NO_COLUMNS =
'Imputer: столбцы не указаны!!Imputer: columns not specified';
ER_IMPUTER_COLUMN_NOT_NUMERIC =
'Imputer: столбец "{0}" не является числовым!!' +
'Imputer: column "{0}" is not numeric';
ER_IMPUTER_NO_VALID_VALUES =
'Imputer(mean): столбец "{0}" не содержит допустимых значений!!' +
'Imputer(mean): column "{0}" has no valid values';
ER_IMPUTER_CONSTANT_VALUE_NULL =
'Imputer(constant): значение nil для столбца "{0}"!!' +
'Imputer(constant): value is nil for column "{0}"';
ER_IMPUTER_CONSTANT_TYPE_MISMATCH =
'Imputer(constant): несоответствие типа значения для столбца "{0}"!!' +
'Imputer(constant): value type mismatch for column "{0}"';
ER_PIPELINE_MODIFY_AFTER_FIT =
'Нельзя добавлять шаг после вызова Fit()!!Cannot add step after Fit';
//----------------------------- //-----------------------------
// StandardScaler // StandardScaler
@ -224,14 +279,14 @@ begin
end; end;
if cnt = 0 then if cnt = 0 then
raise new Exception($'StandardScaler: column "{colName}" has no valid values'); Error(ER_SCALER_NO_VALID_VALUES, colName);
means[i] := sum / cnt; means[i] := sum / cnt;
var v := sum2 / cnt - means[i] * means[i]; var v := sum2 / cnt - means[i] * means[i];
stds[i] := Sqrt(v); stds[i] := Sqrt(v);
if stds[i] = 0 then if stds[i] = 0 then
raise new Exception($'StandardScaler: zero variance in column "{colName}"'); Error(ER_SCALER_ZERO_VARIANCE, colName);
end; end;
fitted := true; fitted := true;
@ -241,7 +296,7 @@ end;
function DataStandardScaler.Transform(df: DataFrame): DataFrame; function DataStandardScaler.Transform(df: DataFrame): DataFrame;
begin begin
if not fitted then if not fitted then
raise new Exception('StandardScaler: not fitted'); NotFittedError(ER_FIT_NOT_CALLED);
var res := df; var res := df;
@ -277,7 +332,7 @@ end;
constructor DataMinMaxScaler.Create(params columns: array of string); constructor DataMinMaxScaler.Create(params columns: array of string);
begin begin
if (columns = nil) or (columns.Length = 0) then if (columns = nil) or (columns.Length = 0) then
raise new ArgumentException('MinMaxScaler: columns not specified'); ArgumentError(ER_MINMAX_NO_COLUMNS);
cols := columns; cols := columns;
fitted := false; fitted := false;
@ -296,7 +351,7 @@ begin
var ct := df.Schema.ColumnTypeAt(idx); var ct := df.Schema.ColumnTypeAt(idx);
if not (ct in [ColumnType.ctInt, ColumnType.ctFloat]) then if not (ct in [ColumnType.ctInt, ColumnType.ctFloat]) then
raise new Exception($'MinMaxScaler: column "{colName}" is not numeric'); Error(ER_MINMAX_COLUMN_NOT_NUMERIC, colName);
var first := true; var first := true;
var minv, maxv: real; var minv, maxv: real;
@ -321,10 +376,10 @@ begin
end; end;
if first then if first then
raise new Exception($'MinMaxScaler: column "{colName}" has no valid values'); Error(ER_MINMAX_NO_VALID_VALUES, colName);
if minv = maxv then if minv = maxv then
raise new Exception($'MinMaxScaler: constant column "{colName}"'); Error(ER_MINMAX_CONSTANT_COLUMN, colName);
mins[i] := minv; mins[i] := minv;
maxs[i] := maxv; maxs[i] := maxv;
@ -337,7 +392,7 @@ end;
function DataMinMaxScaler.Transform(df: DataFrame): DataFrame; function DataMinMaxScaler.Transform(df: DataFrame): DataFrame;
begin begin
if not fitted then if not fitted then
raise new Exception('MinMaxScaler: not fitted'); NotFittedError(ER_FIT_NOT_CALLED);
var res := df; var res := df;
@ -374,7 +429,7 @@ end;
constructor LabelEncoder.Create(column: string); constructor LabelEncoder.Create(column: string);
begin begin
if column = '' then if column = '' then
raise new ArgumentException('LabelEncoder: column not specified'); ArgumentError(ER_LABELENCODER_NO_COLUMN);
col := column; col := column;
fitted := false; fitted := false;
@ -385,7 +440,7 @@ begin
var idx := df.Schema.IndexOf(col); var idx := df.Schema.IndexOf(col);
if df.Schema.ColumnTypeAt(idx) <> ColumnType.ctStr then if df.Schema.ColumnTypeAt(idx) <> ColumnType.ctStr then
raise new Exception($'LabelEncoder: column "{col}" is not string'); Error(ER_LABELENCODER_NOT_STRING, col);
mapping := new Dictionary<string, integer>; mapping := new Dictionary<string, integer>;
@ -411,7 +466,7 @@ end;
function LabelEncoder.Transform(df: DataFrame): DataFrame; function LabelEncoder.Transform(df: DataFrame): DataFrame;
begin begin
if not fitted then if not fitted then
raise new Exception('LabelEncoder: not fitted'); NotFittedError(ER_FIT_NOT_CALLED);
var idx := df.Schema.IndexOf(col); var idx := df.Schema.IndexOf(col);
@ -419,14 +474,12 @@ begin
col, col,
c -> c ->
if not c.IsValid(idx) then if not c.IsValid(idx) then
raise new Exception('NA') // будет поймано как NA Error(ER_LABELENCODER_NA) // будет поймано как NA
else else
begin begin
var s := c.Str(idx); var s := c.Str(idx);
if not mapping.ContainsKey(s) then if not mapping.ContainsKey(s) then
raise new Exception( Error(ER_LABELENCODER_UNSEEN_CATEGORY, s);
$'LabelEncoder: unseen category "{s}"'
);
Result := mapping[s]; Result := mapping[s];
end end
); );
@ -445,7 +498,7 @@ end;
constructor OneHotEncoder.Create(column: string); constructor OneHotEncoder.Create(column: string);
begin begin
if column = '' then if column = '' then
raise new ArgumentException('OneHotEncoder: column not specified'); ArgumentError(ER_ONEHOT_NO_COLUMN);
col := column; col := column;
fitted := false; fitted := false;
end; end;
@ -454,9 +507,7 @@ function OneHotEncoder.Fit(df: DataFrame): IPreprocessor;
begin begin
var idx := df.Schema.IndexOf(col); var idx := df.Schema.IndexOf(col);
if df.Schema.ColumnTypeAt(idx) <> ColumnType.ctStr then if df.Schema.ColumnTypeAt(idx) <> ColumnType.ctStr then
raise new Exception( Error(ER_ONEHOT_NOT_STRING, col);
$'OneHotEncoder: column "{col}" is not string or has no valid values'
);
indexByValue := new Dictionary<string, integer>; indexByValue := new Dictionary<string, integer>;
var values := new List<string>; var values := new List<string>;
@ -481,7 +532,7 @@ end;
function OneHotEncoder.Transform(df: DataFrame): DataFrame; function OneHotEncoder.Transform(df: DataFrame): DataFrame;
begin begin
if not fitted then if not fitted then
raise new Exception('OneHotEncoder: not fitted'); NotFittedError(ER_FIT_NOT_CALLED);
var srcIdx := df.Schema.IndexOf(col); var srcIdx := df.Schema.IndexOf(col);
var catCount := categories.Length; var catCount := categories.Length;
@ -494,7 +545,7 @@ begin
var s := cur.Str(srcIdx); var s := cur.Str(srcIdx);
if not indexByValue.ContainsKey(s) then if not indexByValue.ContainsKey(s) then
raise new Exception($'OneHotEncoder: unseen category "{s}"'); Error(ER_ONEHOT_UNSEEN_CATEGORY, s);
end; end;
// === ШАГ 2. Генерация one-hot столбцов === // === ШАГ 2. Генерация one-hot столбцов ===
@ -543,10 +594,10 @@ end;
constructor Imputer.Create(strategy: ImputeStrategy; params columns: array of string); constructor Imputer.Create(strategy: ImputeStrategy; params columns: array of string);
begin begin
if strategy <> isMean then if strategy <> isMean then
raise new ArgumentException('Imputer: this constructor is for isMean'); ArgumentError(ER_IMPUTER_INVALID_STRATEGY_MEAN);
if (columns = nil) or (columns.Length = 0) then if (columns = nil) or (columns.Length = 0) then
raise new ArgumentException('Imputer: columns not specified'); ArgumentError(ER_IMPUTER_NO_COLUMNS);
self.strategy := strategy; self.strategy := strategy;
self.cols := columns; self.cols := columns;
@ -557,10 +608,10 @@ end;
constructor Imputer.Create(strategy: ImputeStrategy; value: object; params columns: array of string); constructor Imputer.Create(strategy: ImputeStrategy; value: object; params columns: array of string);
begin begin
if strategy <> isConstant then if strategy <> isConstant then
raise new ArgumentException('Imputer: this constructor is for isConstant'); ArgumentError(ER_IMPUTER_INVALID_STRATEGY_CONSTANT);
if (columns = nil) or (columns.Length = 0) then if (columns = nil) or (columns.Length = 0) then
raise new ArgumentException('Imputer: columns not specified'); ArgumentError(ER_IMPUTER_NO_COLUMNS);
self.strategy := strategy; self.strategy := strategy;
self.cols := columns; self.cols := columns;
@ -586,7 +637,7 @@ begin
var ct := df.Schema.ColumnTypeAt(idx); var ct := df.Schema.ColumnTypeAt(idx);
if not (ct in [ColumnType.ctInt, ColumnType.ctFloat]) then if not (ct in [ColumnType.ctInt, ColumnType.ctFloat]) then
raise new Exception($'Imputer(mean): column "{name}" is not numeric'); Error(ER_IMPUTER_COLUMN_NOT_NUMERIC, name);
var sum := 0.0; var sum := 0.0;
var cnt := 0; var cnt := 0;
@ -600,7 +651,7 @@ begin
end; end;
if cnt = 0 then if cnt = 0 then
raise new Exception($'Imputer(mean): column "{name}" has no valid values'); Error(ER_IMPUTER_NO_VALID_VALUES, name);
means[i] := sum / cnt; means[i] := sum / cnt;
end; end;
@ -613,7 +664,7 @@ end;
function Imputer.Transform(df: DataFrame): DataFrame; function Imputer.Transform(df: DataFrame): DataFrame;
begin begin
if not fitted then if not fitted then
raise new Exception('Imputer: not fitted'); NotFittedError(ER_FIT_NOT_CALLED);
var res := df; var res := df;
@ -624,7 +675,7 @@ begin
var ct := df.Schema.ColumnTypeAt(idx); var ct := df.Schema.ColumnTypeAt(idx);
if not (ct in [ColumnType.ctInt, ColumnType.ctFloat]) then if not (ct in [ColumnType.ctInt, ColumnType.ctFloat]) then
raise new Exception($'Imputer: column "{name}" is not numeric'); Error(ER_IMPUTER_COLUMN_NOT_NUMERIC, name);
if strategy = isMean then if strategy = isMean then
begin begin
@ -638,7 +689,7 @@ begin
begin begin
var v := constants[i]; var v := constants[i];
if v = nil then if v = nil then
raise new Exception($'Imputer(constant): value is nil for column "{name}"'); Error(ER_IMPUTER_CONSTANT_VALUE_NULL, name);
if ct = ColumnType.ctInt then if ct = ColumnType.ctInt then
begin begin
@ -647,7 +698,7 @@ begin
k := integer(v); k := integer(v);
except except
on e: Exception do on e: Exception do
raise new Exception($'Imputer(constant): value type mismatch for column "{name}"'); Error(ER_IMPUTER_CONSTANT_TYPE_MISMATCH, name);
end; end;
res := res.ReplaceColumnInt( res := res.ReplaceColumnInt(
@ -662,7 +713,7 @@ begin
r := real(v); r := real(v);
except except
on e: Exception do on e: Exception do
raise new Exception($'Imputer(constant): value type mismatch for column "{name}"'); Error(ER_IMPUTER_CONSTANT_TYPE_MISMATCH, name);
end; end;
res := res.ReplaceColumnFloat( res := res.ReplaceColumnFloat(
@ -695,7 +746,7 @@ end;
function DataPipeline.Add(p: IPreprocessor): DataPipeline; function DataPipeline.Add(p: IPreprocessor): DataPipeline;
begin begin
if fitted then if fitted then
raise new Exception('Cannot add step after Fit'); Error(ER_PIPELINE_MODIFY_AFTER_FIT);
steps.Add(p); steps.Add(p);
Result := Self; Result := Self;
@ -718,7 +769,7 @@ end;
function DataPipeline.Transform(df: DataFrame): DataFrame; function DataPipeline.Transform(df: DataFrame): DataFrame;
begin begin
if not fitted then if not fitted then
NotFittedError(ER_FIT_NOT_CALLED);NotFittedError(ER_FIT_NOT_CALLED); NotFittedError(ER_FIT_NOT_CALLED);
var current := df; var current := df;
foreach var step in steps do foreach var step in steps do

View file

@ -70,8 +70,8 @@ FUNCTION_WITHOUT_BODY_MUST_HAVE_FORWARD_ATTRIBUTE=Function without body must hav
DIFFERENT_PARAMETER_NAME_IN_FUNCTION_DEFINITION_{0}_AND_PREDEFINITION_{1}=Function predefinition and definition have different parameter name: '{0}' and '{1}' DIFFERENT_PARAMETER_NAME_IN_FUNCTION_DEFINITION_{0}_AND_PREDEFINITION_{1}=Function predefinition and definition have different parameter name: '{0}' and '{1}'
FUNCTION_DEFINITION_HAVE_DIFFERENT_PARAMS_WITH_PREDEFINITION=Function definition and predefinition have different parameters FUNCTION_DEFINITION_HAVE_DIFFERENT_PARAMS_WITH_PREDEFINITION=Function definition and predefinition have different parameters
FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES=Function predefinition and definition have different return type FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES=Function predefinition and definition have different return type
FUNCTION_PREDEFINITION_WITHOUT_DEFINITION=Function has no realization FUNCTION_PREDEFINITION_{0}_WITHOUT_DEFINITION=Function {0} has no implementation
PROCEDURE_PREDEFINITION_WITHOUT_DEFINITION=Procedure has no realization PROCEDURE_PREDEFINITION_{0}_WITHOUT_DEFINITION=Procedure {0} has no implementation
CONSTRUCTOR_PREDEFINITION_WITHOUT_DEFINITION=Constructor has no realization CONSTRUCTOR_PREDEFINITION_WITHOUT_DEFINITION=Constructor has no realization
DIVISION_BY_ZERO_CONSTANT=Division by zero DIVISION_BY_ZERO_CONSTANT=Division by zero
TYPE_NAME_EXPECTED=A name of type expected TYPE_NAME_EXPECTED=A name of type expected

View file

@ -70,8 +70,8 @@ FUNCTION_WITHOUT_BODY_MUST_HAVE_FORWARD_ATTRIBUTE=Подпрограмма бе
DIFFERENT_PARAMETER_NAME_IN_FUNCTION_DEFINITION_{0}_AND_PREDEFINITION_{1}=Различные имена параметров в описании подпрограммы {0} и ее предописании {1} DIFFERENT_PARAMETER_NAME_IN_FUNCTION_DEFINITION_{0}_AND_PREDEFINITION_{1}=Различные имена параметров в описании подпрограммы {0} и ее предописании {1}
FUNCTION_DEFINITION_HAVE_DIFFERENT_PARAMS_WITH_PREDEFINITION=Параметры в описании подпрограммы отличаются от параметров в ее предописании FUNCTION_DEFINITION_HAVE_DIFFERENT_PARAMS_WITH_PREDEFINITION=Параметры в описании подпрограммы отличаются от параметров в ее предописании
FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES=Описание и предописание функции имеют разные типы возвращаемого значения FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES=Описание и предописание функции имеют разные типы возвращаемого значения
FUNCTION_PREDEFINITION_WITHOUT_DEFINITION=Предописание функции без описания FUNCTION_PREDEFINITION_{0}_WITHOUT_DEFINITION=Предописание функции {0} без описания
PROCEDURE_PREDEFINITION_WITHOUT_DEFINITION=Предописание процедуры без описания PROCEDURE_PREDEFINITION_{0}_WITHOUT_DEFINITION=Предописание процедуры {0} без описания
CONSTRUCTOR_PREDEFINITION_WITHOUT_DEFINITION=Предописание конструктора без описания CONSTRUCTOR_PREDEFINITION_WITHOUT_DEFINITION=Предописание конструктора без описания
DIVISION_BY_ZERO_CONSTANT=Деление на константу 0 DIVISION_BY_ZERO_CONSTANT=Деление на константу 0
TYPE_NAME_EXPECTED=Ожидалось имя типа TYPE_NAME_EXPECTED=Ожидалось имя типа

View file

@ -62,7 +62,7 @@ FUNCTION_WITHOUT_BODY_MUST_HAVE_FORWARD_ATTRIBUTE=Підпрограма без
DIFFERENT_PARAMETER_NAME_IN_FUNCTION_DEFINITION_{0}_AND_PREDEFINITION_{1}=Різні імена параметрів в опису підпрограми {0} і її передопису {1} DIFFERENT_PARAMETER_NAME_IN_FUNCTION_DEFINITION_{0}_AND_PREDEFINITION_{1}=Різні імена параметрів в опису підпрограми {0} і її передопису {1}
FUNCTION_DEFINITION_HAVE_DIFFERENT_PARAMS_WITH_PREDEFINITION=Параметри в опису підпрограми відрізняються від параметрів в її передопису FUNCTION_DEFINITION_HAVE_DIFFERENT_PARAMS_WITH_PREDEFINITION=Параметри в опису підпрограми відрізняються від параметрів в її передопису
FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES=Опис і предопис функції мають різні типи значення повертання FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES=Опис і предопис функції мають різні типи значення повертання
FUNCTION_PREDEFINITION_WITHOUT_DEFINITION=Предопис функції без опису FUNCTION_PREDEFINITION_{0}_WITHOUT_DEFINITION=Предопис функції {0} без опису
DIVISION_BY_ZERO_CONSTANT=Ділення на константу 0 DIVISION_BY_ZERO_CONSTANT=Ділення на константу 0
TYPE_NAME_EXPECTED=Очікувалося ім'я типу TYPE_NAME_EXPECTED=Очікувалося ім'я типу
ONLY_COMMON_TYPE_METHOD_DEFINITION_ALLOWED=Неприпустимим є визначення методу класу, які не описаного в програмі ONLY_COMMON_TYPE_METHOD_DEFINITION_ALLOWED=Неприпустимим є визначення методу класу, які не описаного в програмі