首页 > 解决方案 > 我必须将聚类算法应用于我的数据集的列

问题描述

我必须将以下内容应用于我的数据集 DF 聚类算法 https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html 我该怎么办?谢谢

我写了这段代码,但是当我发送它与完整的数据集一起运行时,我会输出“MEMORYERROR”

from sklearn.cluster import DBSCAN
from sklearn import metrics
import sklearn.utils
from sklearn.preprocessing import StandardScaler
#sklearn.utils.check_random_state(1000)
Clus_dataSet = df[['pickup_dt','pickup_lat', 'pickup_lon']]
Clus_dataSet = numpy.nan_to_num(Clus_dataSet)
Clus_dataSet = StandardScaler().fit_transform(Clus_dataSet)

# Compute DBSCAN
db = DBSCAN(eps=2, min_samples=2, metric='euclidean').fit(Clus_dataSet)
core_samples_mask = numpy.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_

# Number of clusters in labels, ignoring noise if present.
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_noise_ = list(labels).count(-1)

print('Estimated number of clusters: %d' % n_clusters_)
print('Estimated number of noise points: %d' % n_noise_)

# Plot result
import matplotlib.pyplot as plt

# Black removed and is used for noise instead.
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
          for each in numpy.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
    if k == -1:
        # Black used for noise.
        col = [0, 0, 0, 1]

    class_member_mask = (labels == k)

    xy = Clus_dataSet[class_member_mask & core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=14)

    xy = Clus_dataSet[class_member_mask & ~core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=6)

plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()

标签: python-3.xdbscan

解决方案


Clus_dataSet = df[['pickup_dt','pickup_lat', 'pickup_lon']]
Clus_dataSet = numpy.nan_to_num(Clus_dataSet)
Clus_dataSet = StandardScaler().fit_transform(Clus_dataSet) 

这对我来说已经是一个非常糟糕的主意。经纬度不能标准化。此外,仅将其与 datetime 混合可能会导致两者之间出现不良偏差。相反,您需要使用具有两个阈值的广义 DBSCAN。一个关于时间的阈值,一个关于坐标的Haversine距离的阈值。因为地球不是平的,如果你把它标准化,你甚至可以在向东和向北时缩放它。这没有多大意义,对吧?

此外,epsilon 对我来说似乎非常大,而 min samples 选择得太小(在 2 时,DBSCAN 通过单链路聚类成为一个平面切片)。

至于可扩展性,DBSCAN 的 sklearn 实现与原始 DBSCAN 的不同之处在于它使用更多的内存,特别是当半径设置得太高时。然后 sklearn 最多可以使用 O(n²) 内存。您可能想尝试使用 OPTICS 实现(实际上应该只使用 O(n) 内存)或使用备用 DBSCAN 实现,例如来自 ELKI 的实现。


推荐阅读