Grupowanie długiej listy ciągów (słów) w grupy podobieństwa

31

Mam pod ręką następujący problem: Mam bardzo długą listę słów, ewentualnie imion, nazwisk itp. Muszę utworzyć listę słów w taki sposób, aby podobne słowa, na przykład słowa o podobnej odległości edycji (Levenshtein) pojawiły się w ten sam klaster. Na przykład „algorytm” i „alogrithm” powinny mieć duże szanse na pojawienie się w tym samym klastrze.

Doskonale zdaję sobie sprawę z klasycznych, nieobjętych nadzorem metod grupowania, takich jak grupowanie k-średnich, grupowanie EM w literaturze Rozpoznawanie wzorców. Problem polega na tym, że metody te działają na punktach znajdujących się w przestrzeni wektorowej. Mam tutaj pod ręką słowa strun. Wydaje się, że zgodnie z moimi dotychczasowymi badaniami na pytanie, jak reprezentować ciągi w cyfrowej przestrzeni wektorowej i obliczyć „środki” klastrów ciągów, nie uzyskano wystarczającej odpowiedzi. Naiwnym podejściem do ataku na ten problem byłoby połączenie grupowania k-średnich z odległością Levenshteina, ale nadal pozostaje pytanie „jak reprezentować” oznacza „łańcuchy znaków”? Istnieje waga nazywana wagą TF-IDF, ale wydaje się, że jest ona głównie związana z obszarem klastrowania „dokumentu tekstowego”, a nie zgrupowaniem pojedynczych słów. http://pike.psu.edu/cleandb06/papers/CameraReady_120.pdf

Moje poszukiwania w tej dziedzinie wciąż trwają, ale chciałem też stąd czerpać pomysły. Co byś polecił w tym przypadku, czy ktoś jest świadomy metod tego rodzaju problemów?

Ufuk Can Bicici
źródło
1
Dowiedziałem się o istnieniu wariantu k-średnich o nazwie „K-medoidy”. en.wikipedia.org/wiki/K-medoids Nie działa przy L2 odległość euklidesowa i nie wymaga obliczania średnich. Wykorzystuje punkt danych najbliższy innym punktom w klastrze jako „medoid”.
Ufuk Can Bicici
1
It seems that there are some special string clustering algorithms. Jeśli pochodzisz z pola eksploracji tekstu, a nie statystyki / analizy danych, to stwierdzenie jest uzasadnione. Jeśli jednak poznasz gałąź klastrowania, ponieważ okaże się, że nie ma „specjalnych” algorytmów dla danych łańcuchowych. „Specjalny” to sposób wstępnego przetwarzania takich danych przed wprowadzeniem ich do analizy skupień.
ttnphns
powiązane: stackoverflow.com/questions/21511801/…
Andre Holzner
Zwróć uwagę na różnicę między Propagacją powinowactwa a klastrowaniem K-średnich i jak wpłynie to na czas obliczeń. quora.com/…
Gabriel Alon,

Odpowiedzi:

37

Rekomendacja Seconding @ mican dotycząca propagacji powinowactwa .

Z pracy: L Frey, Brendan J. i Delbert Dueck. „Grupowanie poprzez przekazywanie wiadomości między punktami danych”. science 315.5814 (2007): 972–976. .

Jest bardzo łatwy w użyciu za pośrednictwem wielu pakietów. Działa na wszystkim, co można zdefiniować podobieństwem par. Co możesz uzyskać, mnożąc odległość Levenshteina przez -1.

Rzuciłem razem szybki przykład, używając pierwszego akapitu twojego pytania jako danych wejściowych. W Pythonie 3:

import numpy as np
import sklearn.cluster
import distance

words = "YOUR WORDS HERE".split(" ") #Replace this line
words = np.asarray(words) #So that indexing with a list will work
lev_similarity = -1*np.array([[distance.levenshtein(w1,w2) for w1 in words] for w2 in words])

affprop = sklearn.cluster.AffinityPropagation(affinity="precomputed", damping=0.5)
affprop.fit(lev_similarity)
for cluster_id in np.unique(affprop.labels_):
    exemplar = words[affprop.cluster_centers_indices_[cluster_id]]
    cluster = np.unique(words[np.nonzero(affprop.labels_==cluster_id)])
    cluster_str = ", ".join(cluster)
    print(" - *%s:* %s" % (exemplar, cluster_str))

Dane wyjściowe były (przykłady kursywą po lewej stronie klastra, których są przykładem):

  • mieć: szanse, edytować, rozdawać, mieć, wysokie
  • następujące: następujące
  • problem: problem
  • I: I, a, at, etc, in, list, of
  • ewentualnie: ewentualnie
  • klaster: klaster
  • słowo: Bo i przez długi czas trzeba, bardzo, słowo, słowa
  • podobne: podobne
  • Levenshtein: Levenshtein
  • odległość: odległość
  • the: that, the, this, to with
  • same: przykład, lista, nazwiska, takie same, nazwiska
  • algorytm: algorytm, alogrithm
  • pojawiają się: pojawiają się, pojawiają się

Uruchomienie go na liście 50 losowych imion :

  • Diane: Deana, Diane, Dionne, Gerald, Irina, Lisette, Minna, Nicki, Ricki
  • Jani: Clair, Jani, Jason, Jc, Kimi, Lang, Marcus, Maxima, Randi, Raul
  • Verline: Destiny, Kellye, Marylin, Mercedes, Sterling, Verline
  • Glenn: Elenor, Glenn, Gwenda
  • Armandina: Armandina, Augustina
  • Shiela: Ahmed, Estella, Milissa, Shiela, Thresa, Wynell
  • Laureen: Jesień, Haydee, Laureen, Lauren
  • Alberto: Albertha, Alberto, Robert
  • Wiedza: Ammie, Doreen, Eura, Josef, Lore, Lori, Porter

Wygląda mi całkiem nieźle (to była zabawa).

Lyndon White
źródło
czy można mieć ten sam algorytm przy użyciu tylko sklearn? lub użyć scipy.spatial.distance z hammingiem? Jaka jest korzyść ze stosowania lewenshtein? Chyba będę musiał spróbować użyć tego pytania: stackoverflow.com/questions/4588541/...
pierre
1
@pierre Levenshtein jest tym, co nazwałbym „odległością sprawdzania pisowni”, jest to dobry wskaźnik prawdopodobieństwa błędu w pisowni ludzkiej. Damerau Levenshtein może być jeszcze lepszy. Nie wiem, czy Odległość Hamminga jest zdefiniowana dla łańcuchów o niejednej długości. Pozwala tylko na zamianę, a nie wstawianie. ustalenie, jak najbardziej racjonalnie wypełnić / przyciąć sznurek, jest prawie tak samo trudne, jak obliczenie odległości Levenshteina. Czy powinieneś zacząć / przycinać start? Koniec? Niektórzy ze środka?
Lyndon White
Jeśli naprawdę chcesz uniknąć zależności od odległości. możesz użyć implementacji kodu Rossetta
Lyndon White
czytając en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance widzę, w jaki sposób transpozycja może mieć znaczenie, szczególnie w przypadku literówek, a python ma dla niego zupełnie nowy pakiet. Widzę, jak mogę tego użyć na liście słów i uzyskać „najbliższe”, ale może nie być najważniejsze. Muszę pobrać swoją listę i sprawdzić za pomocą tf-idf. Fajne, dziękuję
pierre
1
@dduhaime prawie na pewno. Ogólnie rzecz biorąc, Propagacja powinowactwa działa dla niesymatycznych percepcji, ale ponieważ jest to symetryczny, śmiało. Jestem pewien, że coś w SciPy ma trójkątny typ matrycy, który uchodzi za kompletną matrycę. Zbyt długo byłem w krainie Julii-Lang i nie pamiętam, jak to się dzieje w Pythonie. (W Julii użyjesz Symmetric)
Lyndon White
5

Użyj algorytmów klastrowania wykresów, takich jak klastrowanie Louvaina, klastrowanie wyszukiwania z ograniczonym sąsiedztwem (RNSC), klastrowanie propagacji powinowactwa (APC) lub algorytm klastra Markowa (MCL).

micans
źródło
Co ze znalezioną metodą K-medoidów? Muszę jak najszybciej wdrożyć to rozwiązanie, więc wydawało mi się to dobrym rozwiązaniem. Zdaję sobie sprawę z istnienia tych metod opartych na grafach, ale obawiam się, że nie stać mnie na czas na ich zrozumienie i wdrożenie.
Ufuk Can Bicici
Dla wszystkich z nich dostępne jest oprogramowanie z dość nieograniczającymi umowami licencyjnymi, takimi jak GNU GPL. Nie jestem wielkim fanem algorytmu typu k-mediody, głównie ze względu na parametr k, ale naturalnie to zależy od ciebie. Jeśli potrzebujesz implementacji wewnętrznej, myślę, że APC i MCL są prawdopodobnie najłatwiejsze do wdrożenia. Jeśli miałbyś to zrobić, wypróbuj je najpierw.
micans
2

Możesz wypróbować model przestrzeni wektorowej z n-gramami słów jako pozycji przestrzeni wektorowej. Myślę, że w tym przypadku musiałbyś użyć miary podobnej do podobieństwa cosinus zamiast edytować odległość.

pokój z zasięgiem
źródło