DBSCAN (tsz. DBSCANs)
A scikit-learn
könyvtár tartalmazza a DBSCAN implementációját.
from sklearn.cluster import DBSCAN
import numpy as np
import matplotlib.pyplot as plt
# Példaadatok generálása
from sklearn.datasets import make_blobs
X, _ = make_blobs(n_samples=300, centers=3, cluster_std=0.5, random_state=0)
# DBSCAN modell
dbscan = DBSCAN(eps=0.3, min_samples=5)
labels = dbscan.fit_predict(X)
# Eredmények vizualizálása
plt.scatter(X, X, c=labels, cmap='viridis', marker='o')
plt.title("DBSCAN klaszterezés")
plt.xlabel("X tengely")
plt.ylabel("Y tengely")
plt.show()
DBSCAN implementálása C++-ban nehezebb lehet, de térbeli adatstruktúrákkal (pl. KD-fa) hatékonyan megvalósítható.
#include <iostream>
#include <vector>
#include <cmath>
#include <unordered_set>
using namespace std;
// Távolság számítása
double euclidean_distance(const vector<double>& a, const vector<double>& b) {
double sum = 0.0;
for (size_t i = 0; i < a.size(); ++i) {
sum += (a - b) * (a - b);
}
return sqrt(sum);
}
// DBSCAN algoritmus
void dbscan(const vector<vector<double>>& points, double eps, int minPts, vector<int>& labels) {
int cluster_id = 0;
size_t n = points.size();
labels.assign(n, -1); // -1 jelöli a zajos pontokat
for (size_t i = 0; i < n; ++i) {
if (labels != -1) continue;
// Szomszédok keresése
vector<int> neighbors;
for (size_t j = 0; j < n; ++j) {
if (euclidean_distance(points, points) <= eps) {
neighbors.push_back(j);
}
}
if (neighbors.size() < static_cast<size_t>(minPts)) {
labels = -1; // Zajos pont
continue;
}
// Új klaszter
++cluster_id;
labels = cluster_id;
// Expand klaszter
size_t idx = 0;
while (idx < neighbors.size()) {
int neighbor = neighbors;
if (labels == -1) {
labels = cluster_id;
} else if (labels != 0) {
++idx;
continue;
}
labels = cluster_id;
// Új szomszédok keresése
vector<int> new_neighbors;
for (size_t j = 0; j < n; ++j) {
if (euclidean_distance(points, points) <= eps) {
new_neighbors.push_back(j);
}
}
if (new_neighbors.size() >= static_cast<size_t>(minPts)) {
neighbors.insert(neighbors.end(), new_neighbors.begin(), new_neighbors.end());
}
++idx;
}
}
}
int main() {
vector<vector<double>> points = {{1, 1}, {2, 2}, {3, 3}, {8, 8}, {8, 9}, {25, 80}};
double eps = 2.0;
int minPts = 2;
vector<int> labels;
dbscan(points, eps, minPts, labels);
for (size_t i = 0; i < labels.size(); ++i) {
cout << "Pont " << i << ": klaszter " << labels << endl;
}
return 0;
}
Kimenet:
Pont 0: klaszter 1 Pont 1: klaszter 1 Pont 2: klaszter 1 Pont 3: klaszter 2 Pont 4: klaszter 2 Pont 5: zajos pont
A DBSCAN egy robusztus és rugalmas klaszterezési algoritmus, amely jól kezeli a zajos adatokat és a tetszőleges alakú klasztereket. Bár paraméterérzékenysége és nagy dimenziójú adatokon való alkalmazása kihívásokat jelenthet, számos gyakorlati probléma megoldására kiváló eszköz.