Ich habe ein semi-funktionierendes System, das dieses Problem löst, Open-Source mit Scikit-Learn, mit einer Reihe von Blog-Posts, die beschreiben, was ich tue. Das Problem, das ich anpacke, ist die Wortsinn-Disambiguierung (Auswahl einer von mehreren Wortsinn- Optionen), die nicht mit der Erkennung benannter Entitäten identisch ist. Mein grundlegender Ansatz ist mit bestehenden Lösungen etwas konkurrenzfähig und (entscheidend) anpassbar.
Es gibt einige vorhandene kommerzielle NER-Tools (OpenCalais, DBPedia Spotlight und AlchemyAPI), mit denen Sie möglicherweise ein ausreichend kommerzielles Ergebnis erzielen - probieren Sie diese zuerst aus!
Ich habe einige davon für ein Kundenprojekt verwendet (ich berate mich mit NLP / ML in London), war aber mit ihrem Rückruf ( Präzision und Rückruf ) nicht zufrieden . Grundsätzlich können sie präzise sein (wenn sie sagen "Dies ist Apple Inc", sind sie normalerweise korrekt), aber mit geringem Rückruf (sie sagen selten "Dies ist Apple Inc", obwohl der Tweet für einen Menschen offensichtlich von Apple Inc handelt). Ich dachte, es wäre eine intellektuell interessante Übung, eine Open-Source-Version zu erstellen, die auf Tweets zugeschnitten ist. Hier ist der aktuelle Code:
https://github.com/ianozsvald/social_media_brand_disambiguator
Ich werde beachten Sie - ich versuche nicht , das verallgemeinerte Disambiguierung Problem bei diesem Ansatz, nur zu lösen Marke Begriffsklärung (Unternehmen, Menschen, etc.) , wenn Sie bereits ihren Namen haben. Deshalb glaube ich, dass dieser einfache Ansatz funktionieren wird.
Ich habe vor sechs Wochen damit begonnen und es ist in Python 2.7 mit scikit-learn geschrieben. Es verwendet einen sehr grundlegenden Ansatz. Ich vektorisiere mit einem Binärzählvektorisierer (ich zähle nur, ob ein Wort erscheint, nicht wie oft) mit 1-3 n-Gramm . Ich skaliere nicht mit TF-IDF (TF-IDF ist gut, wenn Sie eine variable Dokumentlänge haben; für mich sind die Tweets nur ein oder zwei Sätze, und meine Testergebnisse zeigten keine Verbesserung mit TF-IDF).
Ich benutze den einfachen Tokenizer, der sehr einfach, aber überraschend nützlich ist. Es ignoriert @ # (so dass Sie etwas Kontext verlieren) und erweitert natürlich keine URL. Ich trainiere dann mit logistischer Regression und es scheint, dass dieses Problem etwas linear trennbar ist (viele Begriffe für eine Klasse existieren für die andere nicht). Momentan vermeide ich jegliches Stemming / Reinigen (ich versuche die einfachste mögliche Sache, die funktionieren könnte).
Der Code hat eine vollständige README-Datei, und Sie sollten in der Lage sein, Ihre Tweets relativ einfach aufzunehmen und dann meinen Testvorschlägen zu folgen.
Dies funktioniert für Apple, da die Leute weder Apple-Computer essen oder trinken, noch Obst tippen oder damit spielen, sodass die Wörter leicht in die eine oder andere Kategorie unterteilt werden können. Diese Bedingung gilt möglicherweise nicht, wenn Sie etwas wie #definance für die TV-Show in Betracht ziehen (wo Leute #definance auch in Bezug auf den Arabischen Frühling, Cricket-Matches, Prüfungsrevisionen und eine Musikband verwenden). Hier sind möglicherweise klügere Ansätze erforderlich.
Ich habe eine Reihe von Blog-Posts , die dieses Projekt beschreiben, einschließlich einer einstündigen Präsentation, die ich bei der BrightonPython-Benutzergruppe gehalten habe (die zu einer kürzeren Präsentation für 140 Personen bei DataScienceLondon wurde).
Wenn Sie so etwas wie LogisticRegression verwenden (wobei Sie für jede Klassifizierung eine Wahrscheinlichkeit erhalten), können Sie nur die zuverlässigen Klassifizierungen auswählen. Auf diese Weise können Sie eine hohe Präzision erzwingen, indem Sie gegen den Rückruf handeln (damit Sie korrekte Ergebnisse erhalten, aber weniger davon). Sie müssen dies auf Ihr System abstimmen.
Hier ist ein möglicher algorithmischer Ansatz mit Scikit-Learn:
- Verwenden Sie einen Binary CountVectorizer (ich glaube nicht, dass Termzählungen in Kurznachrichten viele Informationen hinzufügen, da die meisten Wörter nur einmal vorkommen).
- Beginnen Sie mit einem Entscheidungsbaumklassifikator. Die Leistung ist erklärbar ( ein Beispiel finden Sie unter Überanpassung mit einem Entscheidungsbaum ).
- Wechseln Sie zur logistischen Regression
- Untersuchen Sie die von den Klassifizierern generierten Fehler (lesen Sie die exportierte Ausgabe des DecisionTree oder sehen Sie sich die Koeffizienten in LogisticRegression an, arbeiten Sie die falsch klassifizierten Tweets durch den Vectorizer zurück, um festzustellen, wie die zugrunde liegende Bag of Words-Darstellung aussieht - dort gibt es weniger Token als Du hast mit dem rohen Tweet angefangen - gibt es genug für eine Klassifizierung?)
- In meinem Beispielcode unter https://github.com/ianozsvald/social_media_brand_disambiguator/blob/master/learn1.py finden Sie eine funktionierende Version dieses Ansatzes
Dinge, die man beachten muss:
- Sie benötigen einen größeren Datensatz. Ich verwende 2000 beschriftete Tweets (ich habe fünf Stunden gebraucht) und mindestens ein ausgewogenes Set mit> 100 pro Klasse (siehe Hinweis zur Überanpassung unten).
- Verbessern Sie den Tokeniser (sehr einfach mit Scikit-Learn), um # @ in Token zu behalten, und fügen Sie möglicherweise einen Detektor für Großbuchstaben hinzu (wie Benutzer @ user2425429 feststellt).
- Betrachten Sie einen nichtlinearen Klassifikator (wie der obige Vorschlag von @ oiez), wenn es schwieriger wird. Persönlich stellte ich fest, dass LinearSVC schlechter abschneidet als die logistische Regression (dies kann jedoch an dem hochdimensionalen Merkmalsraum liegen, den ich noch nicht reduziert habe).
- Ein tweet-spezifischer Teil des Sprach-Taggers (meiner bescheidenen Meinung nach nicht Standfords, wie @Neil vorschlägt - meiner Erfahrung nach funktioniert er bei schlechter Twitter-Grammatik schlecht).
- Sobald Sie viele Token haben, möchten Sie wahrscheinlich eine gewisse Reduzierung der Dimensionalität vornehmen (ich habe dies noch nicht versucht - siehe meinen Blog-Beitrag zur Bestrafung von LogisticRegression l1 l2).
Re. Überanpassung. In meinem Datensatz mit 2000 Elementen habe ich einen 10-minütigen Schnappschuss von Twitter von "Apfel" -Tweets. Etwa 2/3 der Tweets sind für Apple Inc, 1/3 für andere Apple-Zwecke. Ich ziehe eine ausgewogene Teilmenge (ungefähr 584 Zeilen, glaube ich) jeder Klasse heraus und mache eine fünffache Kreuzvalidierung für das Training.
Da ich nur ein Zeitfenster von 10 Minuten habe, habe ich viele Tweets zum gleichen Thema, und dies ist wahrscheinlich der Grund, warum mein Klassifikator im Vergleich zu vorhandenen Tools so gut abschneidet - er passt zu den Trainingsfunktionen, ohne gut zu verallgemeinern (während der vorhandene Werbespot) Tools schneiden in diesem Snapshop schlechter ab, jedoch zuverlässiger für einen größeren Datensatz. Ich werde mein Zeitfenster erweitern, um dies als nachfolgende Arbeit zu testen.