File size: 1,230 Bytes
a828eeb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import json
PAD, BOS, EOS, UNK = 0, 1, 2, 3
SPECIALS = ["<pad>", "<bos>", "<eos>", "<unk>"]
class CharTokenizer:
def __init__(self, vocab=None):
self.vocab = vocab or {}
self.inv = {i: c for c, i in self.vocab.items()}
@classmethod
def build(cls, texts, min_freq=20):
from collections import Counter
cnt = Counter()
for t in texts:
cnt.update(t)
vocab = {s: i for i, s in enumerate(SPECIALS)}
for ch, freq in sorted(cnt.items()):
if freq >= min_freq:
vocab[ch] = len(vocab)
return cls(vocab)
def encode(self, text, add_special=True):
ids = [self.vocab.get(c, UNK) for c in text]
return [BOS] + ids + [EOS] if add_special else ids
def decode(self, ids):
return "".join(self.inv.get(i, "") for i in ids
if i not in (PAD, BOS, EOS, UNK))
def save(self, path):
with open(path, "w", encoding="utf-8") as f:
json.dump(self.vocab, f, ensure_ascii=False)
@classmethod
def load(cls, path):
with open(path, encoding="utf-8") as f:
return cls(json.load(f))
def __len__(self):
return len(self.vocab) |