Ответ 1
Я также искал решение этого и не мог найти ни одного, поэтому мы с другом создали инструмент для этого. Я думал, что вернусь и поделись тем, что другие считают полезным.
В рамках более крупного личного проекта, над которым я работаю, я пытаюсь отделить встроенные даты от различных текстовых источников.
Например, у меня есть большой список строк (которые обычно принимают форму английских предложений или операторов), которые принимают различные формы:
Заседание центральной проектной комиссии Вторник 10/22 6:30 вечера
Th 9/19 LAB: последовательное кодирование (раздел 2.2)
15 декабря будет еще один для тех, кто неспособен сделать это сегодня.
Рабочая тетрадь 3 (минимальная заработная плата): срок Среда 9/18 23:59
Он будет летать 15 сентября.
Хотя эти даты совпадают с естественным текстом, ни одна из них сама по себе не является собственно естественными языковыми формами (например, нет "Встреча будет через две недели с завтрашнего дня" - все это явно).
Как у кого-то, у кого нет слишком большого опыта работы с такой обработкой, что было бы лучше всего начать? Я просмотрел такие вещи, как модуль dateutil.parser
и parsedatetime, но, похоже, это происходит после того, как вы выделили дату.
Из-за этого есть ли хороший способ извлечь дату и посторонний текст
input: Th 9/19 LAB: Serial encoding (Section 2.2)
output: ['Th 9/19', 'LAB: Serial encoding (Section 2.2)']
или что-то подобное? Похоже, что подобная обработка выполняется такими приложениями, как Gmail и Apple Mail, но возможно ли реализовать их на Python?
Я также искал решение этого и не мог найти ни одного, поэтому мы с другом создали инструмент для этого. Я думал, что вернусь и поделись тем, что другие считают полезным.
Если вы можете определить сегменты, которые на самом деле содержат информацию о дате, их анализ может быть довольно простым с parsedatetime. Однако следует учитывать несколько моментов, а именно то, что у ваших дат нет лет, и вы должны выбрать локаль.
>>> import parsedatetime
>>> p = parsedatetime.Calendar()
>>> p.parse("December 15th")
((2013, 12, 15, 0, 13, 30, 4, 319, 0), 1)
>>> p.parse("9/18 11:59 pm")
((2014, 9, 18, 23, 59, 0, 4, 319, 0), 3)
>>> # It chooses 2014 since that the *next* occurence of 9/18
Это не всегда работает идеально, если у вас есть посторонний текст.
>>> p.parse("9/19 LAB: Serial encoding")
((2014, 9, 19, 0, 15, 30, 4, 319, 0), 1)
>>> p.parse("9/19 LAB: Serial encoding (Section 2.2)")
((2014, 2, 2, 0, 15, 32, 4, 319, 0), 1)
Честно говоря, это похоже на проблему, которая была бы достаточно простой, чтобы проанализировать определенные форматы и выбрать наиболее вероятное из каждого предложения. Кроме того, это была бы достойная проблема машинного обучения.
import datefinder
string_with_dates = """
entries are due by January 4th, 2017 at 8:00pm
created 01/15/2005 by ACME Inc. and associates.
"""
matches = datefinder.find_dates(string_with_dates)
for match in matches:
print match
Я удивлен отсутствием упоминания о методах SUTime и dateparser search_dates.
from sutime import SUTime
import os
import json
from dateparser.search import search_dates
str1 = "Let meet sometime next Thursday"
# You'll get more information about these jar files from SUTime github page
jar_files = os.path.join(os.path.dirname(__file__), 'jars')
sutime = SUTime(jars=jar_files, mark_time_ranges=True)
print(json.dumps(sutime.parse(str1), sort_keys=True, indent=4))
"""output:
[
{
"end": 33,
"start": 20,
"text": "next Thursday",
"type": "DATE",
"value": "2018-10-11"
}
]
"""
print(search_dates(str1))
#output:
#[('Thursday', datetime.datetime(2018, 9, 27, 0, 0))]
Хотя я пробовал другие модули, такие как dateutil, datefinder и natty (не мог заставить утенка работать с python), эти два, похоже, дают наиболее многообещающие результаты.
Результаты от SUTime более надежны, и это видно из приведенного выше фрагмента кода. Тем не менее, SUTime не работает в некоторых основных сценариях, таких как анализ текста
"Я не буду доступен до 19 сентября"
или
"I won't be available between (September 18-September 20).
Это не дает результата для первого текста и только дает месяц и год для второго текста. Это, однако, обрабатывается довольно хорошо в методе search_dates. Метод search_dates более агрессивен и выдаст все возможные даты, связанные с любыми словами во входном тексте.
Я еще не нашел способ разобрать текст строго по датам в search_methods. Если бы я мог найти способ сделать это, это будет мой первый выбор по сравнению с SUTime, и я также обязательно обновлю этот ответ, если найду его.
Привет, я не уверен, что подход - это машинное обучение, но вы можете попробовать:
извлеките все маркеры с пробелом разделителя и получите что-то вроде этого:
['Th','Wednesday','9:34pm','7:34','pm','am','9/18','9/','/18', '19','12']
обрабатывать их с помощью наборов правил, например, начиная с будних дней и/или вариантов компонентов, формирующих время и маркирующих их, например. '% d:% dpm', '% d am', '% d/% d', '% d/% d' и т.д. может означать время. Следует отметить, что он может содержать композиции, например. "12/31" - 3грамма ( "12", "/", "31" ) - это один токен "12/31".
"см.", какие жетоны обозначены маркерами вроде "9:45 pm", например ( "Th", "9/19", "9:45 pm" ) составляет 3gram из "интересных" токенов и применяют правила об этом, который может определить смысл.
для более конкретного анализа, например, если есть 31/12, поэтому 31 > 12 означает d/m или наоборот, но если они имеют 12/12 м, d будут доступны только в контексте построения из текста и/или снаружи.
Приветствия
Вы можете использовать метод модуля dateutilparse
с опцией fuzzy
.
>>> from dateutil.parser import parse
>>> parse("Central design committee session Tuesday 10/22 6:30 pm", fuzzy=True)
datetime.datetime(2018, 10, 22, 18, 30)
>>> parse("There will be another one on December 15th for those who are unable to make it today.", fuzzy=True)
datetime.datetime(2018, 12, 15, 0, 0)
>>> parse("Workbook 3 (Minimum Wage): due Wednesday 9/18 11:59pm", fuzzy=True)
datetime.datetime(2018, 3, 9, 23, 59)
>>> parse("He will be flying in Sept. 15th.", fuzzy=True)
datetime.datetime(2018, 9, 15, 0, 0)
>>> parse("Th 9/19 LAB: Serial encoding (Section 2.2)", fuzzy=True)
datetime.datetime(2002, 9, 19, 0, 0)
Более новые версии parsedatetime
lib предоставляют функции поиска.
Пример
from dateparser.search import search_dates
dates = search_dates('Central design committee session Tuesday 10/22 6:30 pm')