76 lines
2.5 KiB
ObjectPascal
76 lines
2.5 KiB
ObjectPascal
// Сравнение KMeans и DBSCAN на данных с шумом и разной плотностью.
|
||
//
|
||
// Оба алгоритма находят одинаковое число кластеров (k = 5),
|
||
// поэтому сравнение по ARI является корректным.
|
||
//
|
||
// KMeans предполагает компактные и одинаковые по форме кластеры,
|
||
// а также чувствителен к шуму, что снижает качество разбиения.
|
||
//
|
||
// DBSCAN выделяет кластеры как области высокой плотности
|
||
// и автоматически игнорирует шумовые точки (label = -1),
|
||
// благодаря чему лучше восстанавливает структуру данных.
|
||
//
|
||
// В результате DBSCAN показывает более высокий ARI,
|
||
// так как точнее отражает реальную геометрию кластеров.
|
||
|
||
// KMeans ARI: 0.8973
|
||
// DBSCAN ARI: 0.9496
|
||
|
||
uses MLABC, PlotML;
|
||
|
||
begin
|
||
// --- данные (сложный случай: разная плотность + шум)
|
||
var (X, yTrue) := Datasets.MakeBlobs(
|
||
n := 400,
|
||
centers := 3,
|
||
nFeatures := 2,
|
||
clusterStd := 0.9,
|
||
clusterStdVar := 1.0,
|
||
centerBox := 6.0,
|
||
classBalance := 1.0,
|
||
noisePoints := 60,
|
||
shuffle := True,
|
||
seed := 1
|
||
);
|
||
|
||
// --- модели
|
||
var kmeans := new KMeans(5);
|
||
kmeans.Fit(X);
|
||
var yKM := kmeans.Predict(X);
|
||
kmeans.ClustersCount.Println;
|
||
|
||
var db := new DBSCAN(0.7, 5);
|
||
var yDB := db.FitPredict(X);
|
||
db.ClustersCount.Println;
|
||
|
||
// --- метрики
|
||
var ariKM := Metrics.AdjustedRandIndex(yTrue, yKM);
|
||
var ariDB := Metrics.AdjustedRandIndex(yTrue, yDB);
|
||
|
||
Println('--- Clustering ---');
|
||
Println($'KMeans ARI: {ariKM,0:F4}');
|
||
Println($'DBSCAN ARI: {ariDB,0:F4}');
|
||
Println;
|
||
|
||
// --- координаты
|
||
var x1 := X.Col(0);
|
||
var x2 := X.Col(1);
|
||
|
||
// --- визуализация
|
||
var fig := Plot.Grid(1, 2);
|
||
|
||
// KMeans
|
||
//fig[0,0].SetPalette(Palettes.Bright);
|
||
fig[0,0].Points(x1, x2, yKM, size := 6);
|
||
fig[0,0].Title := $'KMeans (ARI={ariKM,0:F3})';
|
||
|
||
var yDB_plot := new integer[yDB.Length];
|
||
|
||
for var i := 0 to yDB.Length - 1 do
|
||
yDB_plot[i] := if yDB[i] = -1 then 0 else yDB[i] + 1;
|
||
// DBSCAN
|
||
//fig[0,1].SetPalette(Palettes.Bright);
|
||
fig[0,1].Points(x1, x2, yDB_plot, size := 6);
|
||
fig[0,1].Title := $'DBSCAN (ARI={ariDB,0:F3})';
|
||
end.
|