średnie k || alias Scalable K-Means ++


12

Bahman Bahmani i in. wprowadzono k-średnich ||, która jest szybszą wersją k-średnich ++.

Inicjalizacja średnich k ||

Algorytm ten pochodzi ze strony 4 ich pracy , Bahmani, B., Moseley, B., Vattani, A., Kumar, R., i Vassilvitskii, S. (2012). Skalowalne k-średnie ++. Postępowanie z VLDB Endowment , 5 (7), 622-633.

Niestety nie rozumiem tych wymyślnych greckich liter, więc potrzebuję pomocy, aby zrozumieć, jak to działa. O ile rozumiem, ten algorytm jest ulepszoną wersją k-średnich ++ i wykorzystuje nadpróbkowanie, aby zmniejszyć liczbę iteracji: k-średnich ++ musi iterować razy, gdzie jest liczbą pożądanych klastrów.kk

Dostałem bardzo dobre wyjaśnienie poprzez konkretny przykład działania k-średnich ++, więc użyję tego samego przykładu ponownie.

Przykład

Mam następujący zestaw danych:

(7,1), (3,4), (1,5), (5,8), (1,3), (7,8), (8,2), (5,9), (8 , 0)

k=3 (liczba pożądanych klastrów)

=2 (współczynnik nadpróbkowania)

Przykładowy zestaw danych dla średnich k ||

Zacząłem ją obliczać, ale nie jestem pewien, czy wszystko dobrze zrozumiałem i nie mam pojęcia o krokach 2, 4 lub 5.

  • Krok 1: próbkuj punkt losowo równomiernie zCX

    Powiedzmy, że pierwszym centroidem jest (tak samo jak w k-średnich ++)(8,0)

  • Krok 2:ψϕX(C)

    brak pomysłu

  • Krok 3:

    • d2(x,C)=[2,41,74,73,58,65,4,90]

      Obliczamy kwadratowe odległości do najbliższego środka każdego punktu. W tym przypadku do tej pory mamy tylko jedno centrum .(8,0)

    • d2(x,C)=[4,81,148,146,116,130,8,180]

      (Ponieważ w tym przypadku.)=2

    • cumulative d2(x,C)=[4,85,233,379,495,625,633,813]

      Wybierz liczby losowe w przedziale . Powiedzmy, że i . Obejmują one przedziały i które odpowiadają odpowiednio czwartej i ósmej pozycji.=2[0,813)246.90659.42[379,495)[633,813)

    • Powtórz to razy, ale co to jest (obliczone w kroku 2) w tym przypadku? O(logψ)ψ

  • Krok 4: Dla ustaw aby była liczbą punktów w bliższą niż jakikolwiek inny punkt w .xCwxXxC
  • Krok 5: Ponownie skup ważone punkty w na klastrów.Ck

Każda pomoc w ogóle lub w tym konkretnym przykładzie byłaby świetna.

Odpowiedzi:


10

punkty danych: (7,1), (3,4), (1,5), (5,8), (1,3), (7,8), (8,2), (5,9) , (8,0)

l = 2 // współczynnik nadpróbkowania

k = 3 // nie. pożądanych klastrów

Krok 1:

Załóżmy, że pierwszym centroidem jest to . C{c1}={(8,0)}X={x1,x2,x3,x4,x5,x6,x7,x8}={(7,1),(3,4),(1,5),(5,8),(1,3),(7,8),(8,2),(5,9)}

Krok 2:

ϕX(C) to suma wszystkich najmniejszych 2-normowych odległości (odległość euklidesowa) od wszystkich punktów ze zbioru do wszystkich punktów z . Innymi słowy, dla każdego punktu znaleźć odległość do najbliższego punktu w w końcowej obliczeniowych suma wszystkich tych minimalnych odległościach, po jednym dla każdego punktu .XCXCX

Oznacz za pomocą jako odległość od do najbliższego punktu w . Mamy wtedy .dC2(xi)xiCψ=i=1ndC2(xi)

W kroku 2 zawiera pojedynczy element (patrz krok 1), a jest zbiorem wszystkich elementów. Zatem w tym kroku to po prostu odległość między punktem w i . Zatem .CXdC2(xi)Cxiϕ=i=1n||xic||2

ψ=i=1nd2(xi,c1)=1.41+6.4+8.6+8.54+7.61+8.06+2+9.4=52.128 log(ψ)=log(52.128)=3.95=4(rounded)

Należy jednak pamiętać, że w kroku 3 stosowana jest ogólna formuła, ponieważ będzie zawierał więcej niż jeden punkt.C

Krok 3:

W pętli wykonywane w uprzednio obliczonej.log(ψ)

Rysunki nie są takie, jak zrozumiałeś. Rysunki są niezależne, co oznacza, że będzie wykonywać losowanie dla każdego punktu . Zatem dla każdego punktu w , oznaczonego jako , oblicz prawdopodobieństwo z . Tutaj masz współczynnik podany jako parametr, to odległość do najbliższego centrum, a wyjaśniono w kroku 2.XXxipx=ld2(x,C)/ϕX(C)ld2(x,C)ϕX(C)

Algorytm jest po prostu:

  • iteruj w aby znaleźć wszystkieXxi
  • dla każdego obliczeniaxipxi
  • wygeneruj jednolitą liczbę w , jeśli jest mniejsza niż wybierz ją, aby utworzyć[0,1]pxiC
  • po zakończeniu wszystkich losowań uwzględnij wybrane punkty z doCC

Zauważ, że na każdym kroku 3 wykonanym w iteracji (linia 3 oryginalnego algorytmu) spodziewasz się wybrać punktów z (można to łatwo pokazać, pisząc bezpośrednio wzór na oczekiwanie).lX

for(int i=0; i<4; i++) {

  // compute d2 for each x_i
  int[] psi = new int[X.size()];
  for(int i=0; i<X.size(); i++) {
    double min = Double.POSITIVE_INFINITY;
    for(int j=0; j<C.size(); j++) {
      if(min>d2(x[i],c[j])) min = norm2(x[i],c[j]);
    }
    psi[i]=min;
  }

  // compute psi
  double phi_c = 0;
  for(int i=0; i<X.size(); i++) phi_c += psi[i];

  // do the drawings
  for(int i=0; i<X.size(); i++) {
    double p_x = l*psi[i]/phi;
    if(p_x >= Random.nextDouble()) {
      C.add(x[i]);
      X.remove(x[i]);
    }
  }
}
// in the end we have C with all centroid candidates
return C;

Krok 4:

Prostym algorytmem jest utworzenie wektora o wielkości równej liczbie elementów w i zainicjowanie wszystkich jego wartości za pomocą . Teraz iteruj w (elementy nie wybrane jako centroidy), a dla każdego znajdź indeks najbliższego środka ciężkości (element z ) i zwiększ o . W końcu trzeba będzie wektor obliczone prawidłowo.wC0XxiXjCw[j]1w

double[] w = new double[C.size()]; // by default all are zero
for(int i=0; i<X.size(); i++) {
  double min = norm2(X[i], C[0]);
  double index = 0;
  for(int j=1; j<C.size(); j++) {
    if(min>norm2(X[i],C[j])) {
      min = norm2(X[i],C[j]);
      index = j;
    }
  }
  // we found the minimum index, so we increment corresp. weight
  w[index]++;
}

Krok 5:

Biorąc pod uwagę wagi obliczone w poprzednim kroku, postępujesz zgodnie z algorytmem kmeans ++, aby wybrać tylko punktów jako początkowe centroidy. W ten sposób wykonasz dla pętli, w każdej pętli wybierając pojedynczy element, losowany losowo z prawdopodobieństwem, że każdy element jest . Na każdym kroku wybierasz jeden element i usuwasz go z kandydatów, usuwając również odpowiadającą mu wagę.wkkp(i)=w(i)/j=1mwj

for(int k=0; k<K; k++) {
  // select one centroid from candidates, randomly, 
  // weighted by w
  // see kmeans++ and you first idea (which is wrong for step 3)
  ... 
}  

Wszystkie poprzednie kroki są kontynuowane, podobnie jak w przypadku kmeans ++, przy normalnym przepływie algorytmu klastrowania

Mam nadzieję, że teraz jest jaśniej.

[Później, później edytuj]

Znalazłem także prezentację autorów, w której nie można jednoznacznie stwierdzić, że przy każdej iteracji można wybrać wiele punktów. Prezentacja jest tutaj .

[Późniejsza edycja wydania @ pera]

Oczywiste jest, że zależy od danych, a podniesiony przez ciebie problem byłby prawdziwym problemem, gdyby algorytm był wykonywany na jednym hoście / maszynie / komputerze. Należy jednak pamiętać, że ten wariant klastrowania kmeans jest dedykowany dużym problemom i działa na systemach rozproszonych. Co więcej, autorzy w poniższych akapitach powyżej opisu algorytmu stwierdzają, co następuje:log(ψ)

Zauważ, że rozmiar jest znacznie mniejszy niż rozmiar wejściowy; przekierowanie można zatem wykonać szybko. Na przykład w MapReduce, ponieważ liczba centrów jest niewielka, można je wszystkie przypisać do pojedynczej maszyny, a dowolny algorytm przybliżenia (taki jak k-średnia ++) może zostać użyty do grupowania punktów w celu uzyskania k centrów. Implementacja algorytmu MapReduce 2 została omówiona w rozdziale 3.5. Chociaż nasz algorytm jest bardzo prosty i nadaje się do naturalnej równoległej implementacji (w rundach ), wyzwaniem jest wykazanie, że ma on możliwe do udowodnienia gwarancje.Clog(ψ)

Kolejną rzeczą do odnotowania jest następująca uwaga na tej samej stronie, która stwierdza:

W praktyce nasze wyniki eksperymentalne w rozdziale 5 pokazują, że wystarczy kilka rund, aby znaleźć dobre rozwiązanie.

Co oznacza, że ​​możesz uruchomić algorytm nie dla czasów , ale dla danego stałego czasu.log(ψ)


czy możesz rozszerzyć swoją odpowiedź o obliczenia dla mojego przykładu?
user1930254

Jestem programistą i myślę, że potrafię pisać to w kodzie szybciej niż tutaj :). Mam nadzieję, że to wyjaśnia algo.
rapaio

Czy możesz wyjaśnić, na czym polega pomysł z liczbą iteracji log (Ksi)? Nie rozumiem leżącego u podstaw pomysłu, wydaje się, że liczba iteracji będzie zależeć od zakresu wartości obiektów, co nie wydaje się rozsądne. Na przykład, jeśli obiekty mają wartości atrybutów około 1000, może to na przykład skutkować błędem około 1000, co oznacza, że ​​będą 3 iteracje. Z drugiej strony, jeśli wartości mieszczą się w zakresie 10, może to oznaczać, że błąd wynosi około 10, co skutkuje 1 iteracją. Czy liczba iteracji nie powinna zależeć od liczby obiektów?
Marko

@pera Aktualizuję odpowiedź, aby wyjaśnić podniesiony przez ciebie problem
rapaio

@rapaio Dziękuję za odpowiedź, już idę do rozwiązania, które określi liczbę iteracji na podstawie liczby medoidów. Gdzie x można zwiększyć, aby uzyskać lepszą inicjalizację kosztem kilku iteracji więcej. Czy wszystko w porządku, na podstawie drugiej części, którą podałeś? Dzięki jeszcze raz.
Marko,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.