Jenks Natural Breaks в Python: как найти оптимальное количество перерывов?

17

Я нашел эту реализацию Python в Дженкс Natural Breaks алгоритма , и я мог бы сделать его запустить на моем компьютере Windows 7. Это довольно быстро, и он находит разрывы за короткое время, учитывая размер моих геоданных. Прежде чем использовать этот алгоритм кластеризации для моих данных, я использовал sklearn.clustering.KMeans (здесь) алгоритм. Проблема, с которой я столкнулся с KMeans, заключалась в поиске оптимального параметра значения K, но я «решил» его, запустив алгоритм для различных значений K и используя sklearn.metrics.silhouette_score (здесь), чтобы найти лучший K.

Мой вопрос: если я скажу алгоритму Natural Breaks найти 5 классов (это будет K), как я могу быть уверен, что это количество классов, которые лучше всего соответствуют моим данным? Как проверить, что я выбираю лучшее количество перерывов?

Благодарность!

iamgin
источник
Чтобы мы могли объективно определить, что означает «лучший», не могли бы вы объяснить, в каком смысле классы «соответствуют» данным? (Или, действительно, как бы вы оценили любую степень несоответствия.)
whuber
Использование Silhouette с Jenks должно быть сравнимо с использованием его с kmeans. Это эвристика, и вы не должны доверять ей вслепую. ИМХО, лучше всего визуализировать ваши результаты.
Аноним-Мусс-Восстановить Монику
Whuber: Best, используя Silhouette, будет означать количество классов, которые делают индекс ближе к 1, согласно определению на сайте sklearn : scikit-learn.org/stable/modules/generated/… Anony-Mousse: я не могу визуализировать 20+ переменных, подготовьте карты для этого и ожидайте, что мой мозг не испортит количество классов. Мне нужно полагаться на индекс, который говорит: «Для переменной X лучшее, что вы можете сделать, это использовать классы Y». Более того, мне нужно повторить анализ несколько раз, к сожалению, этот подход медленный ...
iamgin
из jenks import jenks: выдает следующую ошибку Traceback (последний вызов был последним): файл "<stdin>", строка 1, в <module> ImportError: невозможно импортировать имя jenks
user120982

Ответы:

19

Jenks Natural Breaks работает, оптимизируя Goodness of Variance Fit, значение от 0 до 1, где 0 = No Fit и 1 = Perfect Fit. Ключ при выборе количества классов - найти баланс между обнаружением различий и переоснащением ваших данных. Чтобы определить оптимальное количество классов, я предлагаю вам использовать желаемое пороговое значение GVF и сначала использовать количество классов, которое удовлетворяет этому значению.

Ниже приведена функция для вычисления Goodness of Variance Fit с учетом массива значений для классификации и количества выбранных классов:

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
camdenl
источник