Поиск похожих группировок;в том числе разница и оценка (т.е. аналогичные рецепты) - PullRequest
1 голос
/ 12 октября 2010

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

Например;У меня есть следующий рецепт гуакамоле:

3 авокадо1 помидоры, созревшие в виноградных лозах1 красный лук3 халапеньо1 морская соль1 перец

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

Возможный результат будет:

3 Авокадо(- 1 помидоры, созревшие в виноградной лозе)1 красный лук3 халапеньо1 морская соль(- 1 перец)(+ Тобаско) 89,5% идентично

Это также можно использовать для определения следующего варианта использования: «Приведен список ингредиентов в моем холодильнике; что я могу приготовить для еды?».

Спасибо за любую помощь, указав мне в правильном направлении.

1 Ответ

1 голос
/ 12 октября 2010

Вне моей головы, вот некоторые проблемы, которые я вижу, которые возникнут при сопоставлении строк:

  • 3 Avocados и 2 Avocados оба используют авокадо, но строки не совпадают.
  • 1 tbsp salt и 15ml salt относятся к одинаковому количеству соли, но строки не совпадают.

Возможно, вы захотите сохранить таблицу рецептурных ингредиентов, в которой также хранятся нормализованные количества (т. Е. Все будет преобразовано в определенную единицу перед помещением в БД). Здесь я предполагаю, что у вас уже есть таблица для recipes и таблица для ingredients, оба из которых используются здесь как внешние ключи (делая это присоединяемая таблица )

CREATE TABLE recipe_ingredients (
  recipe_id INT NOT NULL,
  ingredient_id INT NOT NULL,
  quantity DECIMAL NOT NULL,
  PRIMARY KEY (recipe_id, ingredient_id),
  FOREIGN KEY recipe_id REFERENCES recipes (id),
  FOREIGN KEY ingredient_id REFERENCES ingredient (id)
)

И затем при определении совпадений вы можете использовать определение того, какой рецепт содержит наибольшее количество ингредиентов, которые вы ищете (это игнорирует количество):

SELECT ri.recipe_id, COUNT(ri.ingredient_id) AS num_common_ingredients
FROM ingredients AS i
RIGHT JOIN recipe_ingredients AS ri
  ON ri.ingredient_id = i.id
WHERE i.id IN (?) -- list of ingredient IDs being searched for
GROUP BY ri.recipe_id
ORDER BY COUNT(ri.ingredient_id) DESC

Строки с наибольшим COUNT имеют наибольшее сходство (поскольку это означает, что наибольшее количество общих ингредиентов).

Чтобы определить сходство между количествами, когда у вас есть рецепты, которые соответствуют большинству ингредиентов, вы можете сравнить количество, указанное с количеством, указанным в recipe_ingredients.

...