Алгоритм рекомендации - расчет связанных магазинов на основе данных их категории - PullRequest
0 голосов
/ 10 декабря 2011

У меня есть модели stores и categories.У магазина может быть много категорий.

Я пытаюсь создать список Похожие магазины для каждого магазина.

Я хочу рассчитать оценку на основе# общих категорий, которыми магазин делится с другим.

У меня есть план, но я не уверен, как начать кодировать это в Ruby on Rails.

Любойсовет?

PS. Я думаю, что было бы лучше иметь отдельную таблицу для хранения этих вычисленных данных для каждого хранилища - так как выполнение этого в реальном времени было бы интенсивным в БД.

ОБНОВЛЕНИЕ Я только что обнаружил ОСНОВНОЙ недостаток в моей логике для этого - только несколько универмагов, таких как Amazon, будут доминировать в связанных магазинах для всех продавцов (так как они принадлежат почти ко всем категориям).и, таким образом, будет соответствовать каждой категории для нишевых магазинов). Как-нибудь обойти эту проблему?

Ответы [ 2 ]

2 голосов
/ 10 декабря 2011

Ваш "ОСНОВНОЙ недостаток" не редкость.Как вы говорите, Amazon будет «связан» со всем.Это довольно распространенная проблема с любой системой рекомендаций, которая пытается использовать такие отношения.Я не делал этого с категориями магазинов, но проблема очень похожа на построенную мной систему выбора / ранжирования видео.

Обычный способ предотвратить доминирование популярного материала - вместо использованияколичество соответствующих категорий, вы даете веса на оценки для каждого магазина.Общие весовые коэффициенты: 1/category_count или 1/sqrt(category_count).

Представьте себе три магазина:

Jim's Books - 2 categories: ["Books", "Music"]
Amazon - 10 categories: ["Books", "Music", "Movies", "Housewares", etc.]
Ralph's Remainders - 3 categories: ["Books", "Music", "Movies"]

Теперь, если вы ищете магазины, похожие на книги Джима, вы подходитекатегории.Очевидно, что и Amazon, и Ralph включают категории «Книги» и «Музыка», и если бы вы использовали только количество совпадающих категорий, обе имели бы одинаковый балл.

Но если вы используете весовой коэффициент, тогда их оценки сильно отличаются.С весовым коэффициентом 1/category_count:

Amazon - 10 categories, weighting factor = 1/10.
Ralph's - 3 categories, weighting factor = 1/3.

Таким образом, Amazon получит оценку сходства 0,20, а Ральфа получит оценку сходства 0,66.

Если коэффициент взвешивания равен 1/sqrt(category_count), затем:

Amazon - weighting factor = 1/sqrt(10) = 0.316
Ralph's - weighting factor = 1/sqrt(3) = 0.562

В этом случае оценка Amazon составляет около 0,632, а оценка Ральфа - 1,124.

Я обнаружил, что 1/sqrt(category_count) обычно лучше, потому что этоуменьшает подавляющий эффект очень популярных магазинов (то есть тех, которые имеют много категорий), но не настолько, чтобы эти магазины не попадали в результаты.Использование 1/category_count придает слишком большое значение магазинам, которые имеют только одну или две категории.

1 голос
/ 10 декабря 2011

Если предположить, что у вас есть модели:

class Store < ActiveRecord:Base
has_many :categories_stores
has_many :categories, :throught => :categories_stores
end 

class CategoriesStore < ActiveRecord::Base
belongs_to :category
belongs_to :store
end

class Category < ActiveRecord::Base
has_many :categories_stores
has_many :categories, :throught => :categories_stores
end

Основной алгоритм в словах будет: 1. Найти категории (идентификаторы), которые имеют выбранный магазин.2. Найдите хранилища, которые имеют любую из категорий, начиная с шага 1. 3. Подсчитайте категории для каждого найденного хранилища из списка категорий 1.

Все это можно сделать несколькими способами в SQL,Например:

SELECT s3.store_id, COUNT(s3.category_id) FROM categories_stores s1, categories_stores s2, categories_stores s3 WHERE s1.store_id = :id and s2.category_id = s1.category_id and s3.store_id = s2.store_id and s3.category_id = s1.category_id GROUP BY s3.store_id

Где: id - параметр для запроса.Некоторые части запроса могут быть выполнены чистым ruby, некоторые нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...