我正在寻找一个Java库来帮助解析用户输入的文本,该文本代表日历应用程序的“约会”。例如:
周二11:30与Mike共进午餐
或
星期五下午5点欢乐时光
我找到了一些很有前途的线索,例如https://github.com/samtingleff/jchronic和http://www.datejs.com/可以解析日期 - 但我还需要能够提取事件的标题,例如“与Mike共进午餐”。
如果不存在这样的API,我也对从编码角度如何最好地解决问题的想法感兴趣。
答案 0 :(得分:9)
延长JChronic可能是您最好的选择。我认为,鉴于对this question的响应,不太可能存在预先构建的库(虽然看起来这样的事情可能有用......我猜测解析的主要用例如果自然语言日期能够从用户提供的字符串中提取其他数据,则它们会更有用。
实现方面,可能最直接的做法是扩展JChronic,因为它支持你的用例的很大一部分,但是应该已经忽略了超过as you can see from the unit test多余的无关信息。框架。 幸运的是,如果你看一下the main class,扩展/修改/包装parse()方法以支持事件标题的自定义扫描程序应该不会太难。 (我自己对这些的偏好是包装框架而不是fork并修改它,因为这样可以更容易地从底层代码的任何改进中受益)。
最终,可能证明最直接的方法是生成一个正则表达式解析器,它忽略了JChronic尝试捕获的大部分内容(这意味着对JChronic源代码非常熟悉)。
与任何NLP类型项目一样,成功实现此项的关键是拥有尽可能多的示例,最好是自动化单元测试(最终,即使测试用例测试多次重复相同的功能,拥有更多的例子比更少的例子更好。幸运的是,由于我们谈论的是自然语言,因此这类测试用例应该特别容易获得,因为即使是非程序员朋友,家人等也应该能够为您提供“事件描述”(或者您想要调用的任何内容)他们)。您还需要特别关注日期解析位可能会干扰位置/标题解析位的边缘情况(例如,在“sigur,在晚上8点”,“at”显然是时间的一部分,而在“party”中在phoebe的星期六“显然不是这样。”
我意识到我对JChronic说了很多,但我觉得这是你问题的自然选择,因为它已经涵盖了解析自然语言“约会”的大部分“困难部分”,即我们的模糊性我们使用的语言与时间有关,并且已经用您所针对的语言实现。
答案 1 :(得分:2)
尝试提取约会名称有两种相对简单的方法。
使用序列标签包
如果您有标签数据集,则可以使用CRF++或Yamcha这样的包训练序列模型,以提取“与Mike共进午餐”等约会标题。
使用命名实体和规则
如果您没有标记数据集,则可能会使用named entity recognizer标记约会文本中的所有人员,位置和组织。作为奖励,这也将给你时间&日期,所以你不需要编写自己的代码来解决这些问题。
对于所有已标记的命名实体,应该非常直接地编写一些规则来为每个约会提取或构建标题。
答案 2 :(得分:0)
我无法想到任何可以按照您的规格做到的事情。您可以尝试使用Stanford NLP Java包或OpenNLP。然而,这可能是你试图做的大锤解决方案。
或者您可以尝试自己解析它。如果要处理更多输入,请使用JFlex扫描输入并使用tokenize和CUP创建语法。