17

Robię witrynę społeczności, która wymaga obliczenia podobieństwa między dowolnymi dwoma użytkownikami. Każdy użytkownik jest opisywany za pomocą następujących atrybutów:Sposoby obliczania podobieństwa

wiek, rodzaj skóry (tłusta, sucha), rodzaj włosów (długi, krótki, średni), styl życia (aktywny miłośnik zewnątrz, TV junky) i inne.

Czy ktoś może mi powiedzieć, jak rozwiązać ten problem lub wskazać mi jakieś zasoby?

+2

pokrewne: http://stackoverflow.com/questions/3007790/finding-the-closest-match/3007816#3007816 – Betamoo

Odpowiedz

2

Prawdopodobnie powinien spojrzeć na

Thes tematy e pozwoli Ci program rozpoznaje podobieństwa i klastrów w swojej kolekcji użytkowników i starają się dostosować do nich ...

Można wtedy znać różne ukryte wspólne grupy powiązanych użytkowników ... (tj użytkownikom zielone włosy zwykle nie lubią oglądać telewizję ..)

Jako radę, spróbuj użyć gotowych zaimplementowane narzędzia dla tej funkcji zamiast wdrażać go samodzielnie ...
Spójrz na Open Directory Data Mining Projects

3

Daj każdego atrybutu odpowiednią wagę i dodaj różnice między wartościami.

enum SkinType 
    Dry, Medium, Oily 

enum HairLength 
    Bald, Short, Medium, Long 

UserDifference(user1, user2) 
    total := 0 
    total += abs(user1.Age - user2.Age) * 0.1 
    total += abs((int)user1.Skin - (int)user2.Skin) * 0.5 
    total += abs((int)user1.Hair - (int)user2.Hair) * 0.8 
    # etc... 
    return total 

Jeśli naprawdę potrzebujesz podobieństwo zamiast różnicę korzystania 1/UserDifference(a, b)

0

Spójrz na algorytmy do obliczania różnicy srting. Jest bardzo podobny do tego, czego potrzebujesz. Przechowuj swoje atrybuty w postaci ciągu bitów i oblicz odległość między ciągami znaków.

14

Kolejny sposób obliczania (w R) wszystkich parach różnić (odległości) między obserwacjami w zbiorze danych. Oryginalne zmienne mogą być typu mieszanego. Obsługa nominalnych, porządkowych i (a) symetrycznych danych binarnych jest osiągnięta przy użyciu ogólnego współczynnika odmienności Gowera (Gower, J. C. (1971) Ogólny współczynnik podobieństwa i niektóre jego właściwości, Biometrics 27, 857-874). Aby uzyskać więcej sprawdzić this on page 47. Jeśli x zawiera kolumny tych typów danych, współczynnik Gower będzie używany jako metryka.

Na przykład

x1 <- factor(c(10, 12, 25, 14, 29)) 
x2 <- factor(c("oily", "dry", "dry", "dry", "oily")) 
x3 <- factor(c("medium", "short", "medium", "medium", "long")) 
x4 <- factor(c("active outdoor lover", "TV junky", "TV junky", "active outdoor lover", "TV junky")) 
x <- cbind(x1,x2,x3,x4) 

library(cluster) 
daisy(x, metric = "euclidean") 

dostaniesz:

Dissimilarities : 
     1  2  3  4 
2 2.000000       
3 3.316625 2.236068     
4 2.236068 1.732051 1.414214   
5 4.242641 3.741657 1.732051 2.645751 

Jeśli jesteś zainteresowany metody redukcji wymiarowości dla danych kategorycznych (również sposób, aby zorganizować zmienne do jednorodnych klastrów) Sprawdź this

+0

'„odległość Gower”jest wybrany przez metryczny„Gower "lub automatycznie, jeśli niektóre kolumny x nie są numeryczne' (? klaster :: daisy), więc nie musisz przekazywać' metryki' - tutaj jest to mylące. –

1

Trzy kroki w celu uzyskania prostej subiektywnej metryki dla różnicy między dwoma punktami danych, które mogą działać poprawnie w twoim cas E:

  1. przechwytywania wszystkie zmienne w reprezentatywnej zmiennej liczbowa, na przykład: (typu skóry tłustej = -1, suche = 1), typu włosów (długi = 2, krótkie = 0, średni = 1), styl życia (aktywny miłośnik zewnątrz = 1, TV junky = -1), wiek to liczba.
  2. Skaluj wszystkie zakresy liczbowe, aby pasowały do ​​względnej ważności, jaką dajesz im do wskazania różnicy. Na przykład: Różnica wieku wynosząca 10 lat jest tak różna jak różnica między włosami długimi i średnimi, a różnica między skórą tłustą i suchą. Tak więc 10 na skali wieku jest tak różne jak 1 na skali włosów jest tak różne jak 2 na skali skóry, więc skaluj różnicę wieku o 0,1, że we włosach o 1 i o skórze o 0.5
  3. odpowiedni distance metric, aby połączyć różnice między dwiema osobami na różnych skalach w jednej różnicy różnicowej. Im mniejsza liczba, tym bardziej podobne. Sugerowałbym prostą różnicę kwadratową jako pierwszą próbę funkcji odległości.

Wtedy różnica między dwojgiem ludzi może być obliczone z (zakładam Person.age, .skin, .hair itp przeszły już etap 1 i są numeryczne):

double Difference(Person p1, Person p2) { 

    double agescale=0.1; 
    double skinscale=0.5; 
    double hairscale=1; 
    double lifestylescale=1; 

    double agediff = (p1.age-p2.age)*agescale; 
    double skindiff = (p1.skin-p2.skin)*skinscale; 
    double hairdiff = (p1.hair-p2.hair)*hairscale; 
    double lifestylediff = (p1.lifestyle-p2.lifestyle)*lifestylescale; 

    double diff = sqrt(agediff^2 + skindiff^2 + hairdiff^2 + lifestylediff^2); 
    return diff; 
} 

Note różnica w tym przykładzie nie jest na podobnej skali jak (0..1). Jego wartość może wynosić od 0 (bez różnicy) do czegoś dużego (duża różnica). Ta metoda jest prawie całkowicie nienaukowa, została zaprojektowana tak, aby szybko dać Ci różnicę roboczą.