Last active
July 26, 2023 17:41
-
-
Save alexeyev/532894d514701994363396fb07d6749b to your computer and use it in GitHub Desktop.
Apertium-Kir-Based Tokenizer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
""" | |
Tokenization as it is done in Apertium; may not be blazing fast, | |
since a full-scale morphological analysis is carried out | |
""" | |
import apertium | |
import re | |
from typing import List, Tuple | |
from streamparser import LexicalUnit, reading_to_string | |
SPECIAL_CHARACTERS = list("/^$<>*{}\\@#+~") | |
REPLACEMENTS = ["shashchar", "capchar", "dollarchar", "lesschar", "morechar", "astchar", | |
"curlyleftchar", "curlyrightchar", "backslashchar", "atchar", "hashchar", | |
"pluschar", "tildechar"] | |
assert len(SPECIAL_CHARACTERS) == len(REPLACEMENTS) | |
spchar2code = {ch: co for ch, co in zip(SPECIAL_CHARACTERS, REPLACEMENTS)} | |
code2spchar = {co: ch for ch, co in zip(SPECIAL_CHARACTERS, REPLACEMENTS)} | |
class ApertiumSimpleTokenizer(object): | |
def __init__(self, lang="kir", already_installed=True): | |
""" | |
Loading the analyzer may take time | |
""" | |
if not already_installed: | |
apertium.installer.install_module(lang) | |
self.analyzer = apertium.Analyzer(lang) | |
def tokenize(self, text: str) -> List[str]: | |
for spc in spchar2code: | |
text = text.replace(spc, f" {spchar2code[spc]} ") | |
analysis: List[LexicalUnit] = self.analyzer.analyze(text) | |
decoded = [lu.wordform if lu.wordform not in code2spchar else code2spchar[lu.wordform] for lu in analysis] | |
return [w if len(w) == 1 else w.strip("\\") for w in decoded] | |
def span_tokenize(self, text: str) -> List[Tuple[int, int]]: | |
tokens, results, last_token = self.tokenize(text), [], 0 | |
for token in tokens: | |
start_index_in_reduced = text[last_token:].find(token) | |
if start_index_in_reduced == -1: | |
raise Exception( | |
f"Token not found! \n'{token}' in '{text[last_token - 1:last_token + 10]}';\n " | |
f"tokens: {tokens}.") | |
start_index = start_index_in_reduced + last_token | |
results.append((start_index, start_index + len(token))) | |
last_token = start_index + len(token) | |
return results | |
if __name__ == "__main__": | |
from nltk import TreebankWordTokenizer | |
test_text = """Кыргызстанда ВИЧ/СПИД менен күрөшүүгө акча жетишпейт. | |
Бул тууралуу «24.kg» маалымат агентигине бул дарт менен күрөшүү Республикалык борборунун директору Улан Кадырбеков билдирди. | |
Анын маалыматында, 2003 — жылдан бери Глобалдуу фонд Кыргызстанга ВИЧ/СПИД менен күрөшүүгө 125 миллион доллар бөлгөн. | |
Бул каражат программанын алкагындагы иш чараларга жана дары-дармек сатып алууга жумшалат. | |
Улан Кадырбековдун айтымында, учурда 2018–2020-жылга карата каржылоо кыскартылууда. | |
Быйыл программанын бюджети 11 миллион долларды түзүп, пландалган иш чараларды ишке ашырууга 1,8 миллион доллар жетишпейт. | |
«2017–2021-жылга карата ВИЧ/СПИД менен күрөшүүгө багытталган мамлекеттик программа иштелип чыккан. | |
Ал азыр Каржы министрлигинин кароосунда. | |
Эгер ал ишке аша турган болсо, анда бул илдетке каршы күрөштү мамлекет колго алып, Глобалдуу фонд каржылоону азайтып баштайт» — дейт борбордун жетекчиси.""" | |
# example_tokenizer = TreebankWordTokenizer() | |
# custom_tokenize = lambda sentence: list(example_tokenizer.span_tokenize(sentence)) | |
# print("Default NLTK word tokenizer") | |
# print(example_tokenizer.tokenize(test_text)) | |
# print(custom_tokenize(test_text)) | |
# print() | |
example_tokenizer2 = ApertiumSimpleTokenizer(lang="kir", already_installed="True") | |
custom_tokenize2 = lambda sentence: list(example_tokenizer2.span_tokenize(sentence)) | |
print("Apertium-based word tokenizer") | |
print(example_tokenizer2.tokenize(test_text)) | |
print(custom_tokenize2(test_text)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment