Python 从数据集中提取线形式的簇

Python 从数据集中提取线形式的簇,python,cluster-analysis,Python,Cluster Analysis,我有一个类似于下图的数据集,从我的角度来看,它清晰地形成了线条。我希望通过一条线连接每条曲线内的标记,而不是绘制标记。我很好奇,在这种情况下,什么样的聚类算法才是好的 import numpy as np import matplotlib.pyplot as plt np.random.seed = 42 #Generate (x,y) data x = np.linspace(0.1,0.9,50) y = x%1 x += np.sin(2*x%1) y = y%0.2 #Shuffl

我有一个类似于下图的数据集,从我的角度来看,它清晰地形成了线条。我希望通过一条线连接每条曲线内的标记,而不是绘制标记。我很好奇,在这种情况下,什么样的聚类算法才是好的

import numpy as np
import matplotlib.pyplot as plt
np.random.seed = 42

#Generate (x,y) data
x = np.linspace(0.1,0.9,50)
y = x%1
x += np.sin(2*x%1)
y = y%0.2

#Shuffle (x,y) data
ns = list(range(len(x)))
np.random.shuffle(ns)
x = x[ns]
y = y[ns]

#Plot
fig, axs = plt.subplots(1,2)
axs[0].scatter(x,y)
axs[1].plot(x,y)
plt.savefig("markers vs lines.pdf")
-左:标记,右:线连接的数据点


由于体系结构的原因,此类数据在图像分析中很常见

为了推断透视图,人们使用Hough变换来识别点的直线


这可能是这里使用的最佳方法。

既然您要求使用聚类算法,那么您可能需要看看DBSCAN

有两个参数,epsilon和点的个数组成一个簇

以下是一段代码,可以帮助您开始:

from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler

import numpy as np
import matplotlib.pyplot as plt
np.random.seed = 42
%matplotlib inline

#Generate (x,y) data
x = np.linspace(0.1,0.9,50)
y = x%1
x += np.sin(2*x%1)
y = y%0.2

#Shuffle (x,y) data
ns = list(range(len(x)))
np.random.shuffle(ns)
x = x[ns]
y = y[ns]

"""
    Fit the Data 
"""
X = [i for i in zip(x,y)]
X = StandardScaler().fit_transform(X)

"""
    Compute the DBSCAN
"""
db = DBSCAN(eps=0.5, min_samples=1).fit(X)
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_clusters_

"""
    Plot the clusters
"""
d= dict(zip(set(labels),['red','green','blue','yellow','purple','grey']))
d[-1] = "black"
plt.scatter(x,y,color=[ d[i] for i in labels])
plt.show()
结果是:

委托人:

有关DBSCAN参数的更多信息,请参见:


希望这能有所帮助。

太好了,DBSCAN正是我想要的。谢谢,谢谢。如果我理解正确,如果曲线的形状已知(例如直线或抛物线),Hough变换效果良好。原则上,这是上述图的正确答案。然而,在我的例子中,我并不确切知道曲线的形状。Tbaki的答案更适合这种情况,因为DBSCAN不需要知道曲线的形状;它们不可能是一个圆。DBSCAN是一个选项(然后您可能应该使用4C集群,它基于DBSCAN?),但是如果线彼此太近,您会看到它失败。谢谢,4C算法似乎是我问题的一个很好的扩展。然而,在我的例子中,简单的DBscan版本就足够了。