使用DBSCAN对角度数据进行聚类
我需要把一些数据点分成不同的组,这些数据点的格式是X,Y,Phi。现在我使用的是DBSCAN这个工具(来自sklearn库)。分组的效果还不错,但有一个问题:Phi是角度数据,它的范围是0到2π(也就是360度)。所以在Phi接近0的地方,分组的结果就不太对了。有没有什么办法可以解决这个问题?我自己找不到合适的办法,也想不出什么有效的解决方案。
谢谢。
2 个回答
1
DBSCAN可以处理任意距离。
所以首先你需要定义一个距离函数(这可能会用到一些三角函数),然后把这个函数放进DBSCAN里作为相似度的计算方式。
你可以尝试用下面这样的方式:
distance = (x1-x2)**2 + (y1-y1)**2 + factor * sin(phi1-phi2)**2
不过你需要仔细选择你的权重factor
,因为角度差异和你的X
和Y
轴是不同的量级,我想是这样的。
在这个数据集上不要使用欧几里得距离,原因很明显。
2
圆形边界条件在实际操作中不太容易实现,特别是在没有傅里叶框架的情况下。
你可以尝试通过重新参数化来解决这个问题,也就是用 X, Y, a * cos(Phi), a * sin(Phi)
来替换 X, Y, Phi
。这里的 a > 0
是一个缩放因子,需要正确选择,这样才能让这个投影在二维空间中按你需要的方式进行聚类。可以先试试 a = 1
(如果在纯 Phi
的情况下效果不错,那这个值就很合适),然后再根据你剩下的数据 X, Y
的数量级来调整 a
。
这样做的想法是把 Phi
替换成它的“真实”复杂“含义”,也就是 相位,即 exp(1j * Phi)
,但在整个过程中保持它是实数。
接下来,你需要基于这个重新参数化的结果来计算距离,比如欧几里得距离:
dist = ((np.array([X1, Y1, a* np.cos(Phi1), a * np.sin(Phi1)]) - np.array([X2, Y2, a * np.cos(Phi2), a * np.sin(Phi2)])) ** 2).sum()
你需要对每一对数据进行这样的计算,然后再把结果输入到你的 DBSCAN 对象中。