我正在实施一种用于 k 均值聚类的算法。到目前为止,它使用欧几里得距离。将欧几里得距离换成马氏距离无法正确聚类。
出于某种原因,马氏距离有时是负的。原来协方差矩阵具有负特征值,这显然不适合协方差矩阵。
以下是我正在使用的功能:
#takes in data point x, centroid m, covariance matrix sigma
def mahalanobis(x, m, sigma):
return np.dot(np.dot(np.transpose(x - m), np.linalg.inv(sigma)), x - m)
#takes in centroid m and data (iris in 2d, dimensions: 2x150)
def covar_matrix(m, data):
d, n = data.shape
R = np.zeros((d,d))
for i in range(n):
R += np.dot(data[:,i:i+1] , np.transpose(data[:,i:i+1]))
R /= n
return R - np.dot(m, np.transpose(m))
#autocorrelation_matrix - centroid*centroid'
我是如何实现算法的:
设置 k
随机选择 k 个质心
计算每个质心的 covar_matrix()
计算每个质心的每个数据点的 mahalanobis() 并添加到最近的集群
- 开始寻找新的质心;对于每个集群中的每个数据点*,计算 mahalanobis() 到集群中每个其他点的总和;总和最小的点成为新的质心
- 重复 3-5 直到旧质心和新质心相同
*用这一点计算covar_matrix()
我期望一个正的马氏距离和一个正定的协方差矩阵(我希望后者将修复前者)。