Достижение адаптивного DBSCAN

#python #machine-learning #cluster-analysis #dbscan

#python #машинное обучение #кластерный анализ #dbscan

Вопрос:

Я выполняю кластеризацию DBSCAN на python. Я хочу добиться адаптивного способа возврата количества кластеров путем самостоятельного вычисления его параметров eps и Minpts. Ниже приведен мой код.

 import math
import copy
import numpy as np
import pandas as pd
from sklearn.cluster import DBSCAN


def loadDataSet(fileName, splitChar='t'):

    dataSet = []
    with open(fileName) as fr:
        for line in fr.readlines():
            curline = line.strip().split(splitChar)
            fltline = list(map(float, curline))
            dataSet.append(fltline)
    return dataSet


def dist(a,b):

    return math.sqrt(math.pow(a[0]-b[0],2)   math.pow(a[1]-b[1],2))


def returnDk(matrix,k):

    Dk = []
    for i in range(len(matrix)):
        Dk.append(matrix[i][k])
    return Dk


def returnDkAverage(Dk):

    sum = 0
    for i in range(len(Dk)):
        sum = sum   Dk[i]
    return sum/len(Dk)


def CalculateDistMatrix(dataset):

    DistMatrix = [[0 for j in range(len(dataset))] for i in range(len(dataset))]
    for i in range(len(dataset)):
        for j in range(len(dataset)):
            DistMatrix[i][j] = dist(dataset[i], dataset[j])
    return DistMatrix


def returnEpsCandidate(dataSet):

    DistMatrix = CalculateDistMatrix(dataSet)
    tmp_matrix = copy.deepcopy(DistMatrix)
    for i in range(len(tmp_matrix)):
        tmp_matrix[i].sort()
    EpsCandidate = []
    for k in range(1,len(dataSet)):
        Dk = returnDk(tmp_matrix,k)
        DkAverage = returnDkAverage(Dk)
        EpsCandidate.append(DkAverage)
    return EpsCandidate


def returnMinptsCandidate(DistMatrix,EpsCandidate):

    MinptsCandidate = []
    for k in range(len(EpsCandidate)):
        tmp_eps = EpsCandidate[k]
        tmp_count = 0
        for i in range(len(DistMatrix)):
            for j in range(len(DistMatrix[i])):
                if DistMatrix[i][j] <= tmp_eps:
                    tmp_count = tmp_count   1
        MinptsCandidate.append(tmp_count/len(dataSet))
    return MinptsCandidate


def returnClusterNumberList(dataset,EpsCandidate,MinptsCandidate):

    np_dataset = np.array(dataset)
    ClusterNumberList = []
    for i in range(len(EpsCandidate)):
        clustering = DBSCAN(eps= EpsCandidate[i],min_samples= MinptsCandidate[i]).fit(np_dataset)
        num_clustering = max(clustering.labels_)
        ClusterNumberList.append(num_clustering)
    return ClusterNumberList

if __name__ == '__main__':
    data = pd.read_csv('/Users/Desktop/Mic/recorder_test1/New folder/MFCCresultsforclustering/MFCCresultsforclustering.csv')
    dataSet = data.iloc[:,0:13].values
    EpsCandidate = returnEpsCandidate(dataSet)
    DistMatrix = CalculateDistMatrix(dataSet)
    MinptsCandidate = returnMinptsCandidate(DistMatrix,EpsCandidate)
    ClusterNumberList = returnClusterNumberList(dataSet,EpsCandidate,MinptsCandidate)
    print(EpsCandidate)
    print(MinptsCandidate)
    print('cluster number list is')
    print(ClusterNumberList)  
  

Однако выходные данные с набором загружаемых данных — это все [-1] s. Мне интересно, где ошибка. Я подхожу для этого общего направления? Если нет, то как я могу добиться адаптивной кластеризации DBSCAN?

Комментарии:

1. Я бы посоветовал вам вместо этого использовать HDBSCAN. Он быстрее обучается и дает довольно хорошие результаты. hdbscan.readthedocs.io/en/latest/index.html

2. @FarhoodET. Для HDBSCAN, я думаю, нам все еще нужно установить значения epsilon и MinSample. Чего я пытаюсь достичь в приведенном выше примере, так это адаптивной установки значений, которые не обязательно должны быть предопределены.

3. HDBSCAN не так чувствителен к этим значениям, как DBSCAN к ним. В ссылке на API четко указано, что: «Выполняет DBSCAN с различными значениями epsilon и интегрирует результат, чтобы найти кластеризацию, которая обеспечивает наилучшую стабильность по сравнению с epsilon». hdbscan.readthedocs.io/en/latest/api.html