2026-03-11 10:50:15 +03:00
|
|
|
|
unit DataAdapters;
|
|
|
|
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
2026-07-01 20:40:56 +03:00
|
|
|
|
type
|
|
|
|
|
|
/// Результат кодирования целевого столбца:
|
|
|
|
|
|
/// целочисленные метки и соответствующие имена классов.
|
|
|
|
|
|
EncodedTarget = record
|
|
|
|
|
|
Labels: array of integer;
|
|
|
|
|
|
ClassNames: array of string;
|
|
|
|
|
|
|
|
|
|
|
|
/// Возвращает код класса для строки с индексом rowIndex.
|
|
|
|
|
|
function ClassIndex(rowIndex: integer): integer;
|
|
|
|
|
|
|
|
|
|
|
|
/// Возвращает имя класса для строки с индексом rowIndex.
|
|
|
|
|
|
function ClassName(rowIndex: integer): string;
|
|
|
|
|
|
end;
|
2026-03-11 10:50:15 +03:00
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
2026-04-11 20:35:52 +03:00
|
|
|
|
uses MLUtilsABC;
|
|
|
|
|
|
uses DataFrameABC;
|
2026-03-11 10:50:15 +03:00
|
|
|
|
uses MLExceptions;
|
2026-04-11 20:35:52 +03:00
|
|
|
|
uses LinearAlgebraML;
|
2026-03-11 10:50:15 +03:00
|
|
|
|
|
|
|
|
|
|
const
|
|
|
|
|
|
ER_TO_MATRIX_NO_COLUMNS =
|
|
|
|
|
|
'ToMatrix: не указаны столбцы!!ToMatrix: no columns specified';
|
|
|
|
|
|
ER_TO_MATRIX_NON_NUMERIC =
|
|
|
|
|
|
'Столбец "{0}" содержит нечисловые или NA значения!!Column "{0}" contains non-numeric or NA values';
|
2026-03-19 00:02:32 +03:00
|
|
|
|
ER_ENCODELABELS_COLUMN_NOT_STRING =
|
|
|
|
|
|
'Столбец {0} должен быть строковым для EncodeLabels!!Column {0} must be string for EncodeLabels';
|
2026-03-31 12:38:47 +03:00
|
|
|
|
ER_ENCODELABELS_NOT_CATEGORICAL =
|
|
|
|
|
|
'Столбец "{0}" должен быть категориальным для EncodeLabels!!Column "{0}" must be categorical for EncodeLabels';
|
|
|
|
|
|
ER_ENCODELABELS_UNSUPPORTED_TYPE =
|
|
|
|
|
|
'Неподдерживаемый тип столбца "{0}" для EncodeLabels!!Unsupported column type "{0}" for EncodeLabels';
|
2026-04-22 14:08:27 +03:00
|
|
|
|
ER_TARGET_HAS_NA =
|
2026-07-01 20:40:56 +03:00
|
|
|
|
'Целевой столбец "{0}" содержит NA!!Target column "{0}" contains NA values';
|
|
|
|
|
|
ER_ENCODED_TARGET_ROW_INDEX_OUT_OF_RANGE =
|
|
|
|
|
|
'Индекс строки {0} вне диапазона [0, {1})!!Row index {0} is out of range [0, {1})';
|
|
|
|
|
|
ER_ENCODED_TARGET_CLASS_INDEX_OUT_OF_RANGE =
|
|
|
|
|
|
'Индекс класса {0} вне диапазона [0, {1})!!Class index {0} is out of range [0, {1})';
|
|
|
|
|
|
|
|
|
|
|
|
function EncodedTarget.ClassIndex(rowIndex: integer): integer;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if (rowIndex < 0) or (rowIndex >= Labels.Length) then
|
|
|
|
|
|
ArgumentOutOfRangeError(ER_ENCODED_TARGET_ROW_INDEX_OUT_OF_RANGE, rowIndex, Labels.Length);
|
|
|
|
|
|
|
|
|
|
|
|
Result := Labels[rowIndex];
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
function EncodedTarget.ClassName(rowIndex: integer): string;
|
|
|
|
|
|
begin
|
|
|
|
|
|
var cls := ClassIndex(rowIndex);
|
|
|
|
|
|
|
|
|
|
|
|
if (cls < 0) or (cls >= ClassNames.Length) then
|
|
|
|
|
|
ArgumentOutOfRangeError(ER_ENCODED_TARGET_CLASS_INDEX_OUT_OF_RANGE, cls, ClassNames.Length);
|
|
|
|
|
|
|
|
|
|
|
|
Result := ClassNames[cls];
|
|
|
|
|
|
end;
|
2026-03-11 10:50:15 +03:00
|
|
|
|
|
|
|
|
|
|
function ToMatrix(Self: DataFrame; colNames: array of string): Matrix; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
var df := Self;
|
|
|
|
|
|
var n := df.RowCount;
|
|
|
|
|
|
var p := colNames.Length;
|
|
|
|
|
|
|
|
|
|
|
|
if p = 0 then
|
|
|
|
|
|
ArgumentError(ER_TO_MATRIX_NO_COLUMNS);
|
|
|
|
|
|
|
|
|
|
|
|
Result := new Matrix(n, p);
|
|
|
|
|
|
|
|
|
|
|
|
for var j := 0 to p - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
var col := df[colNames[j]];
|
2026-05-20 21:25:53 +03:00
|
|
|
|
case col.Info.ColType of
|
|
|
|
|
|
ColumnType.ctInt:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var c := IntColumn(col);
|
|
|
|
|
|
for var i := 0 to n - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not c.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TO_MATRIX_NON_NUMERIC, colNames[j]);
|
|
|
|
|
|
Result[i,j] := c.Data[i];
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctFloat:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var c := FloatColumn(col);
|
|
|
|
|
|
for var i := 0 to n - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not c.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TO_MATRIX_NON_NUMERIC, colNames[j]);
|
|
|
|
|
|
Result[i,j] := c.Data[i];
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctBool:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var c := BoolColumn(col);
|
|
|
|
|
|
for var i := 0 to n - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not c.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TO_MATRIX_NON_NUMERIC, colNames[j]);
|
|
|
|
|
|
Result[i,j] := if c.Data[i] then 1.0 else 0.0;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
else
|
2026-03-11 10:50:15 +03:00
|
|
|
|
ArgumentError(ER_TO_MATRIX_NON_NUMERIC, colNames[j]);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
function ToVector(Self: DataFrame; colName: string): Vector; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
var df := Self;
|
|
|
|
|
|
var n := df.RowCount;
|
|
|
|
|
|
Result := new Vector(n);
|
|
|
|
|
|
|
|
|
|
|
|
var col := df[colName];
|
2026-05-20 21:25:53 +03:00
|
|
|
|
case col.Info.ColType of
|
|
|
|
|
|
ColumnType.ctInt:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var c := IntColumn(col);
|
|
|
|
|
|
for var i := 0 to n - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not c.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TO_VECTOR_NON_NUMERIC, colName);
|
|
|
|
|
|
Result[i] := c.Data[i];
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctFloat:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var c := FloatColumn(col);
|
|
|
|
|
|
for var i := 0 to n - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not c.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TO_VECTOR_NON_NUMERIC, colName);
|
|
|
|
|
|
Result[i] := c.Data[i];
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctBool:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var c := BoolColumn(col);
|
|
|
|
|
|
for var i := 0 to n - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not c.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TO_VECTOR_NON_NUMERIC, colName);
|
|
|
|
|
|
Result[i] := if c.Data[i] then 1.0 else 0.0;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
else
|
2026-03-11 10:50:15 +03:00
|
|
|
|
ArgumentError(ER_TO_VECTOR_NON_NUMERIC, colName);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2026-05-07 22:53:13 +03:00
|
|
|
|
/// Кодирует строковые метки классов в целочисленные индексы (0..K-1).
|
2026-03-19 00:02:32 +03:00
|
|
|
|
/// Порядок кодирования соответствует порядку первого появления меток.
|
2026-05-07 22:53:13 +03:00
|
|
|
|
/// Используйте только при ручной подготовке данных (без DataPipeline).
|
|
|
|
|
|
/// Вызывать только ДО разбиения на train/test, чтобы избежать рассинхронизации меток.
|
2026-03-19 00:02:32 +03:00
|
|
|
|
function EncodeLabels(Self: DataFrame; target: string): array of integer; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Self = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'Self');
|
|
|
|
|
|
|
|
|
|
|
|
if target = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'target');
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.HasColumn(target) then
|
|
|
|
|
|
ArgumentError(ER_COLUMN_NOT_FOUND, target);
|
|
|
|
|
|
|
2026-04-22 14:08:27 +03:00
|
|
|
|
var col := Self[target];
|
|
|
|
|
|
for var i := 0 to Self.RowCount - 1 do
|
|
|
|
|
|
if not col.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TARGET_HAS_NA, target);
|
2026-03-31 12:38:47 +03:00
|
|
|
|
|
|
|
|
|
|
if Self.GetColumnType(target) = ColumnType.ctStr then
|
|
|
|
|
|
begin
|
|
|
|
|
|
var labels := Self.GetStrColumn(target);
|
|
|
|
|
|
Result := EncodeLabels(labels);
|
|
|
|
|
|
exit;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
if Self.GetColumnType(target) = ColumnType.ctInt then
|
|
|
|
|
|
begin
|
|
|
|
|
|
var labels := Self.GetIntColumn(target).ToArray;
|
2026-04-11 20:35:52 +03:00
|
|
|
|
var classes: array of integer;
|
|
|
|
|
|
Result := EncodeLabelsInt(labels,classes);
|
2026-03-31 12:38:47 +03:00
|
|
|
|
exit;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2026-06-19 22:06:08 +03:00
|
|
|
|
if Self.GetColumnType(target) = ColumnType.ctBool then
|
|
|
|
|
|
begin
|
|
|
|
|
|
var labels := Self.GetBoolColumn(target).ToArray.Select(x -> x.ToString).ToArray;
|
|
|
|
|
|
Result := EncodeLabels(labels);
|
|
|
|
|
|
exit;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2026-03-31 12:38:47 +03:00
|
|
|
|
ArgumentError(ER_ENCODELABELS_UNSUPPORTED_TYPE, target);
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Кодирует значения категориального столбца DataFrame в целочисленные индексы.
|
|
|
|
|
|
/// Каждому уникальному значению присваивается номер 0,1,2,...
|
|
|
|
|
|
/// Порядок кодирования соответствует порядку первого появления значений в столбце.
|
|
|
|
|
|
/// В параметр classes возвращается массив уникальных значений в порядке кодирования.
|
2026-06-19 22:06:08 +03:00
|
|
|
|
/// Работает для столбцов типов string, integer и boolean.
|
2026-03-31 12:38:47 +03:00
|
|
|
|
/// Для целочисленных категориальных столбцов значения преобразуются в строки.
|
|
|
|
|
|
/// Используется при подготовке данных для задач классификации и визуализации.
|
|
|
|
|
|
function EncodeLabels(Self: DataFrame; target: string; var classes: array of string): array of integer; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Self = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'Self');
|
|
|
|
|
|
|
|
|
|
|
|
if target = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'target');
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.HasColumn(target) then
|
|
|
|
|
|
ArgumentError(ER_COLUMN_NOT_FOUND, target);
|
|
|
|
|
|
|
2026-04-22 14:08:27 +03:00
|
|
|
|
var col := Self[target];
|
|
|
|
|
|
for var i := 0 to Self.RowCount - 1 do
|
|
|
|
|
|
if not col.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TARGET_HAS_NA, target);
|
2026-03-31 12:38:47 +03:00
|
|
|
|
|
|
|
|
|
|
case Self.GetColumnType(target) of
|
|
|
|
|
|
ColumnType.ctStr:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var labels := Self.GetStrColumn(target).ToArray;
|
|
|
|
|
|
Result := EncodeLabels(labels, classes);
|
|
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctInt:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var labels := Self.GetIntColumn(target).ToArray;
|
|
|
|
|
|
|
|
|
|
|
|
var intClasses: array of integer;
|
|
|
|
|
|
Result := EncodeLabelsInt(labels, intClasses);
|
|
|
|
|
|
|
|
|
|
|
|
// если API требует string classes:
|
|
|
|
|
|
classes := intClasses.Select(x -> x.ToString).ToArray;
|
|
|
|
|
|
end;
|
2026-06-19 22:06:08 +03:00
|
|
|
|
ColumnType.ctBool:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var labels := Self.GetBoolColumn(target).ToArray.Select(x -> x.ToString).ToArray;
|
|
|
|
|
|
Result := EncodeLabels(labels, classes);
|
|
|
|
|
|
end;
|
2026-03-31 12:38:47 +03:00
|
|
|
|
else
|
|
|
|
|
|
ArgumentError(ER_ENCODELABELS_UNSUPPORTED_TYPE, target);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2026-07-01 20:40:56 +03:00
|
|
|
|
/// Кодирует целевой столбец DataFrame и возвращает
|
|
|
|
|
|
/// целочисленные метки вместе с массивом имён классов.
|
|
|
|
|
|
/// Порядок кодирования соответствует порядку первого появления значений.
|
|
|
|
|
|
function EncodeTarget(Self: DataFrame; target: string): EncodedTarget; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
var classes: array of string;
|
|
|
|
|
|
Result.Labels := Self.EncodeLabels(target, classes);
|
|
|
|
|
|
Result.ClassNames := classes;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2026-04-01 06:33:26 +03:00
|
|
|
|
/// Преобразует строковые метки целевого столбца в целочисленные индексы (0,1,2,...)
|
|
|
|
|
|
/// с использованием заданного массива classes (mapping индекс → метка).
|
|
|
|
|
|
/// classes должен быть получен ранее с помощью EncodeLabels.
|
|
|
|
|
|
/// При обнаружении неизвестного значения выбрасывается исключение.
|
|
|
|
|
|
/// Используется для применения кодирования к тестовым данным (Transform).
|
|
|
|
|
|
function TransformLabels(Self: DataFrame; target: string; classes: array of string): array of integer; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Self = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'Self');
|
|
|
|
|
|
|
|
|
|
|
|
if target = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'target');
|
|
|
|
|
|
|
|
|
|
|
|
if classes = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'classes');
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.HasColumn(target) then
|
|
|
|
|
|
ArgumentError(ER_COLUMN_NOT_FOUND, target);
|
|
|
|
|
|
|
2026-04-22 14:08:27 +03:00
|
|
|
|
var col := Self[target];
|
|
|
|
|
|
for var i := 0 to Self.RowCount - 1 do
|
|
|
|
|
|
if not col.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TARGET_HAS_NA, target);
|
2026-04-01 06:33:26 +03:00
|
|
|
|
|
|
|
|
|
|
case Self.GetColumnType(target) of
|
|
|
|
|
|
ColumnType.ctStr:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var data := Self.GetStrColumn(target).ToArray;
|
2026-04-19 21:07:00 +03:00
|
|
|
|
Result := TransformLabels(data, classes);
|
2026-04-01 06:33:26 +03:00
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctInt:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var data := Self.GetIntColumn(target).ToArray;
|
2026-04-19 21:07:00 +03:00
|
|
|
|
var strData := new string[data.Length];
|
|
|
|
|
|
|
2026-06-19 22:06:08 +03:00
|
|
|
|
for var i := 0 to data.Length - 1 do
|
|
|
|
|
|
strData[i] := data[i].ToString;
|
|
|
|
|
|
|
|
|
|
|
|
Result := TransformLabels(strData, classes);
|
|
|
|
|
|
end;
|
|
|
|
|
|
ColumnType.ctBool:
|
|
|
|
|
|
begin
|
|
|
|
|
|
var data := Self.GetBoolColumn(target).ToArray;
|
|
|
|
|
|
var strData := new string[data.Length];
|
|
|
|
|
|
|
2026-04-01 06:33:26 +03:00
|
|
|
|
for var i := 0 to data.Length - 1 do
|
2026-04-19 21:07:00 +03:00
|
|
|
|
strData[i] := data[i].ToString;
|
|
|
|
|
|
|
|
|
|
|
|
Result := TransformLabels(strData, classes);
|
2026-04-01 06:33:26 +03:00
|
|
|
|
end;
|
|
|
|
|
|
else
|
|
|
|
|
|
ArgumentError(ER_ENCODELABELS_UNSUPPORTED_TYPE, target);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
/// Преобразует значения целочисленного категориального столбца
|
|
|
|
|
|
/// в плотные индексы (0,1,2,...) с использованием заданного массива classes.
|
|
|
|
|
|
/// classes должен быть получен ранее с помощью EncodeLabelsInt.
|
|
|
|
|
|
/// При обнаружении неизвестного значения выбрасывается исключение.
|
|
|
|
|
|
function TransformLabelsInt(Self: DataFrame; target: string; classes: array of integer): array of integer; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Self = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'Self');
|
|
|
|
|
|
|
|
|
|
|
|
if target = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'target');
|
|
|
|
|
|
|
|
|
|
|
|
if classes = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'classes');
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.HasColumn(target) then
|
|
|
|
|
|
ArgumentError(ER_COLUMN_NOT_FOUND, target);
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.IsCategorical(target) then
|
|
|
|
|
|
ArgumentError(ER_ENCODELABELS_NOT_CATEGORICAL, target);
|
|
|
|
|
|
|
|
|
|
|
|
if Self.GetColumnType(target) <> ColumnType.ctInt then
|
|
|
|
|
|
ArgumentError(ER_ENCODELABELS_UNSUPPORTED_TYPE, target);
|
2026-04-22 14:08:27 +03:00
|
|
|
|
|
|
|
|
|
|
var col := Self[target];
|
|
|
|
|
|
for var i := 0 to Self.RowCount - 1 do
|
|
|
|
|
|
if not col.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TARGET_HAS_NA, target);
|
2026-04-01 06:33:26 +03:00
|
|
|
|
|
|
|
|
|
|
var data := Self.GetIntColumn(target).ToArray;
|
|
|
|
|
|
|
2026-04-19 21:07:00 +03:00
|
|
|
|
Result := TransformLabelsInt(data, classes);
|
2026-04-01 06:33:26 +03:00
|
|
|
|
end;
|
|
|
|
|
|
|
2026-03-31 12:38:47 +03:00
|
|
|
|
/// Кодирует значения целочисленного категориального столбца DataFrame
|
|
|
|
|
|
/// в плотные целочисленные индексы 0,1,2,...
|
|
|
|
|
|
/// Каждому уникальному значению присваивается номер в порядке первого появления.
|
|
|
|
|
|
/// В параметр classes возвращается массив уникальных значений в порядке кодирования.
|
|
|
|
|
|
/// Работает только для категориальных столбцов типа integer.
|
|
|
|
|
|
/// Используется при подготовке данных для задач классификации и анализа.
|
|
|
|
|
|
function EncodeLabelsInt(Self: DataFrame; target: string; var classes: array of integer): array of integer; extensionmethod;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Self = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'Self');
|
|
|
|
|
|
|
|
|
|
|
|
if target = nil then
|
|
|
|
|
|
ArgumentNullError(ER_ARG_NULL, 'target');
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.HasColumn(target) then
|
|
|
|
|
|
ArgumentError(ER_COLUMN_NOT_FOUND, target);
|
|
|
|
|
|
|
|
|
|
|
|
if not Self.IsCategorical(target) then
|
|
|
|
|
|
ArgumentError(ER_ENCODELABELS_NOT_CATEGORICAL, target);
|
|
|
|
|
|
|
|
|
|
|
|
if Self.GetColumnType(target) <> ColumnType.ctInt then
|
|
|
|
|
|
ArgumentError(ER_ENCODELABELS_UNSUPPORTED_TYPE, target);
|
2026-03-19 00:02:32 +03:00
|
|
|
|
|
2026-04-22 14:08:27 +03:00
|
|
|
|
var col := Self[target];
|
|
|
|
|
|
for var i := 0 to Self.RowCount - 1 do
|
|
|
|
|
|
if not col.IsValid[i] then
|
|
|
|
|
|
ArgumentError(ER_TARGET_HAS_NA, target);
|
|
|
|
|
|
|
2026-03-31 12:38:47 +03:00
|
|
|
|
var labels := Self.GetIntColumn(target).ToArray;
|
2026-03-19 00:02:32 +03:00
|
|
|
|
|
2026-03-31 12:38:47 +03:00
|
|
|
|
Result := EncodeLabelsInt(labels, classes);
|
2026-03-19 00:02:32 +03:00
|
|
|
|
end;
|
|
|
|
|
|
|
2026-03-11 12:13:41 +03:00
|
|
|
|
|
|
|
|
|
|
|
2026-04-27 09:34:44 +03:00
|
|
|
|
end.
|