Способы вычислить подобие

Я делаю общественный веб-сайт, который требует, чтобы я вычислил подобие между любыми двумя пользователями. Каждый пользователь описан со следующими атрибутами:

возраст, тип кожи (масляный, сухой), тип волос (длинный, короткий, средний), образ жизни (активный наружный любитель, телевизионный героинщик) и другие.

Кто-либо может сказать мне, как пойти об этой проблеме или указать на меня на некоторые ресурсы?

17
задан Iterator 27 September 2011 в 01:59
поделиться

6 ответов

Другой способ вычисления (в R) всех парных несходств (расстояний) между наблюдениями в наборе данных. Исходные переменные могут быть смешанного типа. Для обработки номинальных, порядковых и (а)симметричных бинарных данных используется общий коэффициент несходства Гоуэра (Gower, J. C. (1971) A general coefficient of similarity and some of its properties, Biometrics 27, 857-874). Подробнее смотрите на странице 47. Если x содержит любые столбцы этих типов данных, то в качестве метрики будет использоваться коэффициент Гауэра.

Например

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")

вы получите :

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

Если вас интересует метод сокращения размерности для категориальных данных (также способ расположить переменные в однородные кластеры), проверьте это

14
ответ дан 30 November 2019 в 13:45
поделиться

Вам, вероятно, следует поискать

Эти темы позволят вашей программе распознавать сходства и кластеры в вашей коллекции пользователей и пытаться адаптироваться к ним ...

Затем вы можете узнать разные скрытые общие группы связанных пользователей ... (т.е. пользователи с зелеными волосами обычно не любят смотреть телевизор ..)

В качестве совета попробуйте использовать готовые реализованные инструменты для этой функции вместо реализации сам ...
Взгляните на Open Directory Data Mining Projects

2
ответ дан 30 November 2019 в 13:45
поделиться

Посмотрите на алгоритмы вычисления разницы сртинга. Это очень похоже на то, что вам нужно. Сохраните свои атрибуты в виде битовой строки и вычислите расстояние между строками

0
ответ дан 30 November 2019 в 13:45
поделиться

Присвойте каждому атрибуту соответствующий вес и добавьте различия между значениями.

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

Если вам действительно нужно сходство вместо различия, используйте 1 / UserDifference (a, b)

3
ответ дан 30 November 2019 в 13:45
поделиться

Три шага для получения простой субъективной метрики для разницы между двумя точками данных, которая может отлично работать в вашем случае:

  1. Зафиксируйте все ваши переменные в представительной числовой переменной, например: тип кожи (жирная=-1, сухая=-1), тип волос (длинные=-2, короткие=0, средние=-1), образ жизни (активный любитель активного отдыха=-1, любитель телевизора=-1), возраст - число.
  2. Масштабируйте все числовые диапазоны так, чтобы они соответствовали той относительной важности, которую вы придаете им для обозначения различий. Например: Разница в возрасте в 10 лет примерно такая же, как разница между длинными и средними волосами и разница между жирной и сухой кожей. Таким образом, 10 лет по шкале возраста отличаются так же, как 1 по шкале волос отличается от 2 по шкале кожи, поэтому отмасштабируйте разницу в возрасте на 0,1, в волосах - на 1, а в коже - на 0,5
  3. Используйте соответствующую метрику расстояния, чтобы объединить различия между двумя людьми по различным шкалам в одну общую разницу. Чем меньше это число, тем больше они похожи. Я бы предложил простую квадратичную разность в качестве первой попытки для функции расстояния.

Затем разницу между двумя людьми можно вычислить с помощью (я предполагаю, что Person.age, .skin, .hair и т.д. уже прошли через шаг 1 и являются числовыми):

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;
}

Обратите внимание, что diff в этом примере не имеет красивой шкалы (0..1). Его значение может варьироваться от 0 (нет разницы) до чего-то большого (большая разница). Кроме того, этот метод почти полностью ненаучен, он просто предназначен для быстрого получения рабочей метрики разницы.

1
ответ дан 30 November 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: