wake-up-neo.com

Bester Weg, um Daten aus Text Python zu identifizieren und zu extrahieren?

Als Teil eines größeren persönlichen Projekts, an dem ich gerade arbeite, versuche ich, Inline-Daten aus verschiedenen Textquellen zu trennen.

Ich habe zum Beispiel eine große Liste von Zeichenfolgen (die normalerweise die Form von englischen Sätzen oder Anweisungen haben), die verschiedene Formen annehmen:

Sitzung des Zentralkonstruktionskomitees Dienstag 10/22 18:30 Uhr

Th 9/19 LAB: Seriencodierung (Abschnitt 2.2)

Am 15. Dezember wird es eine weitere für diejenigen geben, die es heute nicht schaffen.

Arbeitsbuch 3 (Mindestlohn): fällig am Mittwoch 18.9. 23:59 Uhr

Er wird am 15. September fliegen.

Während diese Datumsangaben mit dem natürlichen Text übereinstimmen, liegt keines von ihnen in spezifisch natürlichen Sprachformen vor (z. B. gibt es kein "Das Treffen wird zwei Wochen ab morgen sein" - das ist alles explizit). 

Als jemand, der nicht zu viel Erfahrung mit dieser Art von Verarbeitung hat, was wäre der beste Startpunkt? Ich habe mir Dinge wie das dateutil.parser-Modul und parsedatetime angeschaut, aber diese scheinen für after zu sein, das Sie isoliert haben.

Gibt es eine gute Möglichkeit, das Datum und den überflüssigen Text zu extrahieren? 

input:  Th 9/19 LAB: Serial encoding (Section 2.2)
output: ['Th 9/19', 'LAB: Serial encoding (Section 2.2)']

oder etwas ähnliches? Es scheint, dass diese Art der Verarbeitung von Anwendungen wie Gmail und Apple Mail durchgeführt wird. Ist es jedoch möglich, sie in Python zu implementieren?

25
redct

Ich habe auch nach einer Lösung dafür gesucht und konnte keine finden, also bauten ein Freund und ich ein Werkzeug, um dies zu tun. Ich dachte, ich würde wiederkommen und teilen, falls andere es hilfreich fanden.

datefinder - Datumsangaben im Text suchen und extrahieren

20
akoumjian

Wenn Sie die Segmente identifizieren können, die tatsächlich die Datumsinformationen enthalten, kann das Parsen mit parsedatetime recht einfach sein. Es gibt ein paar Dinge, die zu beachten sind, nämlich dass Ihre Daten keine Jahre haben und Sie sollten ein Gebietsschema auswählen.

>>> 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's the *next* occurence of 9/18

Es funktioniert nicht immer perfekt, wenn Sie fremden Text haben.

>>> 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)

Ehrlich gesagt scheint dies ein Problem zu sein, das einfach genug ist, um nach bestimmten Formaten zu analysieren und aus jedem Satz das wahrscheinlichste herauszuholen. Darüber hinaus wäre dies ein anständiges Problem beim maschinellen Lernen.

7
Kyle Kelley

Ich bin überrascht, dass die Methode SUTime und dateparsers search_dates nicht erwähnt wird. 

from sutime import SUTime
import os
import json
from dateparser.search import search_dates

str1 = "Let's meet sometime next Thursday" 

# You'll get more information about these jar files from SUTime's 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))]

Obwohl ich andere Module wie dateutil, datefinder und natty ausprobiert habe (konnte nicht mit Python zu Entlein kommen), scheinen diese beiden die vielversprechendsten Ergebnisse zu liefern. 

Die Ergebnisse von SUTime sind zuverlässiger und dies ist aus dem obigen Code-Snippet ersichtlich. In einigen grundlegenden Szenarien wie dem Analysieren eines Textes schlägt SUTime jedoch fehl 

"Ich werde erst am 19.9. Verfügbar sein"

oder 

"Ich werde zwischen dem 18. September und dem 20. September nicht zur Verfügung stehen.

Es gibt kein Ergebnis für den ersten Text und nur Monat und Jahr für den zweiten Text. Dies wird jedoch in der search_dates-Methode ziemlich gut gehandhabt. Die search_dates-Methode ist aggressiver und gibt alle möglichen Datumsangaben für alle Wörter im Eingabetext an. 

Ich habe noch keinen Weg gefunden, den Text strikt nach Datumsangaben in search_methods zu durchsuchen. Wenn ich einen Weg finden könnte, dies zu tun, ist dies meine erste Wahl gegenüber SUTime und ich würde auch sicherstellen, dass diese Antwort aktualisiert wird, wenn ich sie finde. 

Hallo, ich bin mir nicht sicher, ob der unten genannte Ansatz maschinelles Lernen ist, aber Sie können es versuchen:

  • fügen Sie aus externen Texten einen Kontext hinzu, z. B. die Veröffentlichungszeit für Textnachrichten, das Posten usw. (Ihr Text sagt nichts über das Jahr aus). 
  • extrahieren Sie alle Token mit dem Leerzeichen Leerzeichen und sollten etwa so aussehen:

    ['Th','Wednesday','9:34pm','7:34','pm','am','9/18','9/','/18', '19','12']
    
  • sie mit Regelsätzen verarbeiten, z. B. aus Wochentagen bestehen und/oder Variationen der Komponentenbildungszeit, und sie z. '% d:% dpm', '% d am', '% d /% d', '% d /% d' usw. kann Zeit bedeuten. Es sei angemerkt, dass es Zusammensetzungen haben kann, z. "12/31" ist 3 Gramm ("12", "/", "31") sollte ein Zeichen "12/31" von Interesse sein.

  • "Sehen" Sie, um welche Marken sich Markierungen wie "21:45 Uhr" befinden, zB ('Th', '9/19', '21:45' ') wird 3 Gramm aus "interessanten" Token gebildet und wenden Regeln an, die die Bedeutung bestimmen . 

  • wenn Sie 31/12 haben, bedeutet dies, dass 31> 12 bedeutet d/m oder umgekehrt, aber wenn 12/12 m haben, ist d nur im Kontextaufbau aus Text und/oder außerhalb verfügbar.

Prost

1
hardcode

Sie können die dateutil module - Methode parse mit der Option fuzzy verwenden.

>>> 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)
1
Samkit Jain
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
1
Prabin S

Neuere Versionen von parsedatetime lib bieten Suchfunktionen.

Beispiel

from dateparser.search import search_dates

dates = search_dates('Central design committee session Tuesday 10/22 6:30 pm')
0
Ramtin M. Seraj