2010-06-29 4 views
5

Ich möchte einige häufig vorkommende Phrasen mit Lucene bekommen. Ich erhalte einige Informationen aus TXT-Dateien, und ich verliere viel Kontext, weil ich keine Informationen für Phrasen z. "Information Retrieval" wird als zwei separate Wörter indiziert.Wie man häufig vorkommende Phrasen mit Lucene bekommt

Wie erhält man die Sätze so? Ich kann nichts Nützliches im Internet finden, alle Ratschläge, Links, Hinweise, besonders Beispiele sind willkommen!

EDIT: Ich speichere meine Dokumente nur durch Titel und Inhalt:

Document doc = new Document(); 
doc.add(new Field("name", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
doc.add(new Field("text", fReader, Field.TermVector.WITH_POSITIONS_OFFSETS)); 

weil für das, was ich die wichtigsten tue der Inhalt der Datei ist. Titel sind zu oft überhaupt nicht beschreibend (z. B. habe ich viele wissenschaftliche PDF-Dokumente, deren Titel Codes oder Zahlen sind).

Ich brauche verzweifelt Top-Phrasen aus Textinhalten zu indizieren, gerade jetzt sehe ich, wie viel diese einfache "Sack von Wörtern" Ansatz ist nicht effizient.

Antwort

7

Julia, Es scheint, was Sie suchen n-grams ist, speziell Bigrams (auch genannt Collocationen).

Hier ist ein chapter about finding collocations (PDF) von Manning und Schützes Foundations of Statistical Natural Language Processing.

Um dies mit Lucene zu tun, empfehle ich die Verwendung Solr mit ShingleFilterFactory. Weitere Informationen finden Sie unter this discussion.

+0

Ja genau, was ich brauche, ist ngrams .... Ich hatte gehofft, ich werde nicht zu viel ins NLP gehen müssen:/..aber kann ich dich bitte fragen, bevor ich gehe In diesem Buch Kapitel, wenn ich Werkzeuge benutze, die Sie mir empfohlen haben (und wenn ich sowieso handhabe), werden ngrams während der Suchzeit, nicht während der Indexzeit gefunden? Kann ich als das Endergebnis einen Index mit allen indizierten Indexbegriffen erhalten und häufige ngrams? Weil ich einige Konzept zusammenpassend mit Ontologie mache, und es wäre die beste Lösung, es so zu haben (wenn möglich natürlich) Danke! – Julia

+0

+1 für das korrekte Erkennen der proble m ... :) – Favonius

+0

@Julia: Ich denke, Sie können die ShingleFilterFactory während der Indizierung anwenden. Und vielleicht können Sie Luke (http://wiki.apache.org/solr/LukeRequestHandler) zum Anzeigen der Ergebnisse verwenden. Hoffe, du hast jetzt genug, um dich in Gang zu bringen. –

0

Ist es möglich, dass Sie einen von Ihnen geschriebenen Code posten?

Grundsätzlich hängt viel davon ab, wie Sie Ihre Felder erstellen und Dokumente in Lucene speichern.

Betrachten wir einen Fall, wo ich zwei Felder habe: ID und Kommentare; und in meinem ID-Feld erlaube ich Werte wie "Findet Nemo", d. h. Strings mit Leerzeichen. Wobei "Kommentare" ein Fließtextfeld ist, d. H. Ich erlaube alles und jeden, was meine Tastatur zulässt und was Lucene verstehen kann.

Jetzt im wirklichen Leben Szenario macht es keinen Sinn, meine ID zu machen: 'nemo' als zwei verschiedene durchsuchbare Zeichenfolge zu finden. Während ich alles in Kommentare indexieren möchte.

Also, was ich tun ist, werde ich ein Dokument (org.apache.lucene.document.Document) Objekt erstellen, diese zu kümmern ... So etwas wie diese

Document doc = new Document(); 
doc.add(new Field("comments","Finding nemo was a very tough job for a clown fish ...", Field.Store.YES, Field.Index.ANALYZED)); 
doc.add(new Field("id", "finding nemo", Field.Store.YES, Field.Index.NOT_ANALYZED)); 

Also, im Wesentlichen habe ich erstellt zwei Felder:

  1. Kommentare: Wo ich bevorzugt haben es zu analysieren, indem Field.Index.ANALYZED
  2. ID verwenden: Wo ich lucene gerichtet, es zu speichern, aber es nicht Field.Index.NOT_ANALYZED

analysieren Dies ist, wie Sie lucene für Standard Tokenizer und Analysator anpassen. Ansonsten können Sie eigene Tokenizer und Analysatoren schreiben.

Link (s) http://darksleep.com/lucene/

hoffe, dies wird Ihnen helfen ... :)

+0

Vielen Dank für die Antwort Favonius! Ich habe meinen Beitrag bearbeitet, damit Sie sehen können, wie ich Index-Dokumente erstellen kann. Wenn ich verstehe, was Sie sagen, verwenden nur die Informationen aus dem Titel, wird nicht für meinen Fall geeignet sein ..? :( – Julia

+0

@Julia: Eigentlich ist meine Antwort teilweise korrekt. Ich habe die N-Grams-Probleme als ein einfaches Indizierungsproblem missverstanden: o. Obwohl nur die 'ID' ('Titel' in Ihrem Fall) nicht angemessen sein könnte .. Ich glaube, du hast es bereits erkannt ... – Favonius

0

Nun, das Problem des Verlusts des Kontexts für Phrasen kann mit PhraseQuery gelöst werden.

Ein Index enthält standardmäßig Positionsinformationen von Begriffen, solange Sie keine reinen booleschen Felder durch Indizierung mit der Option omitTermFreqAndPositions erstellt haben. PhraseQuery verwendet diese Informationen, um Dokumente zu finden, deren Begriffe sich in einer bestimmten Entfernung voneinander befinden.

Angenommen, ein Feld enthielt den Ausdruck "der schnelle braune Fuchs sprang über den faulen Hund". Ohne den genauen Satz zu kennen, können Sie dieses Dokument immer noch finden, indem Sie nach Dokumenten suchen, deren Felder sich schnell und nahe beieinander befinden. Sicher, eine einfache TermQuery würde den Trick machen, um dieses Dokument mit einem dieser Wörter zu finden, aber in diesem Fall wollen wir nur Dokumente mit Phrasen, in denen die Wörter entweder genau nebeneinander stehen (schneller Fuchs) oder ein Wort dazwischen haben (schnell [irrelevant] Fuchs). Der maximal zulässige Positionsabstand zwischen Termen, die als Übereinstimmung betrachtet werden, wird als Slop bezeichnet. Abstand ist die Anzahl der Positionsverschiebungen von Termen, um die Phrase in der richtigen Reihenfolge zu rekonstruieren.

Check out Lucene's JavaDoc for PhraseQuery

See this example code which demonstrates how to work with various Query Objects:

Sie können auch versuchen, verschiedene Abfragetypen mit Hilfe der BooleanQuery Klasse zu kombinieren.

Und in Bezug auf die Häufigkeit von Phrasen, nehme ich an, Lucene Scoring berücksichtigt die Häufigkeit der Begriffe in den Dokumenten.