假设有一份菜谱(包含食材、步骤等),以自由文本形式呈现,我该如何使用PHP解析它,以便能够提取出食材(例如数量、计量单位、食材名称等)?
假设自由文本稍微有些格式化。
Java中有openNLP用于名称实体提取,可以获取您正在查找的内容,请参见:http://opennlp.sourceforge.net/models-1.5/
然后,您可以使用php-java连接器将结果获取到php中。
关于Java有一个非常相似的问题。简而言之,您需要使用字典(例如,成分)和类似于正则表达式的术语语言(注释)。您可以在Java中完成它,并通过Web服务从PHP调用它,或者您可以尝试在PHP中重新实现它(请注意,在第二种情况下,您可能会遇到显着的减速)。
如果你想快速完成这个任务,并且收集最少的资源,你可能可以想出一些好的启发式算法和正则表达式。
既然你说这个列表是“有点格式化的”,那么我会假设每行只有一个配料指令。
我会先列出一份测量单位名称的清单,这是一个相对封闭的类别(在语言学中称为相对封闭类),例如$measurements=['杯', '汤匙', '茶匙', '一撮', '一点', '适量', ...]
。你甚至可以创建一个字典,将多个项目映射到一个规范化的值上(例如$measurements={cup:['杯', 'c'], tablespoon:['汤匙', 'tbsp', 'tablesp', ...], ...}
或其他类似方式)。
然后,在每一行中,如果测量单位在你的字典中,你就可以找到它。接下来,查找数字(可能以小数形式格式化,例如1.5,也可能以复杂分数形式格式化,例如2 1/2或2-1/2),并假设这是你需要的单位数量。如果没有数字,则可以假定该单位为1(例如“适量”等情况)。
最后,您可以假设剩下的任何内容都是实际的成分。
我想这种启发式方法可以涵盖75-80%的情况。您仍然会遇到很多边角情况,例如当食谱要求“2个橙子”或者更糟糕的是“2个橙子的汁液”时。在这些情况下,您可以将它们添加为例外(在某种离线策划期间),或者让自己“OK”,不要对它们进行正确处理。
如果没有大量的语言建模,我认为唯一的方法就是拥有一个巨大的食材清单,并在食谱中搜索它们。数量应该是食材之前的单词。