85 lines
3.5 KiB
ObjectPascal
85 lines
3.5 KiB
ObjectPascal
|
|
// Первый пример кластеризации.
|
|||
|
|
//
|
|||
|
|
// В этом примере:
|
|||
|
|
// 1) загружаем готовый датасет городов России;
|
|||
|
|
// 2) выбираем признаки для кластеризации;
|
|||
|
|
// 3) обучаем алгоритм KMeans;
|
|||
|
|
// 4) получаем номер кластера для каждого города;
|
|||
|
|
// 5) выводим несколько представителей каждого кластера.
|
|||
|
|
//
|
|||
|
|
// Важно:
|
|||
|
|
// здесь кластеры отражают прежде всего географическую близость городов,
|
|||
|
|
// потому что для кластеризации используются только широта и долгота.
|
|||
|
|
// Население нужно только для выбора самых заметных представителей кластера.
|
|||
|
|
//
|
|||
|
|
// При числе кластеров k = 4 результат можно интерпретировать так:
|
|||
|
|
// • один кластер обычно соответствует Европейской части России;
|
|||
|
|
// • один - Уралу, Поволжью и соседним территориям;
|
|||
|
|
// • один - Сибири;
|
|||
|
|
// • один - Дальнему Востоку и северо-востоку.
|
|||
|
|
uses MLABC;
|
|||
|
|
|
|||
|
|
begin
|
|||
|
|
// Загружаем учебный датасет с городами России
|
|||
|
|
var ds := Datasets.RussianCities;
|
|||
|
|
|
|||
|
|
// Берём таблицу данных из датасета
|
|||
|
|
var df := ds.Data;
|
|||
|
|
|
|||
|
|
// Для первого примера используем только координаты города
|
|||
|
|
var features := ['lat', 'lon'];
|
|||
|
|
|
|||
|
|
// Преобразуем выбранные признаки в числовую матрицу
|
|||
|
|
var X := df.ToMatrix(features);
|
|||
|
|
|
|||
|
|
// Создаём модель KMeans и просим разбить города на 4 группы.
|
|||
|
|
// Для первого примера этого достаточно, чтобы увидеть общую структуру данных.
|
|||
|
|
var model := new KMeans(4, seed := 42);
|
|||
|
|
|
|||
|
|
// Обучаем модель на всех объектах
|
|||
|
|
model.Fit(X);
|
|||
|
|
|
|||
|
|
// Получаем номер кластера для каждого города
|
|||
|
|
var labels := model.PredictLabels(X);
|
|||
|
|
|
|||
|
|
// Получаем названия городов
|
|||
|
|
var cities := df.GetStrColumn('city');
|
|||
|
|
|
|||
|
|
// Получаем численность населения городов
|
|||
|
|
var populations := df.GetFloatColumn('population');
|
|||
|
|
|
|||
|
|
// Выводим, сколько кластеров нашёл алгоритм
|
|||
|
|
Println($'Число кластеров: {model.ClustersCount}');
|
|||
|
|
|
|||
|
|
Println;
|
|||
|
|
Println('Примеры городов в каждом кластере (в скобках - тыс. жителей):');
|
|||
|
|
|
|||
|
|
// Для каждого кластера выводим три самых крупных города
|
|||
|
|
for var cluster := 0 to model.ClustersCount - 1 do
|
|||
|
|
begin
|
|||
|
|
Println;
|
|||
|
|
Println($'Кластер {cluster + 1}:');
|
|||
|
|
|
|||
|
|
var clusterIndices := new List<integer>;
|
|||
|
|
|
|||
|
|
for var i := 0 to labels.Length - 1 do
|
|||
|
|
if labels[i] = cluster then
|
|||
|
|
clusterIndices.Add(i);
|
|||
|
|
|
|||
|
|
clusterIndices := clusterIndices
|
|||
|
|
.OrderByDescending(i -> populations[i])
|
|||
|
|
.ToList;
|
|||
|
|
|
|||
|
|
var shown := 0;
|
|||
|
|
|
|||
|
|
foreach var i in clusterIndices do
|
|||
|
|
begin
|
|||
|
|
Println($' {cities[i]} ({populations[i]:F0})');
|
|||
|
|
shown += 1;
|
|||
|
|
|
|||
|
|
if shown = 4 then
|
|||
|
|
break;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
end.
|