约会的自然语言解析?

2022-09-04 21:30:45

我正在寻找一个Java库来帮助解析用户输入的文本,该文本表示日历应用程序的“约会”。例如:

周二11:30与迈克共进午餐

周五下午5点欢乐时光

我发现了一些有前途的线索,如 https://github.com/samtingleff/jchronichttp://www.datejs.com/ 可以解析日期 - 但我还需要能够提取事件的标题,如“与迈克共进午餐”。

如果不存在这样的API,我也对如何从编码的角度最好地解决问题的任何想法感兴趣。


答案 1

扩展JChronic可能是您最好的选择。我认为,鉴于对这个问题的回答,不太可能存在一个预先构建的库(尽管看起来这样的事情可能是有用的......我猜想,如果解析自然语言日期的主要用例能够从用户提供的字符串中提取其他数据,那么它们将更加有用。

在实现方面,可能最直接的事情是扩展JChronic,因为它支持你用例的相当重要的一部分,但正如你从单元测试中看到的那样,框架应该已经忽略了无关的信息。幸运的是,如果您查看主类,扩展/修改/包装parse()方法以支持事件标题的自定义扫描程序应该不会太难。(我自己更喜欢包装框架,而不是分叉并修改它,因为这可以让你更容易地从底层代码的任何改进中受益)。

最终,最直接的方法可能是生成一个正则表达式解析器,该解析器忽略了JChronic试图捕获的大部分内容(这意味着要非常熟悉JChronic源代码)。

与任何NLP类型的项目一样,成功实现这一点的关键是尽可能多地获得示例,最好是自动化单元测试(最终,即使测试用例测试多次重复相同的功能,最好有更多的示例而不是更少的示例)。幸运的是,既然我们谈论的是自然语言,这样的测试用例应该特别容易获得,因为即使是非程序员的朋友,家人等也应该能够为你提供“事件描述”(或者你想称呼它们的任何东西)。您还需要特别关注日期解析位可能会干扰位置/标题解析位的边缘情况(例如,在“sigur rós at 8pm”中,“at”显然是时间的一部分,而在“phoebe的星期六聚会”中,它显然不是)。

我意识到我对JChronic说了很多,但我觉得这是你的问题的一个自然选择,因为它已经涵盖了解析自然语言“约会”的大部分“困难部分”,即我们使用的关于时间的语言的模糊性,并且已经在你目标的语言中实现。


答案 2

有两种相对简单的方法可以尝试提取约会名称。

使用序列标记包

如果你有一个标记的数据集,你可以使用CRF ++Yamcha等软件包来训练一个序列模型,以提取“与Mike共进午餐”等约会标题。

使用命名实体和规则

如果没有带标签的数据集,则使用命名实体识别器标记约会文本中的所有人员、位置和组织可能会获得一些里程。作为奖励,这也会给你时间和日期,所以你不需要编写自己的代码来提取它们。

在命名实体全部标记后,编写一些规则来提取或构造每个约会的标题应该非常简单。

如果你正在寻找一个基于Java的NER标记器,你可以使用斯坦福大学发布的那个或OpenNLP分发的那个。