我在使用Python进行核密度估计和高斯混合模型来对多维数据样本的可能性进行排序。每条数据都是一个角度,我不确定如何处理角度数据的周期性以用于机器学习。
首先,我通过给所有负角度加上360度来消除所有负角度,这样所有原本为负的角度都变成了正值,-179变成了181。我认为这优雅地处理了-179与179等类似情况的差异不大,但它并未处理像359与1差异不大的情况。
我想到的一种解决方法是保留负值和负值加360后的值,并使用两者中的最小值,但这需要对机器学习算法进行修改。
有没有一种只通过预处理就能解决这个问题的好方法?scipy或scikit中有内置的解决方案吗?
谢谢!
回答:
正如Tal Darom在评论中所写,你可以将每个周期性特征x
替换为两个特征cos(x)
和sin(x)
,在转换为弧度后进行归一化。这解决了359 ≈ 1的问题:
>>> def fromdeg(d):... r = d * np.pi / 180.... return np.array([np.cos(r), np.sin(r)])... >>> np.linalg.norm(fromdeg(1) - fromdeg(359))0.03490481287456796>>> np.linalg.norm(fromdeg(1) - fromdeg(180))1.9999238461283426>>> np.linalg.norm(fromdeg(90) - fromdeg(270))2.0
norm(a - b)
是向量a
和b
之间的欧几里得距离。正如你可以通过简单绘图验证,或者通过意识到这些(cos,sin)对实际上是单位圆上的坐标,这表明当原始角度相差180°时,这些(cos,sin)向量之间的距离最大(点积最小)。