[PYTHON] Berechnen Sie die Entsprechung zwischen zwei Abteilungen

Bei der Verarbeitung einer Sprache denke ich, dass sie häufig mit einem Tokenizer wie Mecab geteilt wird. In diesem Artikel werde ich vorstellen, wie die Korrespondenz zwischen verschiedenen Tokenizer-Ausgaben (separates Schreiben) und deren Implementierung (Tokenisierungen) berechnet wird. Schauen wir uns zum Beispiel die folgende Methode an, die nicht von der Implementierung des Tokenizers abhängt, um die Entsprechung zwischen dem Ergebnis der Teilung von Satzstück und BERT zu berechnen.

#Teilen
(a) BERT          : ['Fu', '##Helt', '##Uns', '##Fuルク', 'Vertrag', 'Zu', 'Fazit']
(b) sentencepiece : ['▁', 'Fu', 'Glocke', 'Zu uns', 'Burg', 'Vertrag', 'Zu', 'Fazit']

#Korrespondenz
a2b: [[1], [2, 3], [3], [4], [5], [6], [7]]
b2a: [[], [0], [1], [1, 2], [3], [4], [5], [6]]

Problem

Wenn Sie sich das vorherige Beispiel ansehen, sehen Sie, dass es die folgenden Unterschiede zwischen verschiedenen Abteilungen gibt.

  1. Das Schneiden von Token ist anders
  2. Unterschiedliche Normalisierung (zB B-> F)
  3. Rauschen wie Steuerzeichen können eingegeben werden (Beispiel: #, _)

Wenn der Unterschied nur 1 beträgt, scheint es einfach zu sein, damit umzugehen. Sie können die beiden Abteilungen zeichenweise von oben vergleichen. Tatsächlich vergleicht die zuvor in spaCy implementierte spacy.gold.align (link) Brüche auf diese Weise. Sobald jedoch 2 und 3 eingehen, wird es verwirrend. Wenn Sie sich auf die Implementierung jedes Tokenizers verlassen können, scheint es möglich zu sein, die Entsprechung durch Ausschließen der Steuerzeichen zu berechnen. Die Implementierung auf diese Weise für eine beliebige Kombination von Tokenizern kann jedoch entmutigend sein. spacy-transformers reagierte auf dieses Problem mit alles außer ASCII-Zeichen ignorierend. /blob/88814f5f4be7f0d4c784d8500c558d9ba06b9a56/spacy_transformers/_tokenizers.py#L539) wird übernommen. Es scheint, dass es auf Englisch ziemlich gut funktioniert, aber auf Japanisch kaum. Daher besteht das diesmal zu lösende Problem darin, die Entsprechung der Teilmengen mit den obigen Differenzen 1 bis 3 zu berechnen.

Normalisierung

Bei der Sprachverarbeitung werden verschiedene Normalisierungen verwendet. Zum Beispiel

Etc. Zusätzlich zu dem oben genannten wird es häufig in Kombination verwendet. Das mehrsprachige BERT-Modell verwendet beispielsweise das Verringern + NFKD + Akzententfernung.

Entsprechende Berechnungsmethode

Die beiden Unterteilungen seien "A" und "B". Zum Beispiel ist "A = [" Heute "," ist "," Gut "," Wetter "," Da "]". Die Entsprechung kann wie folgt berechnet werden.

  1. Normalisieren Sie jedes Token mit NFKD und senken Sie es
  2. Kombiniere die Token von "A" und "B", um zwei Saiten "Sa" und "Sb" zu bilden. (Beispiel: "Sa =" Heute ist ein schöner Tag "")
  3. Berechnen Sie den kürzesten Pfad im Bearbeitungsdiagramm von "Sa" und "Sb"
  4. Folgen Sie dem kürzesten Weg, um die Entsprechung zwischen den Zeichen "Sa" und "Sb" zu erhalten
  5. Berechnen Sie die Token-Entsprechung aus der Zeichenkorrespondenz

Kurz gesagt, nach der richtigen Normalisierung wird die Umkehrung von diff verwendet, um die Entsprechung von Zeichen zu nehmen und die Entsprechung von Token zu berechnen. Der Schlüssel ist 3, der auf die gleiche Weise wie der Bearbeitungsabstand DP berechnet werden kann, beispielsweise unter Verwendung des Myers-Algorithmus zu geringen Kosten. Ich werde. NFKD wurde in 1. übernommen, da der Zeichensatz nach der Normalisierung der kleinste unter der Unicode-Normalisierung ist. Mit anderen Worten kann die Trefferquote so weit wie möglich erhöht werden. Beispielsweise können "bu" und "fu" teilweise von NFKD unterstützt werden, nicht jedoch von NFKC.

>>> a = unicodedata.normalize("NFKD", "Fu")
>>> b = unicodedata.normalize("NFKD", "Bu")
>>> print(a in b)
True
>>> a = unicodedata.normalize("NFKC", "Fu")
>>> b = unicodedata.normalize("NFKC", "Bu")
>>> print(a in b)
False

Implementierung

Die Implementierung wird hier veröffentlicht: GitHub: tamuhey / tokenizations

Es ist Rust, bietet aber auch Python-Bindungen. Die Python-Bibliothek kann wie folgt verwendet werden.

$ pip install pytokenizations
>>> import tokenizations
>>> tokens_a = ['Fu', '##Helt', '##Uns', '##Fuルク', 'Vertrag', 'Zu', 'Fazit']
>>> tokens_b = ['▁', 'Fu', 'Glocke', 'Zu uns', 'Burg', 'Vertrag', 'Zu', 'Fazit']
>>> a2b, b2a = tokenizations.get_alignments(tokens_a, tokens_b)
>>> print(a2b)
[[1], [2, 3], [3], [4], [5], [6], [7]]
>>> print(b2a)
[[], [0], [1], [1, 2], [3], [4], [5], [6]]

Am Ende

Neulich habe ich eine Sprachverarbeitungsbibliothek namens [Camphr] veröffentlicht (https://qiita.com/tamurahey/items/53a1902625ccaac1bb2f), und ich verwende in dieser Bibliothek häufig "Pytokenisierungen". Hiermit wird die Entsprechung zwischen Transformatoren und spaCy berechnet. Dies erleichtert die Kombination der beiden Bibliotheken und macht das Schreiben von Code für jedes Modell überflüssig. Es ist nüchtern, aber ich denke, es ist eine sehr nützliche Funktion im praktischen Gebrauch.

Recommended Posts

Berechnen Sie die Entsprechung zwischen zwei Abteilungen
Untersuchen Sie die Beziehung zwischen zwei Variablen (2)
Berechnen Sie den Zeitunterschied zwischen zwei Spalten mit Pandas DataFrame
Schätzen Sie die Verzögerung zwischen zwei Signalen
Untersuchen Sie die Beziehung zwischen zwei Variablen (1)
Berechnen Sie den Winkel zwischen n-dimensionalen Vektoren mit TensorFlow
Bayes Modellierung-Schätzung des Unterschieds zwischen den beiden Gruppen-
Verschiedene Methoden zur Berechnung der Ähnlichkeit zwischen Daten mit Python
Berechnen Sie die Anzahl der Änderungen
Berechnen Sie die Ähnlichkeit zwischen Sätzen mit Doc2Vec, einer Weiterentwicklung von Word2Vec