了解并找到 DBSCAN 的最佳 eps 值

数据挖掘 Python k-均值 matplotlib 绘图 数据库扫描
2022-03-03 13:53:47

我正在尝试在.csv 上运行 DBSCAN 算法。在我的程序的第一部分,我加载它并在其中绘制数据以检查其分布。这是代码的第一部分:

import csv
import sys
import os
from os.path import join
from sklearn.cluster import DBSCAN
import matplotlib.pyplot as plt
import numpy as np

def load_data(file_path, file_name):
   with open(join(file_path, file_name)) as csv_file:
       data_file = csv.reader(csv_file,delimiter=',')
       temp1 = next(data_file)
       n_samples = int(temp1[0])
       print("n_samples=")
       print(n_samples)
       n_features = int(temp1[1])
       temp2 = next(data_file)
       feature_names = np.array(temp2[:n_features])

       data_list = [iter for iter in data_file]
               
       data = np.asarray(data_list, dtype=np.float64)                  
       
   return(data,feature_names,n_samples,n_features)

# --- Main program ---

file_path="Datasets/"    
file_name3="CURE-complete.csv"    
data3,feature_names3,n_samples3,n_features3 = load_data(file_path, file_name3)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111)
fig.subplots_adjust(top=1)
ax.set_title('Dataset n. 3 of data points')
ax.set_xlabel(feature_names3[0])
ax.set_ylabel(feature_names3[1])
plt.plot(data3[:,0], data3[:,1], '.', markersize=1.2, markeredgecolor = 'blue')
plt.show()

这是数据的表示方式: 在此处输入图像描述

因为我需要知道我应该将数据集分成多少个集群,所以我使用了返回 4 的 Means 算法(这是图表的肘部,最佳值):

sse = {}
for k in range(1, 11):
    kmeans = KMeans(n_clusters=k, random_state=0).fit(data3)
    sse[k] = kmeans.inertia_
    
kn = KneeLocator(
    list(sse.keys()),
    list(sse.values()),
    curve='convex',
    direction='decreasing',
    interp_method='polynomial',
)

plt.figure()
plt.plot(list(sse.keys()), list(sse.values()))
plt.vlines(kn.knee, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')
plt.xlabel("Number of clusters")
plt.ylabel("SSE")
plt.show()

这是图表: 在此处输入图像描述

然后,我使用以下参数运行 DBSCAN 算法:min_sample = 10(固定值,我需要使用它)和 eps = 2。这是代码:

np.random.seed(5)
dbscan2 = DBSCAN(eps=2, min_samples=10).fit(data3)
fig = plt.figure(figsize=(20,10))

ax = fig.add_subplot(111)
fig.subplots_adjust(top=1)
ax.set_title('Clustered points in dataset n. 3')

ax.set_xlabel('x')
ax.set_ylabel('y')

# set the list of colors to be selected when plotting the different clusters
color=['b','g','r','c','m','y','k','w']

# number of clusters given by the diagram
k=4

#plot the dataset
for clu in range(k):
    # collect the sequence of cooordinates of the points in each given cluster (determined by clu)
    data_list_x = [data3[i,0] for i in range(n_samples3) if dbscan2.labels_[i]==clu]
    data_list_y = [data3[i,1] for i in range(n_samples3) if dbscan2.labels_[i]==clu]
    plt.scatter(data_list_x, data_list_y, s=10, edgecolors='none', c=color[clu], alpha=0.5)

plt.show()

这是结果: 在此处输入图像描述

我的流程不正确吗?我不明白为什么情节看起来如此不同。我希望有一个与第一个类似的图表,但每个集群的颜色不同。

1个回答

KMeans 和 DBSCAN 是两种不同类型的聚类技术。

用于获得最佳集群计数的肘部方法应仅在 K-Means 中使用。
您使用该值(即 K=4)为散点图分配颜色,而 DBSCAN 拟合方法中未使用该参数。

实际上这不是 DBSCAN 的有效参数
您必须控制“esp”来控制集群的数量

适合esp=6 导致 112 Clusters你只需要这几行代码

dbscan2 = DBSCAN(eps=6, min_samples=10).fit(data3)
fig = plt.figure(figsize=(12,7))

# max(dbscan2.labels_) # This is the number of Cluster
plt.scatter(data3[:,0], data3[:,1], s=10, edgecolors='none', c=dbscan2.labels_, alpha=0.5, cmap='hsv')

在此处输入图像描述