Разбор количества ингредиентов естественного языка для рецептов

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

я изначально планировал сложное регулярное выражение, а затем какой-то другой код, который преобразует читаемые человеком числа, такие как two или five в целые числа и, наконец, код, который преобразует say 1 cup и 3 teaspoons в некоторые базы измерений. Я контролирую вход, так что Я держал ингредиент отдельно. Однако я заметил, что пользователи вводят абстрактные измерения, такие как to taste и 1 package. По крайней мере, с абстрактными измерениями, я думаю, что мог бы просто игнорировать их и масштабировать и просто царапать любое число, предшествующее им.

вот еще несколько примеров

1 tall can
1/4 cup
2 Leaves
1 packet
To Taste
One
Two slices
3-4 fillets
Half-bunch
2 to 3 pinches (optional)

есть ли какие-либо трюки в этом? Я заметил, что пользователи, похоже, несколько смущены тем, что составляет количество. Я мог бы попытаться навязать более строгие правила и подтолкнуть такие вещи, как tall can и leaves в часть ингредиента. Однако, чтобы обеспечить это, я должен быть в состоянии передать то, что недействительно.

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

я также не уверен, что" базовое " измерение я должен преобразовать в количества.

EDIT: просто чтобы прояснить любую путаницу, это мои цели.

  1. чтобы иметь возможность масштабировать рецепты. произвольные единицы измерения, как packages не должны быть масштабированы, но точные, такие как cups или ounces надо быть.

  2. выясните" основные " ингредиенты. в контексте данного вопроса, это будет сделано в основном, выясняя, какой самый большой ингредиент в рецепте. В производстве должен быть какой-то модификатор на основе тип ингредиента, потому что, очевидно,flour почти никогда не считается "основным" ингредиентом. Однако,chocolate можно использовать экономно, и все еще можно сказать chocolate cake.

  3. нормализации входных данных. чтобы сохранить некоторую согласованность на сайте, я хочу сохранить последовательные сокращения. Например, вместо pounds, должно быть lbs.

я также добавил тег NLTK, потому что мне интересно, будет ли это проще сделать в python с в nltk.

4 ответов


вы ставите две проблемы, распознавая / извлекая выражения количества (синтаксис) и выясняя, какое количество они означают (семантика).

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

<amount> <unit> [of <ingredient>]

здесь <amount> может принимать различные формы:

whole or decimal number, in digits (250, 0.75)
common fraction (3/4)
numeral in words (half, one, ten, twenty-five, three quarters)
determiner instead of a numeral ("an onion")
subjective (some, a few, several)

количество можно также выразить как ряд два простых <amount>s:

two to three
2 to 3
2-3
five to 10

тогда у вас есть сами единицы:

general-purpose measurements (lb, oz, kg, g; pounds, ounces, etc.)
cooking units (Tb, tsp)
informal units (a pinch, a dash)
container sizes (package, bunch, large can)
no unit at all, for countable ingredients (as in "three lemons")

наконец, есть особый случай выражений, которые никогда не могут быть объединены ни с суммами, ни с единицами, поэтому они эффективно функционируют как комбинация обоих:

a little
to taste

Я бы предложил как небольшой парсер, который вы можете сделать как подробно или как грубо, как вам нужно. Это не должно быть слишком сложно написать regexps для всех из них, если это ваш инструмент выбора, но как вы видите, это не просто вопрос текстовой подстановки. Вытяните части вне и представьте каждый ингридиент как втройне (amount, unit, ingredient). (Для подсчетов используйте специальные единицы " штук "или что-то еще; для" немного " и тому подобное, я бы рассматривал их как специальные единицы).

остается вопрос преобразование и сравнение количествах. Преобразование единиц было сделано во многих местах, поэтому, по крайней мере, для официальных единиц у вас не должно быть проблем с получением таблица преобразования. Google сделает это, если вы наберете "конвертировать 4 унции в граммы", например. Обратите внимание, что Tbsp либо три, либо четыре tsp в зависимости от страны.

вы можете стандартизировать свои любимые единицы довольно легко для четко определенных единиц, но неофициальные единицы немного сложнее. Для "щепотки", "тире" и тому подобного я бы предложил выяснить приблизительный вес, чтобы вы могли правильно масштабировать (десять щепотек = 2 грамма или что-то еще). Банки и как безнадежны, если вы не можете посмотреть размер конкретных продуктов.

С другой стороны, субъективные суммы самые простые: если вы масштабируете "по вкусу" в десять раз, это все равно "по вкусу"!

последняя мысль: какая-то база данных ингредиентов также необходима для признавая основные ингредиенты, поскольку размер имеет значение:" одно яйцо", вероятно, не является основным ингредиентом, но" одна маленькая коза, четвертованная " вполне может быть. Я бы рассмотрел его для версии 2.


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

Если вы хотите что-то из сорта Ruby вместо NLTK, взгляните на Treat:

https://github.com/louismullie/treat

кроме того, структура лингвистики может быть хорошим вариантом, как хорошо:

http://deveiate.org/projects/Linguistics

EDIT:

Я решил, что там уже должен быть парсер рецептов Ruby, вот еще один вариант, который вы, возможно, захотите изучить:

https://github.com/iancanderson/ingreedy


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

http://allrecipes.com/Recipe/Darias-Slow-Cooker-Beef-Stroganoff - Этот сайт, кажется, позволяет конвертировать количество рецептов на основе метрической / имперской системы и количества обедающих.

http://www.epicurious.com/tools/conversions/common - Этот сайт, похоже, имеет много констант преобразования.

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

когда у вас есть тонны данных, даже простые методы обучения могут быть довольно полезными. Как только у вас будет много данных, вы можете использовать стандартные трюки НЛП (ngrams, TF-idf, naive bayes и т. д) чтобы быстро делать потрясающие вещи.

например:
главный ингредиент-Несс
Ингредиенты в блюде с более высокой idf (частота обратного документа), скорее всего, будут основными ингредиентами. В каждом блюде упоминается соль, поэтому она должна иметь очень низкий уровень idf. В гораздо меньшем количестве блюд упоминается масло, поэтому оно должно иметь более высокий idf. Большинство блюд, вероятно, имеют только один основной белок, поэтому фразы, такие как "курица", "тофу" и т. д., должны быть реже и гораздо более вероятными основными ингредиентами чем соль, лук, масло, и т. д. Конечно, могут быть такие элементы, как "кинза", которые могут быть реже, чем "курица", но если вы соскребли некоторые соответствующие метаданные вместе с каждым блюдом, у вас будут сигналы, которые помогут вам решить эту проблему. Большинство поваров, возможно, не используют кинзу в своих рецептах, но те, которые, вероятно, используют ее довольно много. Так для любого имени ингридиента, вы можете выяснить имя idf сперва рассматривать только авторов которые упоминали ингридиент на хотя бы один раз, а затем увидеть idf ингредиента на этом подмножестве рецептов.

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

Нормализует Входной Сигнал
Это вовсе не кажется трудной проблемой. Курирование вручную перечень общих сокращений и их полные формы (e.g " lbs "- > "фунты", "килограммы" - > "килограммы", "унции" - > "унции" и т. д.) должны решить 90% проблемы. Добавление новых сокращений в этот список всякий раз, когда вы их видите, должно сделать этот список довольно полным через некоторое время.

В общем, я прошу вас значительно увеличить размер ваших данных и собрать много соответствующих метаданных вместе с каждым рецептом, который вы царапаете (информация об авторе, жанр еды и т. д.), и использовать все эти структурированные данные наряду с простыми трюками НЛП / мл для решения большинства проблем, с которыми вы столкнетесь при попытке создать интеллектуальный Сайт рецептов.


Что касается этих:

  1. Я бы жестко закодировал их так, что если вы получите больше, чем столько ОЗ, перейдите к чашкам, если вы получите mroe, чем столько чашек, перейдите к пинтам, пометам, Галлонам и т. д. Я не знаю, как вы можете избежать этого, если кто-то уже не написал код для обработки этого.

  2. Если ингредиент находится в названии, это, вероятно, основной ингредиент. Однако вы столкнетесь с проблемами с "овсяным печеньем с изюмом". Как вы уже сказали, мука, молоко и т. д не главное ingrediant. Вам также нужно будет сопоставить бекон, свиная отбивная, свиной ростбиф со свининой и стейк, гамбургер и т. д.

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

Если вы пройдете через всю эту работу, рассмотрите отпуская его, чтобы другим не пришлось:)