Способы расчета подобия
Я делаю сайт сообщества, который требует от меня подсчета сходства между любыми двумя пользователями. Каждый пользователь описывается со следующими атрибутами:
возраст, тип кожи (маслянистый, сухой), тип волос (длинный, короткий, средний), образ жизни (активный наружный любовник, телевизионный junky) и другие.
Может ли кто-нибудь сказать мне, как решить эту проблему или указать мне на некоторые ресурсы?
Ответы
Ответ 1
Другой способ вычисления (в R) всех попарных различий (расстояний) между наблюдениями в наборе данных. Исходные переменные могут иметь смешанные типы. Обработка номинальных, порядковых и (а) симметричных двоичных данных достигается за счет использования общего коэффициента несходства Gower (Gower, J. C. (1971) Общий коэффициент подобия и некоторые его свойства, Biometrics 27, 857-874). Подробнее см. на странице 47. Если x содержит любые столбцы этих типов данных, коэффициент Gower будет использоваться как метрика.
Например
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
Если вас интересует метод уменьшения размерности для категориальных данных (также способ упорядочивания переменных в однородные кластеры), проверьте this
Ответ 2
Дайте каждому атрибуту соответствующий вес и добавьте различия между значениями.
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
Вероятно, вам стоит взглянуть на
Эти темы позволят вашей программе распознавать сходства и кластеры в вашей коллекции пользователей и попытаться адаптироваться к ним...
Затем вы можете узнать разные скрытые общие группы связанных пользователей... (например, пользователям с зелеными волосами обычно не нравится смотреть телевизор..)
Как совет, попробуйте использовать готовые реализованные инструменты для этой функции, а не для ее реализации самостоятельно...
Взгляните на Открыть проекты разработки данных каталога
Ответ 4
Три шага для достижения простой субъективной метрики для разницы между двумя точками данных, которые могут нормально работать в вашем случае:
- Захватите все свои переменные в числовой переменной, например: тип кожи (масляный = -1, сухой = 1), тип волос (длинный = 2, короткий = 0, средний = 1), образ жизни (активный наружный любовник = 1, TV junky = -1), возраст - это число.
- Масштабируйте все числовые диапазоны, чтобы они соответствовали относительной важности, которую вы им даете для указания разницы. Например: Разница в возрасте 10 лет примерно такая же разная, как разница между длинными и средними волосами, а также разница между жирной и сухой кожей. Таким образом, 10 по возрастной шкале отличаются друг от друга, так как 1 по шкале волос отличается от 2 по шкале кожи, поэтому уменьшите разницу в возрасте на 0,1, что в волосах на 1, а на коже - на 0,5.
- Используйте соответствующий показатель расстояния, чтобы сочетать различия между двумя людьми в разных масштабах с одной разницей. Чем меньше это число, тем они более похожи. Я бы предложил простое квадратичное различие в качестве первой попытки вашей дистанционной функции.
Тогда разница между двумя людьми может быть рассчитана с помощью (Я предполагаю, что 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 (без разницы) до чего-то большого (высокая разница). Кроме того, этот метод почти полностью ненаучный, он просто разработан, чтобы быстро дать вам показатель рабочих различий.
Ответ 5
Посмотрите на алгоритмы вычисления разности srting. Это очень похоже на то, что вам нужно. Храните свои атрибуты в виде битовой строки и вычисляйте расстояние между строками
Ответ 6
Вы должны прочитать эти две темы.
Самый популярный алгоритм кластеризации k - означает
И матрица подобия существенна в кластеризации