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]]
Wenn Sie sich das vorherige Beispiel ansehen, sehen Sie, dass es die folgenden Unterschiede zwischen verschiedenen Abteilungen gibt.
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.
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.
Die beiden Unterteilungen seien "A" und "B". Zum Beispiel ist "A = [" Heute "," ist "," Gut "," Wetter "," Da "]". Die Entsprechung kann wie folgt berechnet werden.
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
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]]
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