Python 中的 Jenks Natural Breaks:如何找到最佳的休息次数?

机器算法验证 Python 聚类 优化
2022-02-07 20:21:50

我找到Jenks Natural Breaks算法的Python 实现,我可以让它在我的 Windows 7 机器上运行。考虑到我的地理数据的大小,它的速度非常快,并且可以在很短的时间内找到中断。在对我的数据使用此聚类算法之前,我使用的是(此处)算法。我在使用 KMeans 时遇到的问题是找到最佳 K 值参数,但我“解决了”它针对不同 K 值启动算法并使用(此处)找到最佳 K。sklearn.clustering.KMeans sklearn.metrics.silhouette_score

我的问题是:如果我告诉 Natural Breaks 算法找到 5 个类(即 K),我如何确定这是与我的数据最匹配的类数?如何验证我选择了最佳休息次数?

谢谢!

1个回答

Jenks Natural Breaks 通过优化方差拟合优度来工作,该值介于 0 到 1 之间,其中 0 = 无拟合,1 = 完美拟合。选择类数的关键是在检测差异和过度拟合数据之间找到平衡。为了确定最佳的类数,我建议您使用您想要的阈值 GVF 值,并首先使用满足该值的类数。

下面是一个计算方差拟合优度的函数,给定一个要分类的值数组和选择的类数:

from jenks import jenks
import numpy as np
def goodness_of_variance_fit(array, classes):
    # get the break points
    classes = jenks(array, classes)

    # do the actual classification
    classified = np.array([classify(i, classes) for i in array])

    # max value of zones
    maxz = max(classified)

    # nested list of zone indices
    zone_indices = [[idx for idx, val in enumerate(classified) if zone + 1 == val] for zone in range(maxz)]

    # sum of squared deviations from array mean
    sdam = np.sum((array - array.mean()) ** 2)

    # sorted polygon stats
    array_sort = [np.array([array[index] for index in zone]) for zone in zone_indices]

    # sum of squared deviations of class means
    sdcm = sum([np.sum((classified - classified.mean()) ** 2) for classified in array_sort])

    # goodness of variance fit
    gvf = (sdam - sdcm) / sdam

    return gvf

def classify(value, breaks):
    for i in range(1, len(breaks)):
        if value < breaks[i]:
            return i
    return len(breaks) - 1

例如,假设您决定 GVF 至少应为 0.8,那么您可以增加类的数量直到 GVF 得到满足:

gvf = 0.0
nclasses = 2
while gvf < .8:
    gvf = goodness_of_variance_fit(array, nclasses)
    nclasses += 1