Closed smbslt3 closed 7 months ago
@smbslt3 안녕하세요, Kiwi 형태소 분석기는 가능하다면 음절까지 분할하여 최소 형태소를 찾는걸 목표로 구현되어 있기 때문에 아쉽게도 말씀하신 기능은 아직 없습니다. 다만 몇 가지 대안이 있을듯하네요.
Kiwi.join()
이라는 메소드를 제공하고 있습니다. 토큰을 텍스트로 변환하는 단계에서 후처리가 가능하다면 Kiwi.join()
사용하는걸 추천해드립니다.PreservingKiwiTokenizer
는 후처리 로직을 간단히 구현해본 것입니다.
from kiwipiepy import Kiwi
class PreservingKiwiTokenizer: def init(self): self.kiwi = Kiwi()
def __call__(self, text:str):
tokens = self.kiwi.tokenize(text)
is_oversplit = []
prev_start, prev_end = 0, 0
for token in tokens:
oversplit = max(prev_start, token.start) < min(prev_end, token.end)
if oversplit and is_oversplit:
is_oversplit[-1] = True
is_oversplit.append(oversplit)
prev_start, prev_end = token.start, token.end
ret = []
last = 0
for i, (token, oversplit) in enumerate(zip(tokens, is_oversplit)):
if oversplit:
continue
if last < i and all(is_oversplit[last:i]):
ret.append(text[tokens[last].start:tokens[i - 1].end])
ret.append(token.form)
last = i + 1
return ret
tokenizer = PreservingKiwiTokenizer() tokenizer("가벼운 냉장고를 샀어요.")
다만 약간 의문이 드는 지점은 `PeCab(split_compound=False)`나 `PreservingKiwiTokenizer`처럼 분해를 한다해도 단순히 띄어쓰기를 넣고 이어붙이는 것만으로는 조사나 어미 앞에 모두 공백이 들어가는 문제가 있어서 이 경우에도 결국 완벽한 복원이 어려워 보이는데, 이게 의도하시는 바가 맞으실까요?
join
기능을 쓰면 어떻게 될 것 같긴 했는데 구현해주셔서 감사합니다.
띄어쓰기가 중요한 부분은 아니라 제 경우에는 문제가 되지 않습니다. lime text의 작동 방식이 예를 들어 이진 분류 문제라면, 일부 토큰을 [mask]로 가렸을 때 변화되는 분류 확률값을 그 토큰의 중요도로 간주합니다.
따라서 엄밀히 말하면 원본 문장을 replace 할 수 있는 토큰의 형태를 얻을 수 있으면 됩니다.
샀어요
가 사, ㅆ, 어, 요
로 분리되면 사
나 ㅆ
는 원본 문장에 없어서 "가벼운 냉장고를 샀어요.".replace('사', '[MASK]')
를 실행할 수 없었는데, 지금 주신 코드로는 가능하게 되었습니다.
안녕하세요 kiwipiepy를 여기저기 홍보하며 열심히 쓰고 있는 연구자입니다.
최근 xAI 프레임워크인 lime text를 쓸 일이 있는데, 아시다싶이 요즘 transformer 기반 언어 모델들의 토크나이저는 wordpiece나 sentpiece 기반이라 한국어에서 의미 단위로 토크나이징이 안됩니다. lime에서는 이 부분에 별도의 토크나이저를 입력해주는 방법이 있어 이 부분을 우회할 수 있기는 한데, 문제는 분할 된 토큰을 다시 붙였을 때 원본 문장이 되어야 합니다. 기본값인 str.split()의 경우, 모든 토큰을 붙이고 띄어쓰기를 넣으면 원래 문장이 복원되는 형태입니다. 반면 kiwi의경우 토큰을 단순히 이어붙인다고 원본 문장이 되지 않기 때문에 lime에서는 사용할 수 없습니다.
다른 한국어 토크나이저인 pecab의 경우에는 다음과 같이 두 가지 옵션으로 토크나이징을 할 수 있습니다.
kiwi도 이렇게 원형태를 유지하는 방식으로 tokenizing이 가능할까요?