Я делаю общественный веб-сайт, который требует, чтобы я вычислил подобие между любыми двумя пользователями. Каждый пользователь описан со следующими атрибутами:
возраст, тип кожи (масляный, сухой), тип волос (длинный, короткий, средний), образ жизни (активный наружный любитель, телевизионный героинщик) и другие.
Кто-либо может сказать мне, как пойти об этой проблеме или указать на меня на некоторые ресурсы?
Другой способ вычисления (в 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
Если вас интересует метод сокращения размерности для категориальных данных (также способ расположить переменные в однородные кластеры), проверьте это
Вам, вероятно, следует поискать
Эти темы позволят вашей программе распознавать сходства и кластеры в вашей коллекции пользователей и пытаться адаптироваться к ним ...
Затем вы можете узнать разные скрытые общие группы связанных пользователей ... (т.е. пользователи с зелеными волосами обычно не любят смотреть телевизор ..)
В качестве совета попробуйте использовать готовые реализованные инструменты для этой функции вместо реализации сам ...
Взгляните на Open Directory Data Mining Projects
Посмотрите на алгоритмы вычисления разницы сртинга. Это очень похоже на то, что вам нужно. Сохраните свои атрибуты в виде битовой строки и вычислите расстояние между строками
Присвойте каждому атрибуту соответствующий вес и добавьте различия между значениями.
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)
Три шага для получения простой субъективной метрики для разницы между двумя точками данных, которая может отлично работать в вашем случае:
Затем разницу между двумя людьми можно вычислить с помощью (я предполагаю, что 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 (нет разницы) до чего-то большого (большая разница). Кроме того, этот метод почти полностью ненаучен, он просто предназначен для быстрого получения рабочей метрики разницы.
Вам следует прочитать эти две темы.