Krótkie wprowadzenie do metryki odległości i skalowania wielokierunkowego
Na początek załóżmy, że mamy bardzo prosty zestaw danych, w którym czterech klientów oceniło sześć produktów. Każdy klient został poproszony o nadanie każdemu produktowi kciuka w górę lub kciuka w dół, ale mogłaby pominąć produkt, gdyby nie miała o nim opinii. Istnieje wiele systemów oceny, które działają w ten sposób, w tym Pandora i YouTube. Korzystając z tych danych ocen, chcielibyśmy zmierzyć, jak podobni są klienci. W tym prostym przykładzie skonfigurujemy macierz 4 × 6, w której wiersze reprezentują klientów, a kolumny reprezentują produkty. Wypełnimy tę macierz symulowanymi ocenami, losowo wybierając kciuk w górę (1), kciuk w dół (–1) lub pomiń (0) dla każdej pary klientów / produktów. Aby to zrobić, użyjemy funkcji próbki, która pozwoli nam losowo wybrać wartości z wektora c (1, 0, -1) sześć razy z zamianą. Ponieważ będziemy uzyskiwać dostęp do generatora liczb losowych R w celu symulacji danych, ważne jest, aby ustawić ziarno dla generatora na tę samą wartość, której użyliśmy, aby Twoje wyniki były równe tym pokazanym w przykładach. Aby ustawić ziarno, wywołamy set.seed (), aby ustawić ziarno generatora na numer 851982.
set.seed(851982)
ex.matrix <- matrix(sample(c(-1,0,1), 24, replace=TRUE), nrow=4, ncol=6)
row.names(ex.matrix) <- c(‘A’,’B’,’C’,’D’)
colnames(ex.matrix) <- c(‘P1′,’P2′,’P3′,’P4′,’P5′,’P6’)
Ten kod utworzy macierz 4 × 6, w której każdy wpis odpowiada ocenie użytkowników wierszy produktu kolumny. Używamy funkcji row.names i colnames tylko po to, aby zachować przejrzystość w tym przykładzie: klienci A – D i produkty 1–6. Kiedy sprawdzamy matrycę, możemy dokładnie zobaczyć, jak wygląda nasz zestaw danych zabawek. Na przykład klient A dał kciuki w dół produktom 2 i 3 i nie ocenił żadnych innych produktów. Z drugiej strony klient B kciuk w dół do produktu 1, ale kciuk w górę do produktów 3, 4 i 5. Teraz musimy użyć tych różnic, aby wygenerować wskaźnik odległości między wszystkimi klientami.
ex.matrix
P1 P2 P3 P4 P5 P6
A 0 -1 0 -1 0 0
B -1 0 1 1 1 0
C 0 0 0 1 -1 1
D 1 0 1 -1 0 0
Pierwszym krokiem do zebrania tych danych i wygenerowania metryki odległości jest podsumowanie ocen klientów dla każdego produktu, ponieważ odnoszą się one do wszystkich innych klientów, to znaczy nie tylko do produktów w obecnej formie. Innym sposobem myślenia o tym jest to, że musimy przekonwertować macierz N-by-M na macierz N-by-N, w której elementy nowej macierzy zapewniają podsumowanie relacji między użytkownikami na podstawie oceny produktu. Jednym ze sposobów jest pomnożenie naszej macierzy przez jej transpozycję. Efektem tego mnożenia jest obliczenie korelacji między każdą parą kolumn w oryginalnej macierzy. Transponowanie i mnożenie macierzy jest czymś, czego można się nauczyć w pierwszych tygodniach zajęć z dyskretnej matematyki lub algebry liniowej. W zależności od temperamentu instruktora być może staranne wykonanie tych transformacji odbywało się ręcznie. Na szczęście R bardzo chętnie wykonuje te transformacje. Poniżej przedstawiamy krótkie wprowadzenie do operacji macierzowych i ich wykorzystania w konstruowaniu metryki odległości dla danych ocen. Jeśli znasz już operacje na macierzach, możesz pominąć ten rozdział. Transpozycja macierzy odwraca macierz, dzięki czemu wiersze stają się kolumnami, a kolumny – rzędami. Wizualnie transpozycja obraca matrycę o 90 stopni w prawo, a następnie odwraca ją w pionie. Na przykład w poprzednim bloku kodu widzimy naszą macierz oceny według klienta, np. Matrycę, ale w następnym bloku kodu używamy funkcji t do jej transpozycji. Mamy teraz macierz oceny według klienta:
t (ex.matrix)
A B C D
P1 0 -1 0 1
P2 -1 0 0 0
P3 0 1 0 1
P4 -1 1 1 -1
P5 0 1 -1 0
P6 0 0 1 0
Mnożenie macierzy jest nieco bardziej skomplikowane, ale wymaga jedynie podstawowej arytmetyki. Aby pomnożyć dwie macierze, zapętlamy rzędy pierwszej macierzy i kolumny drugiej macierzy. Dla każdej pary wiersz-kolumna mnożymy każdą parę wpisów i sumujemy je razem. Omówimy krótki przykład za sekundę, ale jest kilka ważnych rzeczy, o których należy pamiętać podczas mnożenia macierzy. Po pierwsze, ponieważ mnożymy elementy rzędu pierwszej macierzy przez elementy kolumny drugiej, wymiary te muszą się zgadzać w dwóch macierzach. W naszym przypadku my nie możemy po prostu pomnożyć np. macierzy przez macierz 2 × 2; jak zobaczymy, arytmetyka nie zadziałałaby. Jako taki, wynik mnożenia macierzy zawsze będzie miał taką samą liczbę wierszy jak pierwsza macierz i taką samą liczbę kolumn jak druga macierz.
Bezpośrednią konsekwencją tego jest to, że porządek ma znaczenie przy mnożeniu macierzy. W naszym przypadku chcemy macierzy, która podsumowuje różnice między klientami, dlatego mnożymy naszą macierz klient po przeglądzie przez jej transpozycję, aby uzyskać macierz klient po kliencie jako produkt. Gdybyśmy zrobili coś odwrotnego, tj. mnożąc macierz oceny według klienta, mielibyśmy różnice między recenzjami. Może to być interesujące w innej sytuacji, ale w tej chwili nie jest przydatne. Na rysunku
omawiamy sposób mnożenia macierzy. W lewym górnym rogu znajduje się ex.matrix, a w prawym górnym rogu jest transpozycja. Są to dwie macierze, które zamierzamy pomnożyć i pomnożymy je w tej kolejności. Jako przykład procesu mnożenia wyróżniliśmy wiersz A w przykładowej macierzy i kolumnę B w jego transpozycji. Bezpośrednio pod macierzami pokazujemy dokładnie, jak przebiega arytmetyka mnożenia macierzy. Jest to tak proste, jak pobranie elementu wiersza pierwszej macierzy i pomnożenie go przez odpowiedni element kolumny z drugiej macierzy. Następnie bierzesz te produkty i sumujesz je. Jak widać, w wynikowej macierzy klient-klient element A, B wynosi –1, co jest wynikiem sumowania wiersz po kolumnie.
ex.mult <- ex.matrix %*% t(ex.matrix)
ex.mult
A B C D
A 2 -1 -1 1
B -1 4 0 -1
C -1 0 3 -1
D 1 -1 -1 3
Wprowadziliśmy również pewną notację R na powyższym rysunku, która jest powtarzana w poprzednim bloku kodu, który wytwarza mnożenie macierzy. W R używasz operatora% *% do mnożenia macierzy. Interpretacja nowej matrycy jest dość prosta. Ponieważ zastosowaliśmy schemat kodowania 1, -1 i 0, wartości nie przekątne podsumowują ich ogólną zgodność (wartość dodatnia) lub brak zgody (wartość ujemna) w odniesieniu do recenzji produktów, biorąc pod uwagę te produkty, które obaj ocenili, tj. Niezerowe wpisy . Im bardziej pozytywny jest element nie przekątny, tym więcej zgodności, i im bardziej negatywny, tym mniej zgodności. Ponieważ wpisy są losowe, rozbieżność wśród klientów jest bardzo niewielka, a żadna wartość nie przyjmuje wartości większej niż 1 lub mniejszej niż –1. Wartości ukośne przedstawiają po prostu liczbę produktów, które ocenił każdy użytkownik. Mamy teraz dość przydatne podsumowanie różnic między użytkownikami. Na przykład klienci A i D obrócili produkt 4 kciukiem w dół; jednak klient D lubił produkty 1 i 3, podczas gdy klient A ich nie sprawdzał. Tak więc dla produktów dla których mamy informacje, możemy powiedzieć, że są one podobne, a zatem mają wartość 1 odpowiadającą ich relacji. Niestety jest to bardzo ograniczające, ponieważ możemy jedynie powiedzieć coś o nakładaniu się. Wolelibyśmy metodę ekstrapolacji tych różnic na bogatszą reprezentację. W tym celu wykorzystamy koncepcję odległości euklidesowej w przestrzeni wielowymiarowej. W jednym, dwóch lub trzech wymiarach odległość euklidesowa jest formalizacją naszych intuicji dotyczących odległości. Aby obliczyć odległość euklidesową między dwoma punktami w przestrzeni, mierzymy najkrótszą bezpośrednią ścieżkę między nimi. W naszym przykładzie chcemy obliczyć odległość euklidesową wśród wszystkich klientów w oparciu o miary ogólnych podobieństw i różnic określonych przez mnożenie macierzy. Aby to zrobić, będziemy traktować oceny każdego klienta jako wektor. Aby porównać klienta A z klientem B, możemy odjąć wektory, wyrównać różnice, zsumować je, a następnie przyjąć pierwiastek kwadratowy. To daje nam odległość euklidesową między ocenami klienta A a ocenami klienta B.
Możemy to zrobić „ręcznie” w języku R, używając funkcji sum i sqrt. W poniższym bloku kodu pokazujemy to obliczenie dla klientów A i D, które wynosi około 2.236. Na szczęście obliczenie całej pary odległości między rzędami macierzy jest tak powszechną operacją, że R ma funkcję podstawową zwaną dist, która robi dokładnie to i zwraca macierz odległości, którą nazywamy macierzą odległości. Funkcja dist może wykorzystywać kilka różnych mierników odległości do utworzenia macierzy odległości, ale będziemy trzymać się odległości euklidesowej, która jest domyślna.
sqrt(sum((ex.mult[1,]-ex.mult[4,])^2))
[1] 2.236068
ex.dist <- dist(ex.mult)
ex.dist
A B C
B 6.244998
C 5.477226 5.000000
D 2.236068 6.782330 6.082763
Zmienna ex.dist przechowuje teraz naszą macierz odległości. Jak widać z tego bloku kodu, macierz ta jest w rzeczywistości tylko dolnym trójkątem całej macierzy odległości. Bardzo często pokazywany jest tylko dolny trójkąt dla macierzy odległości, ponieważ macierz odległości musi być symetryczna, ponieważ odległość między rzędem X i rzędem Y jest równa odległości między rzędem Y i rzędem X. Pokazanie górnego trójkąta macierzy odległości jest zatem zbędne i zasadniczo nie jest wykonywane. Możesz jednak zastąpić to ustawienie domyślne podczas wywoływania funkcji dist, ustawiając wartość górną = PRAWDA.
Jak widzimy na podstawie wartości w dolnym trójkącie np. odległości, klienci A i D są najbliżsi, a klienci D i B są najdalsi. Mamy teraz wyraźniejsze poczucie podobieństw wśród użytkowników na podstawie ich recenzji produktów; byłoby jednak lepiej, gdybyśmy mogli wizualnie wyczuć te różnice. W tym miejscu MDS można wykorzystać do stworzenia układu przestrzennego naszych klientów na podstawie właśnie obliczonych odległości. MDS to zestaw technik statystycznych używanych do wizualnego zobrazowania podobieństw i różnic z zestawu odległości. W przypadku klasycznego MDS, którego użyjemy w tym rozdziale, proces przyjmuje macierz odległości, która określa odległość między każdą parą punktów w naszym zbiorze danych i zwraca zestaw współrzędnych dla tych dwóch punktów, który aproksymuje te odległości. Powodem, dla którego musimy stworzyć przybliżenie, jest to, że znalezienie punktów w dwóch wymiarach, które są oddzielone określonym zestawem odległości, może nie być możliwe. Na przykład nie można znaleźć czterech punktów w dwóch wymiarach, wszystkie w odległości 1 od siebie. (Przekonać się o tej notatce, że trzy punkty, które wszystkie znajdują się w odległości 1 od siebie, są wierzchołkami trójkąta. Przekonaj się, że nie ma sposobu, aby znaleźć inny punkt, który jest w odległości 1 od wszystkich trzech wskazuje na ten trójkąt.) Klasyczny MDS wykorzystuje określone przybliżenie do macierzy odległości, a zatem jest kolejnym przykładem algorytmu optymalizacji wykorzystywanego do uczenia maszynowego. Oczywiście algorytm aproksymacji leżący u podstaw klasycznego MDS można zastosować w trzech lub czterech wymiarach, ale naszym celem jest uzyskanie reprezentacji naszych danych, która jest łatwa do wizualizacji.
We wszystkich przypadkach będziemy używać MDS do skalowania danych na dwa wymiary Jest to najczęstszy sposób korzystania z MDS, ponieważ to pozwala na bardzo proste wizualizacje danych na wykresie współrzędnych. Jednak użycie MDS do skalowania danych do wyższych wymiarów jest całkowicie uzasadnione. Na przykład trójwymiarowa wizualizacja może ujawnić różne poziomy grupowania obserwacji podczas przechodzenia punktów do trzeciego wymiaru.
Klasyczna procedura MDS jest częścią podstawowych funkcji R, takich jak cmdscale, a jej jedynym wymaganym wejściem jest macierz odległości, taka jak np. Odległość Domyślnie cmdscale obliczy MDS w dwóch wymiarach, ale można to ustawić za pomocą parametru k. Interesuje nas tylko skalowanie naszych danych odległości do dwóch wymiarów, więc w poniższym bloku kodu używamy ustawień domyślnych i wykreślamy wyniki przy użyciu podstawowej grafiki R.
ex.mds <- cmdscale(ex.dist)
plot(ex.mds, type=’n’)
text(ex.mds, c(‘A’,’B’,’C’,’D’))
Na rysunku
widzimy, że klienci A i D grupują się razem w środku działki. Jednak klienci B i C wcale się nie klastrują. Na podstawie naszych danych widzimy, że klienci A i D mają nieco podobne upodobania, ale musielibyśmy uzyskać znacznie więcej danych i / lub klientów, zanim moglibyśmy mieć nadzieję na zrozumienie sposobu, w jaki klienci klastrują B i C. Ważne jest również, aby zauważyć, że chociaż możemy zobaczyć, jak skupiają się A i D, a także, jak B i C nie, nie możemy powiedzieć nic konkretnego o tym, jak interpretować te odległości. Oznacza to, że wiemy, że A i D są bardziej podobne ze względu na ich bliskość w płaszczyźnie współrzędnych, ale nie możemy używać liczb i odległości między nimi, aby zinterpretować, jak są podobni, ani jak różnią się od B lub C. Dokładna odległość numeryczna wytworzona przez MDS jest artefaktem algorytmu MDS i pozwala na bardzo ograniczoną interpretację merytoryczną. W poniższej sekcji omówimy studium przypadku podobne do przykładu z zabawką, którego właśnie użyliśmy, ale teraz wykorzystamy prawdziwe dane z głosowań imiennych od Senatu USA.
Dane te są znacznie większe niż zbiór danych o zabawkach i wykorzystamy je, aby pokazać, jak członkowie Senatu Stanów Zjednoczonych gromadzą się podczas chronologicznych kongresów. W takim przypadku wykorzystamy te zapisy głosowań imiennych w Senacie do wygenerowania naszego wskaźnika odległości. Następnie użyjemy MDS do skupienia senatorów w dwóch wymiarach