Как я могу использовать динамический c espilon в DBSCAN? - PullRequest
0 голосов
/ 02 апреля 2020

Сегодня я работаю над набором данных из Kaggle https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data. Я хотел бы сегментировать свой набор данных по кроватям, баням, районам и использовать DBSCAN, чтобы получить кластеризацию по цене в каждом сегменте. Проблема в том, что каждый сегмент отличается, я не хочу использовать один и тот же эпсилон для всех моих наборов данных, но для каждого сегмента лучший эпсилон, знаете ли вы эффективный способ сделать это?

from sklearn.cluster import DBSCAN
import sklearn.utils
from sklearn.preprocessing import StandardScaler
sklearn.utils.check_random_state(1000)
Clus_dataSet = pdf[['beds','baths','neighborhood','price']]
Clus_dataSet = np.nan_to_num(Clus_dataSet)
Clus_dataSet = StandardScaler().fit_transform(Clus_dataSet)

# Compute DBSCAN
db = DBSCAN(eps=0.3, min_samples=6).fit(Clus_dataSet)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_
pdf["Clus_Db"]=labels

realClusterNum=len(set(labels)) - (1 if -1 in labels else 0)
clusterNum = len(set(labels)) 

Спасибо.

1 Ответ

0 голосов
/ 03 апреля 2020

Heuristi c для настройки параметров Epsilon и MinPts было предложено в оригинальной бумаге DBSCAN

После установки значения MinPts (например, 2 * Количество функций) результат разбиения сильно зависит от Epsilon. Heuristi c предлагает вывести эпсилон с помощью визуального анализа графика k-dist .

Игрушечный пример процедуры с двумя гауссовыми распределениями представлен ниже.

from sklearn.neighbors import NearestNeighbors
from matplotlib import pyplot as plt
from sklearn.datasets import make_biclusters
data,lab,_ = make_biclusters((200,2), 2, noise=0.1, minval=0, maxval=1)
minpts = 4
nbrs = NearestNeighbors(n_neighbors=minpts, algorithm='ball_tree').fit(data) 
distances, indices = nbrs.kneighbors(data)
k_dist = [x[-1] for x in distances]
f,ax = plt.subplots(1,2,figsize = (10,5))
ax[0].set_title('k-dist plot for k = minpts = 4') 
ax[0].plot(sorted(k_dist))
ax[0].set_xlabel('object index after sorting by k-distance')
ax[0].set_ylabel('k-distance')
ax[1].set_title('original data')
ax[1].scatter(data[:,0],data[:,1],c = lab[0])

В результирующем графике k-dist "колено" теоретически разделяет объекты шума от объектов кластера и действительно дает указание на вероятный диапазон значений для Epsilon (с учетом набора данных в сочетании с выбранным значением MinPts). В этом примере с игрушкой я бы сказал, что от 0,05 до 0,075.

k-dist

...