Was sind einige effiziente Methoden, um die Unterschiede zwischen zwei großen Textkorpussen mit ähnlichen, aber unterschiedlich geordneten Inhalten zu ermitteln?


8

Ich habe zwei große Dateien mit Absätzen englischen Textes:

  1. Der erste Text ist ungefähr 200 Seiten lang und hat ungefähr 10 Absätze pro Seite (jeder Absatz ist 5 Sätze lang).
  2. Der zweite Text enthält fast genau die gleichen Absätze und Texte wie der erste. Es ist auch 200 Seiten lang mit 10 Absätzen pro Seite. Die Absätze sind jedoch zufällig und in einer anderen Reihenfolge als der erste Text. Außerdem weist ein großer Prozentsatz der Absätze im Vergleich zu ähnlichen Absätzen geringfügige Wortlautänderungen auf. Zum Beispiel könnte ein Absatz im ersten Text einen Satz haben, wie Like Jimmy, I wanted to go to the palaceder entsprechende Satz im Absatz des zweiten Textes lauten würde Like Jimmy, I really wanted to go to the castle.

Ich möchte in der Lage sein, die Änderungen hier wie das Hinzufügen reallyund Löschen von palacedurch Ersetzen von zu erfassen castle. Wenn die Absätze grob ausgerichtet wären, wäre dies ziemlich trivial, da es viele Möglichkeiten gibt, Text zu unterscheiden. Da die Absätze jedoch nicht ausgerichtet sind, ist dies nicht der Fall.

Wenn die Dateien klein wären (eine Handvoll Absätze), würde Levenshtein Distance wahrscheinlich gut funktionieren, aber da die Dateien sehr groß sind, wäre es ineffizient, jeden Absatz von Text 1 mit jedem Absatz von Text 2 zu vergleichen, um herauszufinden, welche Absätze übereinstimmen.

Was wären andere Ansätze für dieses Problem, um es effizient zu lösen?


Sind die Absätze mindestens nahe beieinander, etwa innerhalb eines "Radius" von etwa 10? Eine allgemeine Idee wäre, auf irgendeine Weise vorzuverarbeiten. Finden Sie zum Beispiel Wörter heraus, die sich selten ändern (Namen?), Und vergleichen Sie nur diejenigen, die mindestens diese gemeinsam haben.
Raphael

Sie können ein Klonerkennungs-Tool ausprobieren. Sie sollen für Programmiersprachen verwendet werden, sind aber ansonsten für dieses Problem ausgelegt. CCFinder würde wahrscheinlich funktionieren.
Reinierpost

3
Hier ist ein ähnliches Problem mit einigen Antworten: cs.stackexchange.com/questions/47794/…
wvxvw

1
Haben Sie das Befehlszeilenprogramm "diff" ausprobiert?
Usul

@Raphael Können Sie hier erweitern, was Sie unter Vorverarbeitung verstehen? Außerdem kommen die Absätze in "Abschnitten" des Dokuments vor. Ein Abschnitt kann ziemlich lang (wie 50-60 Absätze) und ungeordnet sein.
Vikram7

Antworten:


1

Der Vergleich von 2000 Absätzen mit 2000 Absätzen ergibt nur vier Millionen Vergleiche.

Der Schlüssel zum Problem besteht nicht darin, eine Funktion zu verwenden, die den Levenshtein-Abstand berechnet, sondern eine Funktion, die den Levenshtein-Abstand berechnet, wenn der Abstand unter einem bestimmten Schwellenwert liegt , und fehlschlägt (oder vielmehr + ∞ zurückgibt), wenn der Abstand beträgt größer als die Schwelle.

Dies liegt daran, dass Sie nur an sehr ähnlichen Absätzen interessiert sind. Sie haben überhaupt kein Interesse an der genauen Entfernung zwischen Absätzen, die so unterschiedlich sind, dass sie nichts miteinander zu tun haben. Sobald eine Entfernung hoch genug ist, um uninteressant zu sein, kann die Funktion sofort beendet werden. und dies wird in der Tat meistens sehr früh während der Ausführung der Funktion geschehen.

Je höher der Schwellenwert, desto länger die Laufzeit, desto geringer der Anteil falsch negativer Ergebnisse.

Wenn Sie etwas mehr über die Dokumente wissen (z. B. dass jeder Absatz höchstens einem Absatz im anderen Dokument entspricht), können Sie einen Durchgang mit einem niedrigen Schwellenwert durchführen, die übereinstimmenden Absätze von der weiteren Prüfung ausschließen und einen Durchgang über Ihren jetzt reduzierten Absatz durchführen Korpus mit einem höheren Schwellenwert, schließen Sie diese reduzierten Absätze aus und so weiter.

Implementierungsdetail: Vermutlich würden Sie einen Levenshtein-Abstand eher für Wörter als für Zeichen berechnen. Wenn dies der Fall ist, sollten Sie zuerst jedem Wort eine Nummer zuweisen, indem Sie beispielsweise den gesamten Korpus sortieren, das erste Wort "1", das zweite Wort "2" usw. aufrufen. Auf diese Weise werden Ihre Absatzvergleiche durchgeführt, indem Zahlen statt Wörter verglichen werden, was schneller ist.


-1

Es könnte möglich sein, einen zusammengesetzten Ansatz zu verwenden. Vielleicht kann jemand darauf aufbauen ...

Hash den Inhalt des Absatzes so, dass Absätze mit nur geringen Unterschieden ähnliche Hashes haben, und ordne dann die Hashes an, um zu bestimmen, welche Absätze mit einer genaueren Methode (diff oder etwas Ähnliches) verglichen werden sollen.

Was wäre zum Beispiel als rudimentärer Hash-Algorithmus, wenn Sie die ASCII-Werte der Zeichen addieren und dann die Summe mit einer großen Zahl wie 2.000.000.000 modulieren? Dies würde dazu führen, dass 2 Absätze mit nur wenigen hinzugefügten oder subtrahierten Wörtern Hash-Werte aufweisen, die wahrscheinlich näher beieinander liegen als Absätze mit sehr unterschiedlichen Wörtern, und daher in der Liste viel näher beieinander liegen als die sehr unterschiedlichen Absätze (könnte man sagen) Hashes in der Nähe sind in diesem Fall erforderlich, reichen jedoch für ähnliche Absätze nicht aus. Offensichtlich müssen Sie den durch Modulo verursachten Wrap-Around berücksichtigen und einen Absatz mit dem Hash-Wert 1.999.999.999 als nur einen Abstand von 1 von einem mit dem Wert 0 usw. betrachten.

Infolgedessen könnte die Anzahl der Vergleiche zwischen Absätzen, die Sie durchführen müssen, erheblich reduziert werden (Sie müssten nicht jeden Absatz in einem Text mit jedem Absatz im anderen Text vergleichen) - Sie könnten einen Absatz mit vergleichen Absätze in Text 2 in der Reihenfolge, in der ihre Hashes nahe beieinander liegen (führen Sie zuerst die nächsten Hash-Werte aus), und rufen Sie hier einen teureren Algorithmus auf, um festzustellen, ob sie "ähnlich genug" sind, um als gleich angesehen zu werden.


2
Wenn Sie über Textabschnitte sprechen, ist die Summe der ASCII-Werte mod zwei Milliarden die Summe der ASCII-Werte. Es sei denn, Ihr Absatz besteht aus mehr als acht Millionen Zeichen, das heißt ... Diese Antwort sieht also ziemlich gehackt aus, basierend auf dem, woran Sie damals gedacht haben. Haben Sie Beweise dafür, dass der von Ihnen vorgeschlagene Ansatz effektiv ist? Wird es durch Experimente oder veröffentlichte Forschungsergebnisse gestützt?
David Richerby
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.