主要的方法就是,将数据存储在kd树这种空间数据结构中,树的思想类似于二叉搜索树、红黑树等,真的很强大(相信童靴们明白的)。建立kd树的过程,就是在多维数据点中,按照某一维度数值大小的中位数(中间值)不断循环划分空间,也就是超平面划分空间,形成树的层次结构。在传统的KNN算法中,有很多的应用和说明。
如下函数简单说明了,kd树的生成步骤
def create(point_list=None, dimensions=None, axis=0, sel_axis=None):
""" 基于一系列n维空间的数据点,建立kd树 """
if not point_list and not dimensions:
raise ValueError('empty error')
elif point_list:
dimensions = check_dimensionality(point_list, dimensions)
# by default cycle through the axis
sel_axis = sel_axis or (lambda prev_axis: (prev_axis+1) % dimensions)
if not point_list:
return KDNode(sel_axis=sel_axis, axis=axis, dimensions=dimensions)
# Sort point list and choose median as pivot element
point_list = list(point_list)
point_list.sort(key=lambda point: point[axis])
median = len(point_list) // 2
loc = point_list[median]
left = create(point_list[:median], dimensions, sel_axis(axis))
right = create(point_list[median + 1:], dimensions, sel_axis(axis))
return KDNode(loc, left, right, axis=axis, sel_axis=sel_axis, dimensions=dimensions)
改进的k-means方法主要考虑了合理的初始候选质心的方式,并且利用kd树的特性,减少了循环计算欧式距离的次数,并且从Voronoi多边形得到的启发进行最近点计算和剪枝策略,实现的代码。运行证明在大量数据的情况下,算法的执行效率确实有很大改进。最后感谢Tapas Kanungo等的论文《An Efficient k-Means Clustering Algorithm:Analysis and Implementation》提供的算法思路和证明。