检测文本中日期的最准确方法是什么?

What is the most accurate way to detect dates in text?

我正在处理敏感数据识别 (NER) 任务。面对我无法准确检测文本中的日期这一事实。我几乎什么都试过了...

例如,我的文本中有这种类型的日期:

date_list = ['23 octbr', '08/10/1975', '2/20/1961', 'December 23', '2021', '1/10/1980', ...]

但不得不说,文中也有很多数字信息,例如IP地址、住家地址、银行卡号等

这是 Spacy 工作原理的示例:

'08/10/1975' -> Entityt type: No Entity
'2/20/1961' -> Entityt type: DATE
'1/10/1980' -> Entityt type: CARDINAL

或者例如我有 phone 数字 "(150) 224-2215" 并且它 Spacy"24-2215" 部分标记为日期。地址和信用卡号也经常发生这种情况。

然后我尝试了 datefinderdateparser.search,但他们检测到句子中完全不正确的部分或包含单词“to”的部分。

能否请您分享您的经验,什么可以更好地工作?获得高精度日期检测的最佳方法是什么?

您尝试过使用正则表达式吗?它解决了大多数问题,例如日期和 phone 数字。

这里有一个小例子,你可以理解

例子

import re
import datetime
from datetime import date

register = "The last payment was 2021-09-21"
match = re.search(r'\d{4}-\d{2}-\d{2}', register)
date = datetime.datetime.strptime(match.group(), '%Y-%m-%d').date()
print date

输出

2021-09-21

你的语料库包括什么,包括完整的句子吗?

  • 首先,您可以尝试使用 context 的 spaCy NER。 NER 算法适用于完整的句子。

  • 如果您正在寻找更面向 token/shape 的解决方案,我建议使用上下文无关解析。上下文无关语法非常适合描述日期。基本上你定义了一些语法规则,例如:

calendar_year -> full_year | year
year -> 19\d{,2} | 20\d{,2}
full_year -> day/month/year | day.month.year
day -> digit_num | two_digit_num
month -> digit_num | two_digit_num
digit_num -> 0 | 1 | 2 ... |9

正则表达式在这里不是一个好主意,因为它没有“上下文”,即解析的字符不知道之前解析过什么,没有记忆。上下文无关语法提供了一种结构化的方式来解析字符串并提供解析树。

这是我用 Lark 做的,日期是德文的: https://duygua.github.io/blog/2018/03/28/chatbot-nlu-series-datetimeparser/