Модуль DataFrameABC - фильтрация с пропущенными данными
Пропущенные данные в SCV-файле обозначаются как NA либо просто пустым элементом.
У курсора row есть метод, позволяющий проверять, пропущены ли данные в этом столбце.
В примере - фильтрация по строкам, в которых не пропущены данные в столбце score
#DataFrameABC
Пропущенные данные в SCV-файле обозначаются как NA либо просто пустым элементом.
У курсора row есть метод, позволяющий проверять, пропущены ли данные в этом столбце.
В примере - фильтрация по строкам, в которых не пропущены данные в столбце score
#DataFrameABC
🔥3👍1
Модуль DataFrameABC - добавление нового вычисляемого столбца
Можно добавлять новые вычисляемые столбцы с помощью WithColumn...
В примере показано, как добавить вычисляемый столбец passed, который принимает значение True для тех, у кого score >= 80.
Создается новый датафрейм, но данные создаются только для нового столбца.
#DataFrameABC
Можно добавлять новые вычисляемые столбцы с помощью WithColumn...
В примере показано, как добавить вычисляемый столбец passed, который принимает значение True для тех, у кого score >= 80.
Создается новый датафрейм, но данные создаются только для нового столбца.
#DataFrameABC
👍3
Фрактальная L-кривая Sierpinski Arrowhead
Отвлечемся от ML - и посмотрим на красоту фрактальных кривых.
Перед нами - Sierpinski Arrowhead
Модуль Turtle позволяет масштабировать мышью изображение.
Отвлечемся от ML - и посмотрим на красоту фрактальных кривых.
Перед нами - Sierpinski Arrowhead
Модуль Turtle позволяет масштабировать мышью изображение.
uses Turtle,GraphWPF;
var
Atom,FStr,XStr,YStr: string;
angle,len,x0,y0: real;
n: integer;
procedure Init5; // Sierpinski Arrowhead
begin
(Atom,FStr,XStr,YStr) := ('X', 'F', 'YF+XF+Y', 'XF-YF-X');
(angle,len,n,x0,y0) := (60,0.1,9,1,1);
end;
procedure RunStr(s: string; n: integer);
begin
foreach var c in s do
case c of
'+': Turn(angle);
'-': Turn(-angle);
'f','F': if n>0 then RunStr(FStr,n-1) else Forw(len);
'x','X': if n>0 then RunStr(XStr,n-1);
'y','Y': if n>0 then RunStr(YStr,n-1);
else Print('error')
end;
end;
begin
Init5;
x0 := -10;
y0 := -10;
ToPoint(x0,y0);
SetWidth(0.5);
Down;
RunStr(Atom,n);
Up;
end.
🔥7❤1👍1
Inner Join в DataFrameABC
Иногда данные находятся в разных таблицах, и их нужно объединить по общему ключу. Для этого используется Inner Join — соединение, которое оставляет только те строки, где ключ присутствует в обеих таблицах.
Результат:
Что произошло:
* соединение выполняется по столбцу id
* строка
* строка
Таким образом, Inner Join оставляет только пересечение ключей.
Такой тип соединения — один из самых используемых в анализе данных: объединение пользователей и заказов, студентов и оценок, товаров и продаж и т.д.
#MachineLearning
Иногда данные находятся в разных таблицах, и их нужно объединить по общему ключу. Для этого используется Inner Join — соединение, которое оставляет только те строки, где ключ присутствует в обеих таблицах.
// Inner Join
uses DataFrameABC;
begin
var students := DataFrame.FromCsvText('''
id,name
1,Alice
2,Bob
3,Charlie
''');
var scores := DataFrame.FromCsvText('''
id,score
1,85
2,90
4,70
''');
students.Join(scores, 'id').Print;
end.
Результат:
id name score
1 Alice 85
2 Bob 90
Что произошло:
* соединение выполняется по столбцу id
* строка
id = 3 отсутствует в таблице scores, поэтому она исключается* строка
id = 4 отсутствует в таблице students, поэтому она тоже исключаетсяТаким образом, Inner Join оставляет только пересечение ключей.
Такой тип соединения — один из самых используемых в анализе данных: объединение пользователей и заказов, студентов и оценок, товаров и продаж и т.д.
#MachineLearning
👍8❤🔥1
Left Join в DataFrameABC
Ранее мы показывали Inner Join — он оставляет только те строки, для которых ключи есть в обеих таблицах.
Теперь посмотрим на Left Join, который ведёт себя иначе.
Left Join сохраняет все строки из левой таблицы, даже если для них нет совпадения в правой.
Результат:
Здесь:
*
*
* строка
Это главное отличие от Inner Join, где строка
Ранее мы показывали Inner Join — он оставляет только те строки, для которых ключи есть в обеих таблицах.
Теперь посмотрим на Left Join, который ведёт себя иначе.
Left Join сохраняет все строки из левой таблицы, даже если для них нет совпадения в правой.
// Left Join
uses DataFrameABC;
begin
var students := DataFrame.FromCsvText('''
id,name
1,Alice
2,Bob
3,Charlie
''');
var scores := DataFrame.FromCsvText('''
id,score
1,85
2,90
4,70
''');
students.Join(scores, 'id', jkLeft).Print;
end.
Результат:
id name score
1 Alice 85
2 Bob 90
3 Charlie NA
Здесь:
*
Alice и Bob получили свои score*
Charlie сохранился, но значение score — NA* строка
id = 4 из таблицы scores не попала в результатЭто главное отличие от Inner Join, где строка
Charlie исчезла бы из результата.👍10👌1
PrintPreview для DataFrame
Обратите внимание, как выводит данные PrintPreview: выводится 3 строки - примерно половина из начала датасета и оставшаяся часть - из конца.
Обратите внимание, как выводит данные PrintPreview: выводится 3 строки - примерно половина из начала датасета и оставшаяся часть - из конца.
uses DataFrameABC;
begin
var df := DataFrame.FromCsvText('''
name,age,score
Alice,20,85
Bob,22,90
Charlie,21,78
Bob,22,90
Clara,,78
Kat,21,NA
''');
df.PrintPreview(3);
end.
❤8💯1
ML в PascalABC.NET — старт
В PascalABC.NET появилась новая библиотека машинного обучения — ML PascalABC.NET.
Она спроектирована как полноценный промышленный стек: с чёткой архитектурой, типобезопасностью и без внешних зависимостей.
Начинаем с базовых примеров.
📊 Стандартный датасет Iris + PairPlot визуализация
💡 Что здесь важно:
— Загрузка готового датасета (Datasets.Iris)
— Работа через DataFrame (ds.Data)
— Выделение матрицы признаков (ToMatrix)
— Кодирование целевой переменной (EncodeLabels)
— Визуализация через PairPlot
📌 PairPlot — базовый инструмент разведочного анализа данных (EDA):
он показывает распределения признаков и их попарные зависимости, что позволяет быстро увидеть структуру данных и разделимость классов.
Дальше будут:
— обучение моделей
— метрики
— пайплайны
— практические кейсы
Начинаем двигаться к полноценному ML прямо в PascalABC.NET.
В PascalABC.NET появилась новая библиотека машинного обучения — ML PascalABC.NET.
Она спроектирована как полноценный промышленный стек: с чёткой архитектурой, типобезопасностью и без внешних зависимостей.
Начинаем с базовых примеров.
📊 Стандартный датасет Iris + PairPlot визуализация
uses MLABC, PlotML;
begin
var ds := Datasets.Iris;
var df := ds.Data;
var X := df.ToMatrix(ds.Features);
var labels := df.EncodeLabels(ds.Target);
Plot.PairPlot(X, labels, ds.Features);
Plot.Title := 'Iris: пары признаков';
end.
💡 Что здесь важно:
— Загрузка готового датасета (Datasets.Iris)
— Работа через DataFrame (ds.Data)
— Выделение матрицы признаков (ToMatrix)
— Кодирование целевой переменной (EncodeLabels)
— Визуализация через PairPlot
📌 PairPlot — базовый инструмент разведочного анализа данных (EDA):
он показывает распределения признаков и их попарные зависимости, что позволяет быстро увидеть структуру данных и разделимость классов.
Дальше будут:
— обучение моделей
— метрики
— пайплайны
— практические кейсы
Начинаем двигаться к полноценному ML прямо в PascalABC.NET.
❤15🔥3
📊 Синтетические датасеты в PascalABC.NET: MakeBlobs
Иногда для демонстрации алгоритмов или отладки ML-моделей нужны простые и наглядные данные. Вместо поиска реальных датасетов удобно генерировать их самостоятельно.
В модуле MLABC есть классический генератор — MakeBlobs.
Он создаёт точки, сгруппированные в кластеры (как в задачах кластеризации и классификации).
🔹 Что делает MakeBlobs:
* генерирует заданное число точек
* разбивает их на кластеры
* добавляет контролируемый шум
* возвращает:
*
*
🔹 Пример + визуализация через PlotML:
🔹 Ключевые параметры:
*
*
*
*
💡 Где это полезно:
* объяснение кластеризации (k-means, DBSCAN)
* тестирование моделей классификации
* демонстрации на лекциях
* отладка пайплайнов
Иногда для демонстрации алгоритмов или отладки ML-моделей нужны простые и наглядные данные. Вместо поиска реальных датасетов удобно генерировать их самостоятельно.
В модуле MLABC есть классический генератор — MakeBlobs.
Он создаёт точки, сгруппированные в кластеры (как в задачах кластеризации и классификации).
🔹 Что делает MakeBlobs:
* генерирует заданное число точек
* разбивает их на кластеры
* добавляет контролируемый шум
* возвращает:
*
X — координаты точек*
y — метки кластеров🔹 Пример + визуализация через PlotML:
uses MLABC, PlotML;
begin
var centers := 3;
var (X,y) := Datasets.MakeBlobs(
n := 600,
centers := centers,
clusterStd := 0.8,
seed := 1
);
Plot.Title := 'MakeBlobs синтетический датасет';
var xs := X.Col(0);
var ys := X.Col(1);
Plot.Points(xs, ys, LabelsToInts(y), size := 4);
end.
🔹 Ключевые параметры:
*
n — число точек*
centers — число кластеров*
clusterStd — разброс внутри кластера*
seed — фиксирует генерацию (важно для воспроизводимости)💡 Где это полезно:
* объяснение кластеризации (k-means, DBSCAN)
* тестирование моделей классификации
* демонстрации на лекциях
* отладка пайплайнов
👍11❤2🔥1
Машинное обучение в PascalABC.NET: логистическая регрессия
Продолжаем серию практических постов по ML-библиотеке в PascalABC.NET.
В этом посте — первый полный пример: обучение и применение модели.
Разберём пример на классическом датасете Iris 🌸
🔍 Что здесь происходит
1. Загрузка данных
▪️ Datasets.Iris — встроенный датасет
▪️ df — табличное представление (DataFrame)
2. Подготовка признаков
▪️ ToMatrix → преобразование в Matrix (числовое ядро)
▪️ EncodeLabels → кодирование классов в Vector<int>
3. Разбиение
▪️ TrainTestSplit → контроль воспроизводимости через seed
4. Модель
▪️ LogisticRegression
▫️ мультиклассовая (softmax)
▫️ работает через Matrix/Vector
▫️ типобезопасная реализация
5. Обучение и предсказание
▪️ Fit → обучение
▪️ Predict → классы
6. Метрика
▪️ Metrics.Accuracy → базовая проверка качества
💡 Важно
Это не “обёртка над Python”, а нативная ML-библиотека на PascalABC.NET:
▪️ все шаги явно прописаны в коде (нет скрытых преобразований)
▪️ данные и модели имеют строгие типы (Matrix, Vector<int>)
▪️ результат полностью воспроизводим (за счёт фиксированного seed)
Продолжаем серию практических постов по ML-библиотеке в PascalABC.NET.
В этом посте — первый полный пример: обучение и применение модели.
Разберём пример на классическом датасете Iris 🌸
uses MLABC;
begin
var ds := Datasets.Iris;
var df := ds.Data;
var X := df.ToMatrix(ds.Features);
var y := df.EncodeLabels(ds.Target);
var (Xtrain, Xtest, ytrain, ytest) :=
Validation.TrainTestSplit(X, y, 0.2, 1);
var model := new LogisticRegression;
model.Fit(Xtrain, ytrain);
var pred := model.Predict(Xtest);
Println('Accuracy:', Metrics.Accuracy(ytest, pred):0:3);
end.
🔍 Что здесь происходит
1. Загрузка данных
▪️ Datasets.Iris — встроенный датасет
▪️ df — табличное представление (DataFrame)
2. Подготовка признаков
▪️ ToMatrix → преобразование в Matrix (числовое ядро)
▪️ EncodeLabels → кодирование классов в Vector<int>
3. Разбиение
▪️ TrainTestSplit → контроль воспроизводимости через seed
4. Модель
▪️ LogisticRegression
▫️ мультиклассовая (softmax)
▫️ работает через Matrix/Vector
▫️ типобезопасная реализация
5. Обучение и предсказание
▪️ Fit → обучение
▪️ Predict → классы
6. Метрика
▪️ Metrics.Accuracy → базовая проверка качества
💡 Важно
Это не “обёртка над Python”, а нативная ML-библиотека на PascalABC.NET:
▪️ все шаги явно прописаны в коде (нет скрытых преобразований)
▪️ данные и модели имеют строгие типы (Matrix, Vector<int>)
▪️ результат полностью воспроизводим (за счёт фиксированного seed)
🔥8🥰2❤1
Гистограмма распределения цен
Гистограмма показывает, как часто встречаются значения из набора данных.
В данном случае:
• по оси X — цена квартиры
• по оси Y — количество квартир с такой ценой
Каждый столбец (bin) — это интервал цен.
По гистограмме можно:
• понять, в каком диапазоне находится большинство значений
• увидеть редкие значения (очень дешёвые или очень дорогие квартиры)
• оценить форму распределения (например, симметричное или с «длинным хвостом» вправо)
Это базовый инструмент анализа данных перед построением моделей.
#MLABC
uses MLABC, PlotML;
begin
var ds := Datasets.MoscowHousing;
var df := ds.Data;
var price := df.ToVector(ds.Target);
Plot.Hist(price, bins := 40);
Plot.Title := 'Распределение цен на квартиры в Москве';
Plot.XLabel('Цена (руб)');
Plot.YLabel('Количество');
end.
Гистограмма показывает, как часто встречаются значения из набора данных.
В данном случае:
• по оси X — цена квартиры
• по оси Y — количество квартир с такой ценой
Каждый столбец (bin) — это интервал цен.
По гистограмме можно:
• понять, в каком диапазоне находится большинство значений
• увидеть редкие значения (очень дешёвые или очень дорогие квартиры)
• оценить форму распределения (например, симметричное или с «длинным хвостом» вправо)
Это базовый инструмент анализа данных перед построением моделей.
#MLABC
👍6❤1
🌳 Рекурсия на примере идеально сбалансированного дерева
💡 Что здесь происходит
1. Идеально сбалансированное дерево
Функция
* левое поддерево получает
* правое — остальные
Разница размеров поддеревьев не больше 1 ⇒ дерево максимально «ровное» по высоте.
2. Рекурсия
* База:
* Шаг: создаём узел и рекурсивно строим левое и правое поддеревья
То же самое в обходе:
* если узел пустой — выходим
* иначе обходим левое поддерево → текущий узел → правое
3. Инфиксный обход (LNR)
Порядок:
👉 Left → Node → Right
Это означает:
* сначала все элементы слева
* затем текущий
* затем справа
#pascalabc #рекурсия #деревья
type
Node<T> = auto class
public
Value: T;
Left, Right: Node<T>;
end;
function RandomTree(n: integer): Node<integer>;
begin
if n = 0 then
Result := nil
else
Result := new Node<integer>(
Random(100),
RandomTree((n - 1) div 2),
RandomTree(n - 1 - (n - 1) div 2)
);
end;
procedure Infix<T>(r: Node<T>; act: Action<T>);
begin
if r = nil then exit;
Infix(r.Left, act);
act(r.Value);
Infix(r.Right, act);
end;
begin
var root := RandomTree(10);
Infix(root, x -> Print(x));
end.
💡 Что здесь происходит
1. Идеально сбалансированное дерево
Функция
RandomTree(n) строит дерево из n узлов так, чтобы:* левое поддерево получает
(n - 1) div 2 узлов* правое — остальные
Разница размеров поддеревьев не больше 1 ⇒ дерево максимально «ровное» по высоте.
2. Рекурсия
* База:
n = 0 → nil* Шаг: создаём узел и рекурсивно строим левое и правое поддеревья
То же самое в обходе:
* если узел пустой — выходим
* иначе обходим левое поддерево → текущий узел → правое
3. Инфиксный обход (LNR)
Порядок:
👉 Left → Node → Right
Это означает:
* сначала все элементы слева
* затем текущий
* затем справа
#pascalabc #рекурсия #деревья
👍10❤2
🔍 Поиск выхода из лабиринта (DFS + backtracking)
Классическая задача: есть лабиринт → нужно найти путь от старта к выходу.
Решение — через DFS с откатом (backtracking):
* идём в глубину
* помечаем посещённые вершины
* если зашли в тупик — откатываемся назад
💡 Что важно:
*
*
📌 Такой код — отличный мост:
школьные задачи → графы → алгоритмы поиска → основы AI/ML
Классическая задача: есть лабиринт → нужно найти путь от старта к выходу.
Решение — через DFS с откатом (backtracking):
* идём в глубину
* помечаем посещённые вершины
* если зашли в тупик — откатываемся назад
function FindPath(graph: List<List<integer>>; visited: array of boolean;
path: List<integer>; v, finish: integer): boolean;
begin
path.Add(v);
visited[v] := True;
if v = finish then
exit(True);
foreach var toV in graph[v] do
if not visited[toV] then
if FindPath(graph, visited, path, toV, finish) then
exit(True);
path.RemoveAt(path.Count - 1);
Result := False;
end;
begin
// 3x3 лабиринт (граф)
var graph := Lst(
Lst(1,3),
Lst(0,2,4),
Lst(1,5),
Lst(0,4,6),
Lst(1,3,5),
Lst(2,4,8),
Lst(3,7),
Lst(6,8),
Lst(5,7)
);
var n := graph.Count;
var visited := n *[False];
var path := new List<integer>;
if FindPath(graph, visited, path, 0, 8) then
Println(path.JoinToString(' -> '))
else
Println('No path');
end.
💡 Что важно:
*
path.RemoveAt(...) — ключевой шаг отката*
Lst(...) удобно задаёт граф декларативно📌 Такой код — отличный мост:
школьные задачи → графы → алгоритмы поиска → основы AI/ML
👍10
Scan в PascalABC.NET — строим путь по шагам
Одна из самых недооценённых функций в работе с последовательностями — это Scan.
Она позволяет не просто «посчитать итог», а увидеть, как меняется состояние на каждом шаге.
📌 Пример — строим путь по последовательности шагов:
📊 Что происходит:
(1,0) → старт
затем добавляем каждый следующий шаг
получаем всю траекторию движения
👉 Результат — последовательность координат:
(1,0) (1,1) (2,1) (2,0) (2,-1) (1,-1) (1,0) (1,1)
Одна из самых недооценённых функций в работе с последовательностями — это Scan.
Она позволяет не просто «посчитать итог», а увидеть, как меняется состояние на каждом шаге.
📌 Пример — строим путь по последовательности шагов:
begin
var steps := Seq((1,0),(0,1),(1,0),(0,-1),(0,-1),(-1,0),(0,1),(0,1));
steps.Scan((p, step) -> (p[0] + step[0], p[1] + step[1])).Print
end.
📊 Что происходит:
(1,0) → старт
затем добавляем каждый следующий шаг
получаем всю траекторию движения
👉 Результат — последовательность координат:
(1,0) (1,1) (2,1) (2,0) (2,-1) (1,-1) (1,0) (1,1)
🔥5
Новый метод последовательностей DistinctAdjacent
В стандартной библиотеке последовательностей появился новый метод: DistinctAdjacent.
Он удаляет только подряд идущие одинаковые элементы, в отличие от обычного
Пример с числами
Результат:
Пример со строкой
Результат:
Пример с логами
Результат:
Когда это полезно
* очистка логов от повторяющихся подряд сообщений
* сжатие последовательностей (run-length preprocessing)
* обработка сигналов и данных с “залипанием” значений
Метод работает за один проход и не требует дополнительной памяти под множество — только сравнение с предыдущим элементом.
#новое
В стандартной библиотеке последовательностей появился новый метод: DistinctAdjacent.
Он удаляет только подряд идущие одинаковые элементы, в отличие от обычного
Distinct, который убирает все повторы.Пример с числами
begin
Seq(1,1,2,2,2,3,1,1).DistinctAdjacent.Println
end.
Результат:
1 2 3 1
Пример со строкой
begin
var s := 'aaabbbcca'.ToCharArray;
s.DistinctAdjacent.Println
end.
Результат:
a b c a
Пример с логами
begin
var logs := Seq('INFO','INFO','WARN','WARN','ERROR','INFO');
logs.DistinctAdjacent.Println
end.
Результат:
INFO WARN ERROR INFO
Когда это полезно
* очистка логов от повторяющихся подряд сообщений
* сжатие последовательностей (run-length preprocessing)
* обработка сигналов и данных с “залипанием” значений
Метод работает за один проход и не требует дополнительной памяти под множество — только сравнение с предыдущим элементом.
#новое
👍7
Не надо слов, не надо паники
(это мой последний день на Титанике 🚢)
В новой библиотеке ML для PascalABC.NET появился встроенный датасет TitanicRu — классическая задача бинарной классификации: предсказать, выжил пассажир или нет.
Причём поля датасета уже русифицированы:
●
●
●
●
●
●
и т.д.
Ниже — полный пример ML pipeline:
● загрузка датасета,
● обработка пропусков,
● кодирование категориальных признаков,
● разделение train/test,
● нормализация,
● обучение моделей,
● сравнение качества.
Типичный результат:
Получается практически sklearn-style ML прямо в PascalABC.NET:
●
●
●
●
●
●
●
●
без внешних зависимостей и с полностью типизированным API.
#MLABC
(это мой последний день на Титанике 🚢)
В новой библиотеке ML для PascalABC.NET появился встроенный датасет TitanicRu — классическая задача бинарной классификации: предсказать, выжил пассажир или нет.
Причём поля датасета уже русифицированы:
●
Возраст●
Пол●
Класс●
ЦенаБилета●
ПортПосадки●
Выжили т.д.
Ниже — полный пример ML pipeline:
● загрузка датасета,
● обработка пропусков,
● кодирование категориальных признаков,
● разделение train/test,
● нормализация,
● обучение моделей,
● сравнение качества.
uses MLABC;
begin
var ds := Datasets.TitanicRu;
var df := ds.Data.Drop(['Id', 'Имя']);
// Заполняем пропуски
var ageImputer := new Imputer(['Возраст']);
df := ageImputer.FitTransform(df);
var portImputer := new Imputer('Саутгемптон', ['ПортПосадки']);
df := portImputer.FitTransform(df);
// Кодируем категориальные признаки числами.
var sexEncoder := new LabelEncoder('Пол');
df := sexEncoder.FitTransform(df);
var portEncoder := new LabelEncoder('ПортПосадки');
df := portEncoder.FitTransform(df);
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги',
'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
var X := df.ToMatrix(features);
var y := df.GetIntColumn('Выжил');
var (Xtrain, Xtest, ytrain, ytest) :=
Validation.TrainTestSplit(X, y, testRatio := 0.2, seed := 42);
var scaler := new StandardScaler;
scaler.Fit(Xtrain);
var XtrainScaled := scaler.Transform(Xtrain);
var XtestScaled := scaler.Transform(Xtest);
var lr := new LogisticRegression(
learningRate := 0.01,
epochs := 2000
);
lr.Fit(XtrainScaled, ytrain);
var predLR := lr.Predict(XtestScaled);
var tree := new DecisionTreeClassifier(
maxDepth := 5,
minSamplesLeaf := 3,
minSamplesSplit := 6
);
tree.Fit(Xtrain, ytrain);
var predTree := tree.Predict(Xtest);
var forest := new RandomForestClassifier(
nTrees := 100,
maxDepth := 6,
minSamplesLeaf := 3,
minSamplesSplit := 6
);
forest.Fit(Xtrain, ytrain);
var predForest := forest.Predict(Xtest);
Println('Сравнение моделей на TitanicRu');
Println($'LogisticRegression: Accuracy = {Metrics.Accuracy(ytest, predLR):F3}');
Println($'DecisionTreeClassifier: Accuracy = {Metrics.Accuracy(ytest, predTree):F3}');
Println($'RandomForestClassifier: Accuracy = {Metrics.Accuracy(ytest, predForest):F3}');
end.
Типичный результат:
LogisticRegression: Accuracy = 0.787
DecisionTreeClassifier: Accuracy = 0.809
RandomForestClassifier: Accuracy = 0.831
Получается практически sklearn-style ML прямо в PascalABC.NET:
●
Imputer●
LabelEncoder●
StandardScaler●
TrainTestSplit●
LogisticRegression●
DecisionTreeClassifier●
RandomForestClassifier●
Metrics.Accuracyбез внешних зависимостей и с полностью типизированным API.
#MLABC
👏5❤3👍1
Табличная предобработка: Imputer и OrdinalEncoder
Один из важных этапов работы с табличными данными — предобработка: заполнение пропусков, кодирование категориальных признаков, масштабирование числовых данных и другие преобразования.
Пример: сначала заполним пропуск в числовом столбце
Вывод:
Такой подход реализует привычную для ML-библиотек схему Fit/Transform: сначала объект настраивается по данным, затем применяет преобразование к таблице.
#MLABC
Один из важных этапов работы с табличными данными — предобработка: заполнение пропусков, кодирование категориальных признаков, масштабирование числовых данных и другие преобразования.
Пример: сначала заполним пропуск в числовом столбце
population средним значением, а затем закодируем категориальный столбец region числами.uses MLABC;
begin
var df := DataFrame.FromCsvText('''
city,population,region
Ростов-на-Дону,1142,Юг
Таганрог,NA,Юг
Воронеж,1058,Центр
Курск,452,Центр
Белгород,392,Центр
''');
Println('Исходные данные:');
df.Print;
Println;
// Заполняем пропуск в числовом столбце средним значением
var imp := new Imputer(['population']);
df := imp.FitTransform(df);
// Кодируем названия регионов числами 0, 1, 2, ...
var encoder := new OrdinalEncoder('region');
df := encoder.FitTransform(df);
Println('После Imputer и OrdinalEncoder:');
df.Print;
end.
Вывод:
Исходные данные:
city population region
Ростов-на-Дону 1142 Юг
Таганрог NA Юг
Воронеж 1058 Центр
Курск 452 Центр
Белгород 392 Центр
После Imputer и OrdinalEncoder:
city population region
Ростов-на-Дону 1142.00 0
Таганрог 761.00 0
Воронеж 1058.00 1
Курск 452.00 1
Белгород 392.00 1
Imputer анализирует данные на этапе Fit и запоминает значение, которым нужно заменить пропуски. В данном примере для столбца population используется среднее значение.OrdinalEncoder преобразует строковые категории в числовые коды: разные значения столбца region получают номера 0, 1, 2, ...Такой подход реализует привычную для ML-библиотек схему Fit/Transform: сначала объект настраивается по данным, затем применяет преобразование к таблице.
#MLABC
👍6❤2🤩1
Простой текстовый редактор в GraphWPF
Демонстрация событий клавиатуры в GraphWPF для создания игрушечного текстового редактора.
Можно набирать текст, стирать последний символ, используя BackSpace, и переходить на следующую строку
uses GraphWPF;
var (x,y) := (0.0,0.0);
procedure KeyPress(c: char);
begin
if c = ' ' then
c := Chr($A0);
TextOut(x,y,c);
x += TextWidth(c);
end;
procedure KeyDown(k: Key);
begin
case k of
Key.Enter: begin
x := 0;
y += TextHeight('q');
end;
Key.Back: if x > 0 then
begin
x -= TextWidth('n');
FillRectangle(x,y,TextWidth('n'),TextHeight('n'));
end;
end;
end;
begin
Font.Size := 20;
Font.Name := 'Consolas';
OnKeyPress := KeyPress;
OnKeyDown := KeyDown;
end.
Демонстрация событий клавиатуры в GraphWPF для создания игрушечного текстового редактора.
Можно набирать текст, стирать последний символ, используя BackSpace, и переходить на следующую строку
❤🔥6👍6
Олимпиада PascalABC.NET 2026
16 мая прошла олимпиада по программированию Мехмат - PascalABC.NET 2026
В ней приняло участие 49 школьников Ростова и области
Приводим задачу C1 и ее решение
16 мая прошла олимпиада по программированию Мехмат - PascalABC.NET 2026
В ней приняло участие 49 школьников Ростова и области
Приводим задачу C1 и ее решение
begin
var words := ReadString.ToWords;
Print(words.GroupBy(w -> w.Order.JoinToString).Max(g -> g.Count));
end.
👍6