sklearn kmeans игнорирует номер кластера - PullRequest
0 голосов
/ 26 февраля 2020

Итак, у меня есть этот код для выбора лучшего числа кластеров с использованием метода силуэта:

def kmeans_silhouette(data) -> Tuple[np.array, np.array]:
    """
    Performs silhouette method to choose the best result for kMeans clustering.

    :param data: data to be clustered.
    :return:
    """
    import os

    logger.info(len(data))
    if len(data) == 1:
        return [0], data

    range_n_clusters = [2, 3, 4, 5, 6]
    labels = None
    centroids = None
    silhouette = -999

    for n_clusters in range_n_clusters:
        kmeans = KMeans(n_clusters=n_clusters, random_state=0)
        cluster_labels = kmeans.fit_predict(data)

        silhouette_avg = silhouette_score(data, cluster_labels)
        if silhouette_avg > silhouette:
            silhouette = silhouette_avg
            labels = cluster_labels
            centroids = kmeans.cluster_centers_

        if os.environ["DEBUG"]:
            logger.info(
                f"For n_clusters = {n_clusters}, the average silhouette_score is {silhouette_avg}"
            )

    return labels, centroids

Однако иногда появляется эта ошибка:

  File "/home/paula/.local/lib/python3.6/site-packages/sklearn/metrics/cluster/_unsupervised.py", line 117, in silhouette_score
    return np.mean(silhouette_samples(X, labels, metric=metric, **kwds))
  File "/home/paula/.local/lib/python3.6/site-packages/sklearn/metrics/cluster/_unsupervised.py", line 228, in silhouette_samples
    check_number_of_labels(len(le.classes_), n_samples)
  File "/home/paula/.local/lib/python3.6/site-packages/sklearn/metrics/cluster/_unsupervised.py", line 35, in check_number_of_labels
    "to n_samples - 1 (inclusive)" % n_labels)
ValueError: Number of labels is 1. Valid values are 2 to n_samples - 1 (inclusive)

Это должно произойти если определен один кластер, то для метода силуэта требуются как минимум кластеры ( ValueError: Количество меток равно 1. Допустимые значения от 2 до n_samples - 1 (включительно) при использовании silhouette_score ).

Итак, я проверил номер уникального cluster_labels, и он извлекает только один:

logger.info(np.unique(kmeans.labels_))

INFO [0]

Но указано, что минимальное количество кластеров, которое я хочу, равно 2. Интересно, имеет ли смысл для kmeans иметь параметр, указывающий количество кластеров, и при этом получить меньше кластеров, чем ожидалось.

...