erstellen Sie eine symmetrische matrix aus einer paarweisen Liste von python für clustering scikit, DBSCAN

Mein Ziel ist die Durchführung von clustering mit DBSCAN von scikit mit einem vorausberechneten ähnlichkeit matrix.
Ich habe eine Liste mit Funktionen. Ich mache eine paarweise zu erzeugen einzigartige Paare für die Liste und eine Funktion, die berechnet die ähnlichkeit zwischen Paaren. Jetzt möchte ich, um es zu transformieren, um eine symmetrische matrix, die verwendet werden können als eine Eingabe für das clustering-Algorithmus.
Ich denke, groupby kann hilfreich sein, aber ich bin mir nicht sicher wie Sie gehen über es. Hier ist ein Beispielcode, enthält eine Liste von Paaren mit Abstand Messen.Das id-Feld in der original-Liste ist der eindeutige Zeilenbezeichner.

def add_similarity(listdict):
    random.seed(10)
    newlistdist=[]
    for tup_dict in listdict:
        newdict={}
        tup0=tup_dict[0]
        tup1=tup_dict[1]
        for key,value in tup0.items():
            newdict[key +"_1"]=value
        for key,value in tup1.items():
            newdict[key+"_2"]=value 
        newdict["similarity"]=random.random()      
        newlistdist.append(newdict)                   
    return newlistdist


def generatesymm():
    listdict =[{'feature1': 4, 'feature2':2,"id": 100},{'feature1': 3, 'feature2': 2,"id":200},{'feature1': 4, 'feature2':2,"id": 300}]
    pairs=list(itertools.combinations(listdict, 2) )
    newlistdict=add_similarity(pairs)

Wenn ich diesen code ausführen dieser gibt

    [{'id_2': 200, 'feature1_2': 3, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.571, 'id_1': 100},     


{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.42, 'id_1': 100},   


{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 3, 'similarity': 0.578, 'id_1': 200}]

Den Ausgang brauche ich

          100       200       300


100        1         0.571      0.42  


200        0.571      1          0.578


300        0.428      0.578       1
  • Wie wäre es mit einem for – Schleife und speichern Sie den Wert einmal in [x,y] ad oncein [y,x]?
  • Sie tun dies mit einer for-Schleife ist nicht wirklich rentabel mit großen Matrizen. Sie werden wahrscheinlich ausführen in den Speicher Probleme.
  • Die Speicherprobleme sind nicht mit, ob Sie Schleifen oder nicht. Vorausberechnete matrix-Ansätze immer skaliert schlecht, aber das ist seine Forderung.
InformationsquelleAutor AMisra | 2016-01-30



One Reply
  1. 2

    Es ist mir nicht klar, wo id_3 kommt, aber unten ist ein Weg, um Ihre dataframe. Der trick ist die Verwendung von numpy, um index in die oberen und unteren dreieckigen Teile der matrix.

    In [679]:
    import numpy as np
    import pandas as pd
    similarities = [x["similarity"] for x in newlistdict]
    names = ['id_'+str(x) for x in range(1,4)]
    n = len(similarities)
    iuu = np.mask_indices(3, np.triu, 1)
    iul = np.mask_indices(3, np.tril, -1)
    mat = np.eye(n)
    mat[iuu] = similarities
    mat[iul] = similarities
    df = pd.DataFrame(mat,columns=names)
    df.index = names
    df
    
    Out[679]:
            id_1        id_2        id_3
    id_1    1.000000    0.896082    0.897818
    id_2    0.896082    1.000000    0.186298
    id_3    0.897818    0.186298    1.000000

    (Die Werte unterscheiden sich von Ihrer Frage, denn ich weiß nicht, die zufällige Streuung, die Sie verwendet.)

    • Das id-Feld in der original-Liste ( vor pairwise) enthält die eindeutige id eines Datensatzes. Nach paarweise, jede Zeile ist eindeutig durch die Werte in der colnames id_1, id_2. Endlich [id_1][id_3] sollte ähnlichkeit mit dem Wert für die Datensätze mit id=1 und id=3. Wenn die ursprüngliche Liste hatte 5 Datensätze paarweise gibt 10 Kombinationen. Matrix ist 10*10, wo die row-und col-Namen entsprechen, eindeutige Werte der original-id-Feld.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.