Какой алгоритм / реализация для взвешенного сходства между пользователями по их выбранным, удаленным атрибутам?


Структура Данных:

User has many Profiles
    (Limit - no more than one of each profile type per user, no duplicates)
Profiles has many Attribute Values
    (A user can have as many or few attribute values as they like)
Attributes belong to a category
    (No overlap. This controls which attribute values a profile can have)

Пример / Контекст:

Я полагаю, что с помощью stack exchange вы можете иметь много профилей для одного пользователя, так как они отличаются для каждого сайта exchange? В этой задаче:

  • профиль: видео, поэтому профиль видео содержит только атрибуты категории Видео
  • атрибуты, поэтому атрибутом в категории Видео может быть Жанр
  • значения атрибутов, например Комедия, Боевик, Триллер - это все значения атрибутов

Профили и атрибуты-это просто способы группирования значений атрибутов на двух уровнях. Без группировки (что необходимо для взвешивания в 2. далее), отношение-это просто значения атрибутов пользователя hasMany.

Задача:

Дайте каждомупользователю оценку сходствадруг с другом.

  1. сходство основано навсех значениях атрибутов , связанных с пользователем.
    • плоский / один уровень
    • неравное число значений атрибутов между двумя пользователями
    • значение атрибута может выбирается только один раз для каждого пользователя, так что никаких дубликатов
    • следовательно, двоичная строка / булев массив с Косинусным подобием?
  2. 1 + Вес Профили
    • дайте каждому профилю вес (в сумме 1?)
    • вычислить сходство профиля, затем умножить на вес и суммировать?
  3. 1 + Вес категории атрибутов и профили
    • поскольку атрибут относится к категории, категории могут быть взвешены
    • сходство в расчете категория, взвешенная сумма, то же самое по профилю?
    • или объединить веса профиля и категории
  4. 3 + расстояние между каждым атрибутом значением
    • таблица расстояния подобия для каждого возможного значения vs value
    • а не сходство по значению = = = значение
    • "близкие" атрибуты способствуют общему сходству.
    • понятия не имею, как это сделать

Причудливый код и полезные функции-это здорово, но я действительно глядя, чтобы полностью понять, как достичь этих задач, поэтому я думаю, что общий псевдокод является лучшим.

Спасибо!

1 6

1 ответ:

Прежде всего, вы должны помнить, что все должно быть сделано максимально просто, но не проще. Это правило применимо ко многим областям, но в таких вещах, как семантика, сходство и машинное обучение, оно существенно. Использование нескольких уровней абстракции (атрибуты - > категории - > профили - > пользователи) делает вашу модель более трудной для понимания и рассуждения, поэтому я постараюсь опустить ее как можно больше. Это означает, что очень предпочтительно держать прямым отношение между пользователями и атрибутами. Таким образом, в основном ваши пользователи должны быть представлены в виде векторов, где каждая переменная (векторный элемент) представляет один атрибут.

Если вы выбрали такое представление, убедитесь, что все атрибуты имеют смысл и имеют соответствующий тип в этом контексте. Например, вы можете представить 5 жанров видео как 5 различных переменных, но не как числа от 1 до 5, так как косинусное сходство (и большинство других Альго) будет относиться к ним неправильно (например, умножьте триллер, представленный как 2, с комедией, представленной как 5, что на самом деле не имеет смысла).

Можно использовать расстояние между атрибутами, когда это применимо. Хотя я вряд ли могу привести пример в ваших условиях.

На этом этапе вы должны прекратить чтение и попробовать: простое представление пользователей в виде вектора атрибутов и Косинуса подобия. Если это хорошо работает, оставьте все как есть - чрезмерное усложнение модели никогда не бывает хорошим.

И если модель плохо работает, постарайтесь понять почему. Достаточно ли у вас соответствующих атрибутов? Или слишком много шумных переменных, которые только ухудшают ситуацию? Или некоторые атрибуты действительно должны иметь большее значение, чем другие? В зависимости от этих вопросов вы можете:

  1. беги выбор функции чтобы избежать шумных переменных.
  2. преобразуйте свои переменные , представляя их в какой-то другой "системе координат". Например, вместо использования N переменные для N жанров видео вы можете использовать M других переменных для представления близости к определенной социальной группе. Скажем, 1 для переменной " комедия "становится 0,8 для переменной" дети", 0,6 для переменной" домохозяйка "и 0,9 для переменной"старики". Или еще что-нибудь. Любой вид перевода, который кажется более "правильным", в порядке.
  3. используйтевеса . Не веса для категорий или профилей, а веса для различных атрибутов. Но не устанавливайте эти веса сами, вместо этого запустите линейную регрессию , чтобы найти они вышли.
Позвольте мне описать последний пункт немного подробнее. Вместо простого косинусного подобия, которое выглядит так:
cos(x, y) = x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]

Вы можете использовать взвешенную версию:

cos(x, y) = w[0]*x[0]*y[0] + w[1]*x[1]*y[1] + ... + w[2]*x[2]*y[2]
Стандартным способом нахождения таких весов является использование некоторого вида регрессии (линейная является наиболее популярной). Обычно вы собираете dataset (X, y), где X - матрица с векторами данных по строкам (например, сведения о проданном доме), а y - это своего рода "правильный ответ" (например, фактическая цена за что дом был продан). Однако в вашем случае нет правильного ответа на пользовательские векторы. На самом деле, вы можете определить правильный ответ только на их сходство. Так почему бы и нет? Просто сделайте так, чтобы каждая строка X была комбинацией 2 - х пользовательских векторов, а соответствующий элемент y - подобием между ними (вы должны сами назначить его для обучающего набора данных). Например:
X[k] = [ user_i[0]*user_j[0], user_i[1]*user_j[1], ..., user_i[n]*user_j[n] ]
y[k] = .75  // or whatever you assign to it

HTH