Package kiwipiepy

Kiwipiepy란?

Kiwipiepy는 한국어 형태소 분석기인 Kiwi(Korean Intelligent Word Identifier)의 Python 모듈입니다. C++로 작성되었고 다른 패키지에 의존성이 없으므로 C++ 컴파일이 가능한 환경이라면 어디에서나 Kiwipiepy를 사용 가능합니다.

kiwipiepy

시작하기

pip를 이용해 쉽게 설치할 수 있습니다. (https://pypi.org/project/kiwipiepy/)

$ pip install kiwipiepy

지원하는 OS와 Python 버전은 다음과 같습니다:

  • Python 3.6 이상이 설치된 Linux (x86-64)
  • Python 3.6 이상이 설치된 macOS 10.13이나 그 이후 버전
  • Python 3.6 이상이 설치된 Windows 7 이나 그 이후 버전 (x86, x86-64)
  • Python 3.6 이상이 설치된 다른 OS: 이 경우 소스 코드 컴파일을 위해 C++11이 지원되는 컴파일러가 필요합니다.

Kiwipiepy가 제대로 설치되었는지 확인하기 위해서는 다음 명령어를 실행해보십시오.

$ python -m kiwipiepy

위 명령어는 대화형 인터페이스를 시작합니다. 인터페이스에 원하는 문장을 입력하면 형태소 분석 결과를 확인할 수 있습니다.

>> 안녕?
[Token(form='안녕', tag='IC', start=0, len=2), Token(form='?', tag='SF', start=2, len=3)]

인터페이스를 종료하려면 Ctrl + C 를 누르십시오.

예제

간단한 분석

다음 예제 코드는 kiwipiepy 인스턴스를 생성해 형태소 분석을 수행하는 간단한 예제 코드입니다.

from kiwipiepy import Kiwi
kiwi = Kiwi()
for result, score in kiwi.analyze("형태소 분석 결과입니다", top_n=5):
    print(score, result, sep='\t')

# 위 코드를 실행하면 다음과 같은 결과가 나옵니다.
# -34.33329391479492      [Token(form='형태소', tag='NNG', start=0, len=3), Token(form='분석', tag='NNG', start=4, len=2), Token(form='결과', tag='NNG', start=7, len=2), Token(form='이', tag='VCP', start=9, len=1), Token(form='ᆸ니다', tag='EF', start=10, len=2)]
# -38.10548400878906      [Token(form='형태소', tag='NNG', start=0, len=3), Token(form='분석', tag='NNG', start=4, len=2), Token(form='결과', tag='NNG', start=7, len=2), Token(form='이', tag='MM', start=9, len=1), Token(form='ᆸ니다', tag='EC', start=10, len=2)]
# -51.977012634277344     [Token(form='형태소', tag='NNG', start=0, len=3), Token(form='분석', tag='NNG', start=4, len=2), Token(form='결과', tag='NNG', start=7, len=2), Token(form='이', tag='MM', start=9, len=1), Token(form='ᆸ니다', tag='NNP', start=10, len=2)]
# -51.978363037109375     [Token(form='형태소', tag='NNG', start=0, len=3), Token(form='분석', tag='NNG', start=4, len=2), Token(form='결과', tag='NNG', start=7, len=2), Token(form='이', tag='MM', start=9, len=1), Token(form='ᆸ', tag='NNG', start=10, len=0), Token(form='니', tag='EC', start=10, len=1), Token(form='다', tag='EC', start=11, len=1)]
# -52.152374267578125     [Token(form='형태소', tag='NNG', start=0, len=3), Token(form='분석', tag='NNG', start=4, len=2), Token(form='결과', tag='NNG', start=7, len=2), Token(form='이', tag='MM', start=9, len=1), Token(form='ᆸ', tag='NNG', start=10, len=0), Token(form='니다', tag='EF', start=10, len=2)]

# 간단하게 형태소 분석 결과만 얻고 싶다면 `tokenize` 메소드를 사용하면 됩니다.

result = kiwi.tokenize("형태소 분석 결과입니다")
print(result)
# [Token(form='형태소', tag='NNG', start=0, len=3), Token(form='분석', tag='NNG', start=4, len=2), Token(form='결과', tag='NNG', start=7, len=2), Token(form='이', tag='VCP', start=9, len=1), Token(form='ᆸ니다', tag='EF', start=10, len=2)]

사용자 단어 추가

사용자 정의 단어를 추가하여 형태소 분석을 수행하는 예제입니다. 사용자 정의 단어를 등록하면 이는 Kiwi 분석기의 사전에 포함되어 결과의 후보로 등장할 수 있게 됩니다.

종종 동일한 형태의 단어가 여러 가지로 분석되는 경우가 있습니다. 이 경우 사용자 정의 단어를 우선할지, 분석기가 가지고 있는 형태소 정보를 우선할지 사용자 단어 점수를 조절함으로써 통제 가능합니다. 아래 예제는 '골리'라는 고유 명사 단어가 포함된 문장을 분석하는 경우에 부여하는 단어 점수에 따라 결과가 어떻게 달라지는지를 보여줍니다.

from kiwipiepy import Kiwi

# 사용자 단어 추가 없이 분석해보겠습니다.

kiwi = Kiwi()

print(*kiwi.analyze('사람을 골리다', top_n=5), sep='\n')
# 결과
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('다', 'EC', 6, 1)], -36.505615234375)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('다', 'MAG', 6, 1)], -40.310791015625)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('하', 'XSA', 6, 1), ('다', 'EC', 6, 1)], -40.388427734375)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('하', 'XSV', 6, 1), ('다', 'EC', 6, 1)], -42.22119140625)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('다', 'EF', 6, 1)], -42.44189453125)

print(*kiwi.analyze('골리는 사람이다', top_n=5), sep='\n')
# 결과
# ([('골리', 'VV', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EC', 7, 1)], -39.06201171875)
# ([('골리', 'VV', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EF', 7, 1)], -41.10693359375)
# ([('골리', 'VV', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'JKS', 6, 1), ('다', 'MAG', 7, 1)], -41.588623046875)
# ([('골리', 'VV', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EC', 7, 1)], -41.6220703125)
# ([('골리', 'VV', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'JKS', 6, 1), ('다', 'MAG', 7, 1)], -43.114990234375)

# 사용자 단어 '골리'를 추가해보도록 하겠습니다.
kiwi = Kiwi()
kiwi.add_user_word('골리', 'NNP', 0)

print(*kiwi.analyze('사람을 골리다', top_n=5), sep='\n')
# 결과
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'NNP', 4, 2), ('다', 'EC', 6, 1)], -31.064453125)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'NNP', 4, 2), ('다', 'MAG', 6, 1)], -34.109619140625)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'NNP', 4, 2), ('다', 'EF', 6, 1)], -37.097900390625)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골', 'NNG', 4, 1), ('리다', 'EF', 5, 2)], -45.919189453125)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골', 'VV', 4, 1), ('리다', 'EF', 5, 2)], -49.18359375)

print(*kiwi.analyze('골리는 사람이다', top_n=5), sep='\n')
# 결과
# ([('골리', 'NNP', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EC', 7, 1)], -25.12841796875)
# ([('골리', 'NNP', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'JKS', 6, 1), ('다', 'MAG', 7, 1)], -26.621337890625)
# ([('골리', 'NNP', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EF', 7, 1)], -27.17333984375)
# ([('골리', 'NNP', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EC', 7, 1)], -29.90185546875)
# ([('골리', 'NNP', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EF', 7, 1)], -31.94677734375)

# 사용자 단어 '골리'의 점수를 낮춰서 추가해보도록 하겠습니다.
kiwi = Kiwi()
kiwi.add_user_word('골리', 'NNP', -6)

print(*kiwi.analyze('사람을 골리다', top_n=5), sep='\n')
# 결과
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('다', 'EC', 6, 1)], -36.505615234375)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'NNP', 4, 2), ('다', 'EC', 6, 1)], -37.064453125)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'NNP', 4, 2), ('다', 'MAG', 6, 1)], -40.109619140625)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('다', 'MAG', 6, 1)], -40.310791015625)
# ([('사람', 'NNG', 0, 2), ('을', 'JKO', 2, 1), ('골리', 'VV', 4, 2), ('다', 'EF', 6, 1)], -42.44189453125)

print(*kiwi.analyze('골리는 사람이다', top_n=5), sep='\n')    
# 결과
# ([('골리', 'NNP', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EC', 7, 1)], -31.12841796875)
# ([('골리', 'NNP', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'JKS', 6, 1), ('다', 'MAG', 7, 1)], -32.621337890625)
# ([('골리', 'NNP', 0, 2), ('는', 'JX', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EF', 7, 1)], -33.17333984375)
# ([('골리', 'NNP', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EC', 7, 1)], -35.90185546875)
# ([('골리', 'NNP', 0, 2), ('는', 'ETM', 2, 1), ('사람', 'NNG', 4, 2), ('이', 'VCP', 6, 1), ('다', 'EF', 7, 1)], -37.94677734375)

멀티스레딩 analyze

다음 예제 코드는 멀티스레드를 활용하여 test.txt 파일을 줄별로 읽어들여 형태소 분석한 뒤 그 결과를 result.txt 에 저장합니다.

from kiwipiepy import Kiwi
# 4개의 스레드에서 동시에 처리합니다.
# num_workers 생략시 현재 환경에서 사용가능한 모든 코어를 다 사용합니다.
kiwi = Kiwi(num_workers=4)
with open('result.txt', 'w', encoding='utf-8') as output:
    for res in kiwi.analyze(open('test.txt', encoding='utf-8')):
        output.write(' '.join(map(lambda x:x[0]+'/'+x[1], res[0][0])) + '\n')

Kiwi 생성시 인자로 준 num_workers에 따라 여러 개의 스레드에서 작업이 동시에 처리됩니다. 반환되는 값은 입력되는 값의 순서와 동일합니다.

analyze 를 인자를 str의 iterable로 준 경우 이 iterable을 읽어들이는 시점은 analyze 호출 이후일 수도 있습니다. 따라서 이 인자가 다른 IO 자원(파일 입출력 등)과 연동되어 있다면 모든 분석이 끝나기 전까지 해당 자원을 종료하면 안됩니다. 예를 들어 다음과 같이 open을 통해 생성한 파일 입출력 객체를 미리 종료하는 경우 오류가 발생할 수 있습니다.

from kiwipiepy import Kiwi
kiwi = Kiwi(num_workers=4)
file = open('long_text.txt', encoding='utf-8')
result_iter = kiwi.analyze(file)
file.close() # 파일이 종료됨
next(result_iter) # 종료된 파일에서 분석해야할 다음 텍스트를 읽어들이려고 시도하여 오류 발생

# ValueError: I/O operation on closed file.
# The above exception was the direct cause of the following exception:
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# SystemError: <built-in function next> returned a result with an error set

normalize_coda 0.10.2버전부터 normalize_coda 기능이 추가되었습니다. 이 기능은 웹이나 채팅 텍스트 데이터에서 자주 쓰이는 ㅋㅋㅋ, ㅎㅎㅎ와 같은 초성체가 어절 뒤에 붙는 경우 분석에 실패하는 경우를 막아줍니다.

from kiwipiepy import Kiwi
kiwi = Kiwi()
kiwi.tokenize("안 먹었엌ㅋㅋ", normalize_coda=False)
# [Token(form='안', tag='NNP', start=0, len=1), Token(form='먹었엌', tag='NNP', start=2, len=3), Token(form='ㅋㅋ', tag='SW', start=5, len=2)]
kiwi.tokenize("안 먹었엌ㅋㅋ", normalize_coda=True)
# [Token(form='안', tag='MAG', start=0, len=1), Token(form='먹', tag='VV', start=2, len=1), Token(form='었', tag='EP', start=3, len=1), Token(form='어', tag='EF', start=4, len=1), Token(form='ㅋㅋㅋ', tag='SW', start=5, len=2)]

0.10.0 버전 변경사항

0.10.0 버전에서는 일부 불편한 메소드들이 좀 더 편한 형태로 개량되었습니다. 변경된 메소드들은 analyze , perform , extract_words , extract_filter_words , extract_add_words 입니다. 그리고 async_analyze 함수는 analyze 함수의 멀티스레딩 버전으로 통합되어 제거되었습니다. 또한 prepare 함수를 별도로 호출할 필요가 없도록 변경되었습니다. 이전 버전의 사용법에 대해서는 이전 버전의 문서를 참조하십시오.

0.10.0 이후 버전의 analyze, perform 사용법

from kiwipiepy import Kiwi

kiwi = Kiwi()
kiwi.load_user_dictionary('userDict.txt')
with open('result.txt', 'w', encoding='utf-8') as out:
    for res in kiwi.analyze(open('test.txt', encoding='utf-8')):
        score, tokens = res[0] # top-1 결과를 가져옴
        print(' '.join(map(lambda x:x.form + '/' + x.tag, tokens), file=out)

# perform 함수의 경우
'''
perform 함수의 입력은 여러 번 순회 가능해야합니다.
따라서 str의 list 형태이거나 iterable을 반환하도록 입력을 넣어주어야 합니다.
'''
inputs = list(open('test.txt', encoding='utf-8'))
with open('result.txt', 'w', encoding='utf-8') as out:
    for res in kiwi.perform(inputs):
        score, tokens = res[0] # top-1 결과를 가져옴
        print(' '.join(map(lambda x:x.form + '/' + x.tag, tokens), file=out)

'''
list(open('test.txt', encoding='utf-8'))의 경우 
모든 입력을 미리 list로 저장해두므로
test.txt 파일이 클 경우 많은 메모리를 소모할 수 있습니다.
그 대신 파일에서 필요한 부분만 가져와 사용하도록(streaming) 할 수도 있습니다.
'''

class IterableTextFile:
    def __init__(self, path):
        self.path = path

    def __iter__(self):
        yield from open(path, encoding='utf-8')

with open('result.txt', 'w', encoding='utf-8') as out:
    for res in kiwi.perform(IterableTextFile('test.txt')):
        score, tokens = res[0] # top-1 결과를 가져옴
        print(' '.join(map(lambda x:x.form + '/' + x.tag, tokens), file=out)

extract_words , extract_add_words 역시 perform과 마찬가지로 str의 list를 입력하거나 위의 예시의 IterableTextFile 처럼 str의 iterable을 반환하는 객체를 만들어 사용하면 됩니다.

0.10.0 이후 버전의 extract_words의 사용법

class IterableTextFile:
    def __init__(self, path):
        self.path = path

    def __iter__(self):
        yield from open(path, encoding='utf-8')

kiwi.extract_words(IterableTextFile('test.txt'), 10, 10, 0.25)
# 아니면 그냥 str의 list를 입력해도 됩니다.

사용자 정의 사전 포맷

사용자 정의 사전은 UTF-8로 인코딩된 텍스트 파일이어야 하며, 다음과 같은 구조를 띄어야 합니다.

#으로 시작하는 줄은 주석 처리됩니다.
# 각 필드는 Tab(\t)문자로 구분됩니다.
#
# <단일 형태소를 추가하는 경우>
# (형태) \t (품사태그) \t (점수)
# * (점수)는 생략시 0으로 처리됩니다.
키위  NNP -5.0

# <이미 존재하는 형태소의 이형태를 추가하는 경우>
# (이형태) \t (원형태소/품사태그) \t (점수)
# * (점수)는 생략시 0으로 처리됩니다.
기위  키위/NNG  -3.0

# <기분석 형태를 추가하는 경우>
# (형태) \t (원형태소/품사태그 + 원형태소/품사태그 + ...) \t (점수)
# * (점수)는 생략시 0으로 처리됩니다.
사겼다 사귀/VV + 었/EP + 다/EF -1.0
#
# 현재는 공백을 포함하는 다어절 형태를 등록할 수 없습니다.
#
# <규칙 기반의 변형된 이형태를 추가하는 경우>
# (형태 규칙)$ \t (변형된 형태/품사태그) \t (점수)
# 예) 요$ 용/EF    -5

단어점수는 생략 가능하며, 생략 시 기본값인 0으로 처리됩니다. 실제 예시에 대해서는 Kiwi에 내장된 기본 사전 파일인 https://raw.githubusercontent.com/bab2min/Kiwi/main/ModelGenerator/default.dict 을 참조해주세요.

또한 0.14.0버전부터 내장된 기본 오타 사전이 추가되었습니다. 이에 대해서는 https://raw.githubusercontent.com/bab2min/Kiwi/main/ModelGenerator/typo.dict 을 참조해주세요.

언어 모델

Kiwi는 최적의 형태소 조합을 탐색하기 위해 내부적으로 언어 모델을 사용합니다. 0.13.0 버전 이전까지는 Kneser-ney 언어 모델(knlm)만을 사용했지만, 0.13.0버전부터 SkipBigram(sbg)이라는 새로운 언어 모델에 대한 지원이 추가되었습니다. 기본값은 knlm로 설정되어 있지만, 상황에 따라 이용자가 더 적절한 모델을 선택하여 사용할 수 있습니다. 각 모델의 특징은 다음과 같습니다.

  • knlm: 0.12.0버전까지 기본적으로 제공되던 모델로, 속도가 빠르고 짧은 거리 내의 형태소(주로 2~3개) 간의 관계를 높은 정확도로 모델링할 수 있습니다. 그러나 먼 거리의 형태소 간의 관계는 고려하지 못하는 한계가 있습니다.
  • sbg: 0.13.0버전에서 추가된 모델로, sbg를 사용시 내부적으로 knlm의 결과에 SkipBigram 결과를 보정하는 식으로 구동됩니다. knlm에 비해 약 30%정도 처리 시간이 늘어나지면, 먼 거리의 형태소(실질 형태소 기준 최대 8개까지) 간의 관계를 적당한 정확도로 모델링할 수 있습니다.

두 모델 간의 분석 결과 차이는 다음처럼 형태소의 모호성이 먼 거리의 형태소를 통해 해소되는 경우 잘 드러납니다.

>> kiwi = Kiwi(model_type='knlm')
>> kiwi.tokenize('이 번호로 전화를 이따가 꼭 반드시 걸어.')
[Token(form='이', tag='MM', start=0, len=1), 
 Token(form='번호', tag='NNG', start=2, len=2), 
 Token(form='로', tag='JKB', start=4, len=1), 
 Token(form='전화', tag='NNG', start=6, len=2), 
 Token(form='를', tag='JKO', start=8, len=1), 
 Token(form='이따가', tag='MAG', start=10, len=3), 
 Token(form='꼭', tag='MAG', start=14, len=1), 
 Token(form='반드시', tag='MAG', start=16, len=3), 
 Token(form='걷', tag='VV-I', start=20, len=1),  # 걷다/걸다 중 틀리게 '걷다'를 선택했음.
 Token(form='어', tag='EF', start=21, len=1), 
 Token(form='.', tag='SF', start=22, len=1)]

>> kiwi = Kiwi(model_type='sbg')
>> kiwi.tokenize('이 번호로 전화를 이따가 꼭 반드시 걸어.')
[Token(form='이', tag='MM', start=0, len=1), 
 Token(form='번호', tag='NNG', start=2, len=2), 
 Token(form='로', tag='JKB', start=4, len=1), 
 Token(form='전화', tag='NNG', start=6, len=2), 
 Token(form='를', tag='JKO', start=8, len=1), 
 Token(form='이따가', tag='MAG', start=10, len=3), 
 Token(form='꼭', tag='MAG', start=14, len=1), 
 Token(form='반드시', tag='MAG', start=16, len=3), 
 Token(form='걸', tag='VV', start=20, len=1), # 걷다/걸다 중 바르게 '걸다'를 선택했음.
 Token(form='어', tag='EC', start=21, len=1), 
 Token(form='.', tag='SF', start=22, len=1)]

오타 교정

연속적인 문자열을 처리하는 모델의 경우, 특정 지점에서 분석 오류가 발생하면 그 오류 때문에 뒤따르는 분석 결과들이 전부 틀려버리는 경우가 종종 있습니다. 이를 개선하기 위해 0.13.0버전부터 간단한 수준의 오타를 자동으로 교정하는 기능이 추가되었습니다. 오타 교정을 위해서는 특정 형태소가 어떤 식으로 오타로 변형되는지 정의한, 오타 정의자가 필요합니다. 패키지에 내장된 기본 오타 정의자인 basic_typos 혹은 'basic' 를 사용해도 되고, 직접 오타를 정의할 수도 있습니다.

>> from kiwipiepy import Kiwi, TypoTransformer, TypoDefinition, basic_typo
>> kiwi = Kiwi(typos=basic_typo) # basic_typo 대신 str으로 'basic'이라고 입력해도 됨
>> kiwi.tokenize('외않됀대?') # 초기에는 로딩 시간으로 5~10초 정도 소요됨
[Token(form='왜', tag='MAG', start=0, len=1),
 Token(form='안', tag='MAG', start=1, len=1),
 Token(form='되', tag='VV', start=2, len=1),
 Token(form='ᆫ대', tag='EF', start=2, len=2),
 Token(form='?', tag='SF', start=4, len=1)]
>> kiwi.typo_cost_weight = 6 # 오타 교정 비용을 변경할 수 있음. 기본값은 6
>> kiwi.tokenize('일정표를 게시했다')
[Token(form='일정표', tag='NNG', start=0, len=3),
 Token(form='를', tag='JKO', start=3, len=1), 
 Token(form='게시', tag='NNG', start=5, len=2), 
 Token(form='하', tag='XSV', start=7, len=1), 
 Token(form='었', tag='EP', start=7, len=1), 
 Token(form='다', tag='EF', start=8, len=1)]

>> kiwi.typo_cost_weight = 2 # 교정 비용을 낮추면 더 적극적으로 교정을 수행함. 맞는 표현도 과도교정될 수 있으니 주의
>> kiwi.tokenize('일정표를 게시했다')
[Token(form='일정표', tag='NNG', start=0, len=3),
 Token(form='를', tag='JKO', start=3, len=1), 
 Token(form='개시', tag='NNG', start=5, len=2), # '게시'가 맞는 표현이지만 '개시'로 잘못 교정되었음
 Token(form='하', tag='XSV', start=7, len=1), 
 Token(form='었', tag='EP', start=7, len=1), 
 Token(form='다', tag='EF', start=8, len=1)]

오타 정의자를 직접 정의하는 방법에 대해서는 TypoTransformer 를 참조하십시오. 현재 Kiwi에서 수행하는 오타 교정은 각각의 형태소를 경계로 적용되기에 여러 형태소를 넘나드는 오타는 교정하지 못합니다.

오타 교정 기능을 사용할 경우 Kiwi 초기화 시에 약 5~10초 정도의 시간이 추가로 소요되며, 문장 당 처리시간은 2배 정도로 늘어납니다. 메모리 사용량은 약 2~3배 정도 증가합니다.

데모

https://lab.bab2min.pe.kr/kiwi 에서 데모를 실행해 볼 수 있습니다.

라이센스

Kiwi는 LGPL v3 라이센스로 배포됩니다.

오류 제보

Kiwipiepy 사용 중 오류 발생시 깃헙 이슈탭을 통해 제보해주세요.

Python 모듈 관련 오류는 https://github.com/bab2min/kiwipiepy/issues, 형태소 분석기 전반에 대한 오류는 https://github.com/bab2min/kiwi/issues 에 올려주시면 감사하겠습니다.

태그 목록

세종 품사 태그를 기초로 하되, 일부 품사 태그를 추가/수정하여 사용하고 있습니다.

대분류태그설명
체언(N)NNG일반 명사
NNP고유 명사
NNB의존 명사
NR수사
NP대명사
용언(V)VV동사
VA형용사
VX보조 용언
VCP긍정 지시사(이다)
VCN부정 지시사(아니다)
관형사MM관형사
부사(MA)MAG일반 부사
MAJ접속 부사
감탄사IC감탄사
조사(J)JKS주격 조사
JKC보격 조사
JKG관형격 조사
JKO목적격 조사
JKB부사격 조사
JKV호격 조사
JKQ인용격 조사
JX보조사
JC접속 조사
어미(E)EP선어말 어미
EF종결 어미
EC연결 어미
ETN명사형 전성 어미
ETM관형형 전성 어미
접두사XPN체언 접두사
접미사(XS)XSN명사 파생 접미사
XSV동사 파생 접미사
XSA형용사 파생 접미사
어근XR어근
부호, 외국어, 특수문자(S)SF종결 부호(. ! ?)
SP구분 부호(, / : ;)
SS인용 부호 및 괄호(' " ( ) [ ] < > { } ― ‘ ’ “ ” ≪ ≫ 등)
SSOSS 중 여는 부호
SSCSS 중 닫는 부호
SE줄임표(…)
SO붙임표(- ~)
SW기타 특수 문자
SL알파벳(A-Z a-z)
SH한자
SN숫자(0-9)
분석 불능UN분석 불능*
웹(W)W_URLURL 주소*
W_EMAIL이메일 주소*
W_HASHTAG해시태그(#abcd)*
W_MENTION멘션(@abcd)*
W_SERIAL일련번호(전화번호, 통장번호, IP주소 등)*

* 세종 품사 태그와 다른 독자적인 태그입니다.

0.12.0 버전부터 VV, VA, VX, XSA 태그에 불규칙 활용여부를 명시하는 접미사 -R-I이 덧붙을 수 있습니다. -R은 규칙 활용,-I은 불규칙 활용을 나타냅니다.

역사

  • 0.14.0 (2022-09-01)

    • Kiwi 0.14.0의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.14.0 )이 반영되었습니다.
      • 동사 '이르다'의 모호성 해소 기능 추가
      • W_SERIAL 태그 추가. SS 태그를 SSO, SSC 태그로 세분화
      • 인용문 등으로 둘러싸인 안긴 문장이 포함된 문장에 대해 문장 분리 성능 개선
      • 랬/댔/잖의 분석 정확도 개선
      • 내장 오타 사전 추가. 사용을 원치 않는 경우 Kiwi(load_typo_dict=False)로 끌 수 있습니다.
    • 각종 버그가 수정되었습니다.
      • 오타 교정 기능이 켜져 있는 경우 Kiwi.join()이 실패하는 문제 해결
      • 사용자 사전에 숫자를 포함한 NNP를 추가해도 반영이 되지 않는 문제 해결
      • Kiwi.join()이 일부 텍스트를 잘못 결합시키는 오류 해결
  • 0.13.1 (2022-07-05)

  • 0.13.0 (2022-06-28)

    • Kiwi 0.13.0의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.13.0 )이 반영되었습니다.
      • 형태소 분석 시 간단한 오타 교정을 수행하는 기능 추가
      • SkipBigram 언어 모델 추가. Kiwi(model_type='sbg') 로 사용 가능
      • 분석 결과에서 개별 형태소의 오타 교정 비용을 반환하는 Token.typo_cost 필드, 오타 교정 전 형태를 반환하는 Token.raw_form 필드 추가
    • 각종 버그가 수정되었습니다.
      • 배포 판에서 stopwords.txt 파일이 누락되었던 버그 수정
  • 0.12.0 (2022-05-10)

    • Kiwi 0.12.0의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.12.0 )이 반영되었습니다.
      • 형태소에 불규칙 활용 여부를 반영하는 Token.regularity 필드 추가
      • 분석 결과에서 개별 형태소의 언어 모델 점수를 반영하는 Token.score 필드 추가
      • 동사 '걷다'와 '묻다'의 모호성 해소 기능 추가
      • 형태소 결합 기능을 수행하는 Kiwi.join() 메소드 추가
    • 각종 버그가 수정되었습니다.
      • 특정 상황에서 소수점 패턴이 숫자 - 마침표 - 숫자로 오분석되는 버그
      • 문장 분리 시 종결어미 - 조사로 이어지는 한 문장이 두 문장으로 분리되는 버그
      • 있소, 잇따라, 하셔 등의 표현이 제대로 분석되지 않는 버그
  • 0.11.2 (2022-04-14)

    • Kiwi 0.11.2의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.11.2 )이 반영되었습니다.
      • 특수 문자가 섞인 텍스트 중 일부가 잘못 분석되는 버그가 수정되었습니다.
      • 특정한 패턴의 텍스트를 입력할 경우 분석 결과가 빈 값으로 나오는 버그가 수정되었습니다.
      • 받침 정규화 기능(normalizeCoda)이 모든 받침에 대해 적용되었습니다.
    • Kiwi.tokenize()echo 인자가 추가되었습니다.
  • 0.11.1 (2022-04-03)

    • Kiwi 0.11.1의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.11.1 )이 반영되었습니다.
      • Windows 환경에서 한글이나 기타 유니코드를 포함한 경로에 위치한 모델을 읽지 못하는 버그가 수정되었습니다.
      • 이제 소수점, 자리 구분 쉼표가 섞인 숫자도 SN 품사태그로 제대로 분석됩니다.
      • Kiwi.space_tolerance, Kiwi.space_penalty 프로퍼티가 추가되었습니다.
    • 여러 줄의 텍스트를 결합할 때 공백을 적절히 삽입해주는 메소드인 Kiwi.glue(), 띄어쓰기 교정을 실시하는 메소드인 Kiwi.space()가 추가되었습니다.
  • 0.11.0 (2022-03-19)

    • Kiwi 0.11.0의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.11.0 )이 반영되었습니다.
      • 이용자 사전을 관리하는 메소드 Kiwi.add_pre_analyzed_word(), Kiwi.add_rule(), Kiwi.add_re_rule()가 추가되었습니다.
      • 분석 시 접두사/접미사 및 동/형용사 파생접미사의 분리여부를 선택할 수 있는 옵션 Match.JOIN_NOUN_PREFIX, Match.JOIN_NOUN_SUFFIX, Match.JOIN_VERB_SUFFIX, Match.JOIN_ADJ_SUFFIX가 추가되었습니다.
      • 결합된 형태소 Tokenstart, end, length가 부정확한 버그를 수정했습니다.
      • 이제 형태소 결합 규칙이 Kiwi 모델 내로 통합되어 Kiwi.add_user_word()로 추가된 동/형용사의 활용형도 정상적으로 분석이 됩니다.
      • 언어 모델의 압축 알고리즘을 개선하여 초기 로딩 속도를 높였습니다.
      • SIMD 최적화가 개선되었습니다.
      • 언어 모델 및 기본 사전을 업데이트하여 전반적인 정확도를 높였습니다.
      • 문장 분리 기능의 정확도가 향상되었습니다.
  • 0.10.3 (2021-12-22)

  • 0.10.2 (2021-11-12)

    • Kiwi 0.10.2의 기능들(https://github.com/bab2min/Kiwi/releases/tag/v0.10.2 )이 반영되었습니다.
      • Tokenword_position 프로퍼티가 추가되었습니다.
      • Kiwi.analyze()normalize_coda 인자가 추가되었습니다.
    • Kiwi.tokenize() 메소드가 추가되었습니다. analyze 메소드와는 다르게 바로 분서결과인 Tokenlist를 반환하므로 더 간편하게 사용할 수 있습니다.
    • 불용어 관리 기능을 제공하는 Stopwords 클래스가 추가되었습니다.
  • 0.10.1 (2021-09-06)

    • macOS에서 pip를 통한 설치가 제대로 지원되지 않던 문제를 해결했습니다.
    • load_user_dictionary 사용시 품사 태그 뒤에 공백문자가 뒤따르는 경우 태그 해석에 실패하는 문제를 해결했습니다.
  • 0.10.0 (2021-08-15)

    • API를 Python에 걸맞게 개편하였습니다. 일부 불편한 메소드들은 사용법이 변경되거나 삭제되었습니다. 이에 대해서는 0.10.0 버전 변경사항 단락을 확인해주세요.
    • prepare 없이 analyze 를 호출할 때 크래시가 발생하던 문제를 수정했습니다.
    • Linux 환경에서 extract_words 를 호출할 때 크래시가 발생하던 문제를 수정했습니다.
    • Linux 환경에서 Options.INTEGRATE_ALLOMORPH 를 사용시 크래시가 발생하던 문제를 수정했습니다.
    • 이제 형태소 분석 결과가 tuple 이 아니라 Token 타입으로 반환됩니다.
    • 형태소 분석 모델 포맷이 최적화되어 파일 크기가 약 20% 작아졌습니다.
  • 0.9.3 (2021-06-06)

    • Linux 환경에서 특정 단어가 포함된 텍스트를 분석할 때 크래시가 발생하던 문제를 수정했습니다.
  • 0.9.2 (2020-12-03)

    • 0.9.1에서 제대로 수정되지 않은 mimalloc 충돌 문제를 수정했습니다.
    • 형태소 분석 모델을 분리하여 패키징하는 기능을 추가했습니다. 용량 문제로 업로드 못했던 대용량 모델을 차차 추가해나갈 예정입니다.
  • 0.9.1 (2020-12-03)

    • kiwipiepy가 다른 Python 패키지와 함께 사용될 경우 종종 mimalloc이 충돌하는 문제를 해결했습니다.
  • 0.9.0 (2020-11-26)

    • analyze 메소드에서 오류 발생시 exception 발생대신 프로그램이 죽는 문제를 해결했습니다.
    • default.dict 에 포함된 활용형 단어 때문에 발생하는 오분석을 수정했습니다.
    • 멀티스레딩 사용시 발생하는 메모리 누수 문제를 해결했습니다.
    • 형태소 탐색 시 조사/어미의 결합조건을 미리 고려하도록 변경하여 속도가 개선되었습니다.
    • 일부 명사(전랑 처럼 받침 + 랑으로 끝나는 사전 미등재 명사) 입력시 분석이 실패하는 버그를 수정했습니다.
    • 공백문자만 포함된 문자열 입력시 분석결과가 /UN 로 잘못나오는 문제를 수정했습니다.
  • 0.8.2 (2020-10-13)

    • W_URL, W_EMAIL, W_HASHTAG 일치 이후 일반 텍스트가 잘못 분석되는 오류를 수정했습니다.
    • W_MENTION을 추가했습니다.
    • 특정 상황에서 결합조건이 무시되던 문제를 해결했습니다. (ex: 고기를 굽다 -> 고기/NNG + 를/JKO + 굽/VV + 이/VCP + 다/EF + ./SF )
  • 0.8.1 (2020-04-01)

    • U+10000 이상의 유니코드 문자를 입력시 Python 모듈에서 오류가 발생하는 문제를 수정했습니다.
  • 0.8.0 (2020-03-29)

    • URL, 이메일, 해시태그를 검출하는 기능이 추가되었습니다. analyze 메소드의 match_options 파라미터로 이 기능의 사용 유무를 설정할 수 있습니다.
    • 치(하지), 컨대(하건대), 토록(하도록), 케(하게) 축약형이 포함된 동사 활용형을 제대로 분석하지 못하는 문제를 해결했습니다.
    • 사용자 사전에 알파벳이나 숫자, 특수 기호가 포함된 단어가 있을 때, 형태소 분석시 알파벳, 숫자, 특수 기호가 포함된 문장이 제대로 분석되지 않는 문제를 수정했습니다.
    • 사용자 사전에 형태는 같으나 품사가 다른 단어를 등록할 수 없는 제한을 해제하였습니다.
  • 0.7.6 (2020-03-24)

    • async_analyze 메소드가 추가되었습니다. 이 메소드는 형태소 분석을 비동기로 처리합니다. 처리 결과는 callable인 리턴값을 호출하여 얻을 수 있습니다.
    • U+10000 이상의 유니코드 문자에 대해 형태소 분석 결과의 위치 및 길이가 부정확하게 나오는 문제를 해결했습니다.
  • 0.7.5 (2020-03-04)

    • U+10000 이상의 문자를 입력시 extract 계열 함수에서 종종 오류가 발생하던 문제를 해결했습니다.
    • gcc 4.8 환경 및 manylinux 대한 지원을 추가했습니다.
  • 0.7.4 (2019-12-30)

    • reader, receiver를 사용하는 함수 계열에서 메모리 누수가 발생하던 문제를 해결했습니다.
    • 문서 내 reader, receiver의 사용법 내의 오류를 적절하게 수정했습니다.
    • 종종 분석 결과에서 빈 /UN 태그가 등장하는 문제를 수정했습니다.
    • 일부 특수문자를 분석하는데 실패하는 오류를 수정했습니다.
  • 0.7.3 (2019-12-15)

    • macOS 환경에서 extract 계열 함수를 호출할때 스레드 관련 오류가 발생하는 문제를 해결했습니다.
  • 0.7.2 (2019-12-01)

  • 0.7.1 (2019-09-23)

    • 사전 로딩 속도를 개선했습니다.
    • 음운론적 이형태 통합여부를 선택할 수 있도록 옵션을 추가했습니다.
  • 0.6.5 (2019-06-22)

  • 0.6.4 (2019-06-09)

  • 0.6.3 (2019-04-14)

    • 예외를 좀 더 정교하게 잡아내도록 수정했습니다.
    • 형태소 분석을 바로 테스트해볼 수 있도록 모듈에 대화형 인터페이스를 추가했습니다.
  • 0.6.1 (2019-03-26)

  • 0.6.0 (2018-12-04)

    • 형태소 검색 알고리즘 최적화로 분석 속도가 향상되었습니다.
    • 전반적인 정확도가 상승되었습니다.
  • 0.5.4 (2018-10-11)

  • 0.5.2 (2018-09-29)

  • 0.5.0 (2018-09-16)

    • Python 모듈 지원이 추가되었습니다.
Expand source code
"""
.. include:: ./documentation.md
"""
from _kiwipiepy import Token
from kiwipiepy._version import __version__
from kiwipiepy._wrap import Kiwi, Sentence, TypoTransformer, TypoDefinition
import kiwipiepy.utils as utils
from kiwipiepy.const import Match, Option

Kiwi.__module__ = 'kiwipiepy'
TypoTransformer.__module__ = 'kiwipiepy'
TypoDefinition.__module__ = 'kiwipiepy'
Sentence.__module__ = 'kiwipiepy'

basic_typos = TypoTransformer([
    TypoDefinition(["ㅐ", "ㅔ"], ["ㅐ", "ㅔ"], 1.),
    TypoDefinition(["ㅐ", "ㅔ"], ["ㅒ", "ㅖ"], 1.5),
    TypoDefinition(["ㅒ", "ㅖ"], ["ㅐ", "ㅔ"], 1.5),
    TypoDefinition(["ㅒ", "ㅖ"], ["ㅒ", "ㅖ"], 1.),
    TypoDefinition(["ㅚ", "ㅙ", "ㅞ"], ["ㅚ", "ㅙ", "ㅞ", "ㅐ", "ㅔ"], 1.),
    TypoDefinition(["ㅝ"], ["ㅗ", "ㅓ"], 1.),
    TypoDefinition(["ㅟ", "ㅢ"], ["ㅣ"], 1.),
    TypoDefinition(["위", "의"], ["이"], float("inf")),
    TypoDefinition(["위", "의"], ["이"], 1., "any"),
    TypoDefinition(["자", "쟈"], ["자", "쟈"], 1.),
    TypoDefinition(["재", "쟤"], ["재", "쟤"], 1.),
    TypoDefinition(["저", "져"], ["저", "져"], 1.),
    TypoDefinition(["제", "졔"], ["제", "졔"], 1.),
    TypoDefinition(["조", "죠", "줘"], ["조", "죠", "줘"], 1.),
    TypoDefinition(["주", "쥬"], ["주", "쥬"], 1.),
    TypoDefinition(["차", "챠"], ["차", "챠"], 1.),
    TypoDefinition(["채", "챼"], ["채", "챼"], 1.),
    TypoDefinition(["처", "쳐"], ["처", "쳐"], 1.),
    TypoDefinition(["체", "쳬"], ["체", "쳬"], 1.),
    TypoDefinition(["초", "쵸", "춰"], ["초", "쵸", "춰"], 1.),
    TypoDefinition(["추", "츄"], ["추", "츄"], 1.),
    TypoDefinition(["유", "류"], ["유", "류"], 1.),
    TypoDefinition(["므", "무"], ["므", "무"], 1.),
    TypoDefinition(["브", "부"], ["브", "부"], 1.),
    TypoDefinition(["프", "푸"], ["프", "푸"], 1.),
    TypoDefinition(["르", "루"], ["르", "루"], 1.),
    TypoDefinition(["러", "뤄"], ["러", "뤄"], 1.),
    TypoDefinition(["\ㄲ", "\ㄳ"], ["\ㄱ", "\ㄲ", "\ㄳ"], 1.5),
    TypoDefinition(["\ㄵ", "\ㄶ"], ["\ㄴ", "\ㄵ", "\ㄶ"], 1.5),
    TypoDefinition(["\ㄺ", "\ㄻ", "\ㄼ", "\ㄽ", "\ㄾ", "\ㄿ", "\ㅀ"], ["\ㄹ", "\ㄺ", "\ㄻ", "\ㄼ", "\ㄽ", "\ㄾ", "\ㄿ", "\ㅀ"], 1.5),
    TypoDefinition(["\ㅅ", "\ㅆ"], ["\ㅅ", "\ㅆ"], 1.),

    TypoDefinition(["안"], ["않"], 1.5),
    TypoDefinition(["맞추", "맞히"], ["맞추", "맞히"], 1.5),
    TypoDefinition(["맞춰", "맞혀"], ["맞춰", "맞혀"], 1.5),
    TypoDefinition(["받치", "바치", "받히"], ["받치", "바치", "받히"], 1.5),
    TypoDefinition(["받쳐", "바쳐", "받혀"], ["받쳐", "바쳐", "받혀"], 1.5),
    TypoDefinition(["던", "든"], ["던", "든"], 1.),
    TypoDefinition(["때", "데"], ["때", "데"], 1.5),
    TypoDefinition(["빛", "빚"], ["빛", "빚"], 1.),

    TypoDefinition(["\ㄷ이", "지"], ["\ㄷ이", "지"], 1.),
    TypoDefinition(["\ㄷ여", "져"], ["\ㄷ여", "져"], 1.),
    TypoDefinition(["\ㅌ이", "치"], ["\ㅌ이", "치"], 1.),
    TypoDefinition(["\ㅌ여", "쳐"], ["\ㅌ여", "쳐"], 1.),
        
    TypoDefinition(["ㄱ", "ㄲ"], ["ㄱ", "ㄲ"], 1., "applosive"),
    TypoDefinition(["ㄷ", "ㄸ"], ["ㄷ", "ㄸ"], 1., "applosive"),
    TypoDefinition(["ㅂ", "ㅃ"], ["ㅂ", "ㅃ"], 1., "applosive"),
    TypoDefinition(["ㅅ", "ㅆ"], ["ㅅ", "ㅆ"], 1., "applosive"),
    TypoDefinition(["ㅈ", "ㅉ"], ["ㅈ", "ㅉ"], 1., "applosive"),

    TypoDefinition(["\ㅎㅎ", "\ㄱㅎ", "\ㅎㄱ"], ["\ㅎㅎ", "\ㄱㅎ", "\ㅎㄱ"], 1.),

    TypoDefinition(["\ㄱㄴ", "\ㄲㄴ", "ᆪㄴ", "ᆿㄴ", "ᆼㄴ"], ["\ㄱㄴ", "\ㄲㄴ", "ᆪㄴ", "ᆿㄴ", "ᆼㄴ"], 1.),
    TypoDefinition(["\ㄱㅁ", "\ㄲㅁ", "ᆪㅁ", "ᆿㅁ", "ᆼㅁ"], ["\ㄱㅁ", "\ㄲㅁ", "ᆪㅁ", "ᆿㅁ", "ᆼㅁ"], 1.),
    TypoDefinition(["\ㄱㄹ", "\ㄲㄹ", "ᆪㄹ", "ᆿㄹ", "ᆼㄹ", "ᆼㄴ",], ["\ㄱㄹ", "\ㄲㄹ", "ᆪㄹ", "ᆿㄹ", "ᆼㄹ", "ᆼㄴ",], 1.),
    TypoDefinition(["\ㄷㄴ", "\ㅅㄴ", "\ㅆㄴ", "\ㅈㄴ", "ᆾㄴ", "ᇀㄴ", "\ㄴㄴ"], ["\ㄷㄴ", "\ㅅㄴ", "\ㅆㄴ", "\ㅈㄴ", "ᆾㄴ", "ᇀㄴ", "\ㄴㄴ"], 1.),
    TypoDefinition(["\ㄷㅁ", "\ㅅㅁ", "\ㅆㅁ", "\ㅈㅁ", "ᆾㅁ", "ᇀㅁ", "\ㄴㅁ"], ["\ㄷㅁ", "\ㅅㅁ", "\ㅆㅁ", "\ㅈㅁ", "ᆾㅁ", "ᇀㅁ", "\ㄴㅁ"], 1.),
    TypoDefinition(["\ㄷㄹ", "\ㅅㄹ", "\ㅆㄹ", "\ㅈㄹ", "ᆾㄹ", "ᇀㄹ", "\ㄴㄹ", "\ㄴㄴ",], ["\ㄷㄹ", "\ㅅㄹ", "\ㅆㄹ", "\ㅈㄹ", "ᆾㄹ", "ᇀㄹ", "\ㄴㄹ", "\ㄴㄴ",], 1.),
    TypoDefinition(["\ㅂㄴ", "ᆹㄴ", "ᇁㄴ", "\ㅁㄴ"], ["\ㅂㄴ", "ᆹㄴ", "ᇁㄴ", "\ㅁㄴ"], 1.),
    TypoDefinition(["\ㅂㅁ", "ᆹㅁ", "ᇁㅁ", "\ㅁㅁ"], ["\ㅂㅁ", "ᆹㅁ", "ᇁㅁ", "\ㅁㅁ"], 1.),
    TypoDefinition(["\ㅂㄹ", "ᆹㄹ", "ᇁㄹ", "\ㅁㄹ", "\ㅁㄴ",], ["\ㅂㄹ", "ᆹㄹ", "ᇁㄹ", "\ㅁㄹ", "\ㅁㄴ",], 1.),
    TypoDefinition(["\ㄴㄹ", "\ㄴㄴ", "\ㄹㄹ", "\ㄹㄴ"], ["\ㄴㄹ", "\ㄴㄴ", "\ㄹㄹ", "\ㄹㄴ"], 1.),
        
    TypoDefinition(["\ㄱㅇ", "ㄱ"], ["\ㄱㅇ", "ㄱ"], 1., "vowel"),
    TypoDefinition(["\ㄲㅇ", "ㄲ"], ["\ㄲㅇ", "ㄲ"], 1., "vowel"),
    TypoDefinition(["\ㄴㅇ", "\ㄴㅎ", "ㄴ"], ["\ㄴㅇ", "\ㄴㅎ", "ㄴ"], 1., "vowel"),
    TypoDefinition(["\ㄵㅇ", "\ㄴㅈ"], ["\ㄵㅇ", "\ㄴㅈ"], 1., "vowel"),
    TypoDefinition(["\ㄶㅇ", "ㄴ"], ["\ㄶㅇ", "ㄴ"], 1., "vowel"),
    TypoDefinition(["\ㄷㅇ", "ㄷ"], ["\ㄷㅇ", "ㄷ"], 1., "vowel"),
    TypoDefinition(["\ㄹㅇ", "\ㄹㅎ", "ㄹ"], ["\ㄹㅇ", "\ㄹㅎ", "ㄹ"], 1., "vowel"),
    TypoDefinition(["\ㄺㅇ", "\ㄹㄱ"], ["\ㄺㅇ", "\ㄹㄱ"], 1., "vowel"),
    TypoDefinition(["\ㄺㅎ", "\ㄹㅋ"], ["\ㄺㅎ", "\ㄹㅋ"], 1., "vowel"),
    TypoDefinition(["\ㅁㅇ", "ㅁ"], ["\ㅁㅇ", "ㅁ"], 1., "vowel"),
    TypoDefinition(["\ㅂㅇ", "ㅂ"], ["\ㅂㅇ", "ㅂ"], 1., "vowel"),
    TypoDefinition(["\ㅅㅇ", "ㅅ"], ["\ㅅㅇ", "ㅅ"], 1., "vowel"),
    TypoDefinition(["\ㅆㅇ", "\ㅅㅅ", "ㅆ"], ["\ㅆㅇ", "\ㅅㅅ", "ㅆ"], 1., "vowel"),
    TypoDefinition(["\ㅈㅇ", "ㅈ"], ["\ㅈㅇ", "ㅈ"], 1., "vowel"),
    TypoDefinition(["\ㅊㅇ", "\ㅊㅎ", "\ㅈㅎ", "ㅊ"], ["\ㅊㅇ", "\ㅊㅎ", "\ㅈㅎ", "ㅊ"], 1., "vowel"),
    TypoDefinition(["\ㅋㅇ", "\ㅋㅎ", "\ㄱㅎ", "ㅋ"], ["\ㅋㅇ", "\ㅋㅎ", "\ㄱㅎ", "ㅋ"], 1., "vowel"),
    TypoDefinition(["\ㅌㅇ", "\ㅌㅎ", "\ㄷㅎ", "ㅌ"], ["\ㅌㅇ", "\ㅌㅎ", "\ㄷㅎ", "ㅌ"], 1., "vowel"),
    TypoDefinition(["\ㅍㅇ", "\ㅍㅎ", "\ㅂㅎ", "ㅍ"], ["\ㅍㅇ", "\ㅍㅎ", "\ㅂㅎ", "ㅍ"], 1., "vowel"),

    TypoDefinition(["은", "는"], ["은", "는"], 2.),
    TypoDefinition(["을", "를"], ["을", "를"], 2.),

    TypoDefinition(["ㅣ워", "ㅣ어", "ㅕ"], ["ㅣ워", "ㅣ어", "ㅕ"], 1.5),
    #TypoDefinition(["ㅡ아", "ㅏ"], ["ㅡ아", "ㅏ"], 1.5),
    #TypoDefinition(["ㅡ어", "ㅓ"], ["ㅡ어", "ㅓ"], 1.5),
    #TypoDefinition(["ㅡ오", "ㅗ"], ["ㅡ오", "ㅗ"], 1.5),
    #TypoDefinition(["ㅡ우", "ㅜ"], ["ㅡ우", "ㅜ"], 1.5),
])
'''
내장된 기본 오타 정보입니다.
'''

Sub-modules

kiwipiepy.const

const 모듈은 kiwipiepy에서 사용되는 주요 상수값들을 모아놓은 모듈입니다.

kiwipiepy.utils

utils 모듈은 kiwipiepy를 사용하는 데에 있어서 다양한 편의 기능을 제공하기 위한 유틸리티성 클래스 및 함수를 제공합니다. 현재는 Stopwords 클래스만 포함되어 있으며, 이 클래스는 불용어를 관리하고 Kiwi의 형태소 분석 결과 중 불용어를 쉽게 …

Global variables

var basic_typos

내장된 기본 오타 정보입니다.

Classes

class Kiwi (num_workers: Optional[int] = None, model_path: Optional[str] = None, options: Optional[int] = None, integrate_allomorph: Optional[bool] = None, load_default_dict: Optional[bool] = None, load_typo_dict: Optional[bool] = None, model_type: Optional[str] = 'knlm', typos: Union[str, TypoTransformer, None] = None, typo_cost_threshold: Optional[float] = 2.5)

Kiwi 클래스는 실제 형태소 분석을 수행하는 kiwipiepy 모듈의 핵심 클래스입니다.

Parameters

num_workers : int
내부적으로 멀티스레딩에 사용할 스레드 개수. 0으로 설정시 시스템 내 가용한 모든 코어 개수만큼 스레드가 생성됩니다. 멀티스레딩은 extract 계열 함수에서 단어 후보를 탐색할 때와 perform, analyze 함수에서만 사용됩니다.
model_path : str
읽어들일 모델 파일의 경로. 모델 파일의 위치를 옮긴 경우 이 값을 지정해주어야 합니다.
options : int
Kiwi 생성시의 옵션을 설정합니다. 옵션에 대해서는 Option을 확인하십시오.

Deprecated since version: 0.10.0

차기 버전에서 제거될 예정입니다. options 대신 integrate_allormophload_default_dict를 사용해주세요.
integrate_allormoph : bool
True일 경우 음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다. 기본값은 True입니다.
load_default_dict : bool
True일 경우 인스턴스 생성시 자동으로 기본 사전을 불러옵니다. 기본 사전은 위키백과와 나무위키에서 추출된 고유 명사 표제어들로 구성되어 있습니다. 기본값은 True입니다.
load_typo_dict : bool

Added in version: 0.14.0

True일 경우 인스턴스 생성시 자동으로 내장 오타 사전을 불러옵니다. 오타 사전은 자주 틀리는 오타 일부와 인터넷에서 자주 쓰이는 변형된 종결 어미로 구성되어 있습니다. 기본값은 True입니다.

model_type : str

Added in version: 0.13.0

형태소 분석에 사용할 언어 모델을 지정합니다. 'knlm', 'sbg' 중 하나를 선택할 수 있습니다. 기본값은 'knlm'입니다. 각 모델에 대한 자세한 설명은 여기를 참조하세요.

typos : Union[str, TypoTransformer]

Added in version: 0.13.0

교정에 사용할 오타 정보입니다. 기본값은 None으로 이 경우 오타 교정을 사용하지 않습니다. 'basic'으로 입력시 내장된 기본 오타 정보를 이용합니다. 이에 대한 자세한 내용은 TypoTransformer여기를 참조하세요.

typo_cost_threshold : float

Added in version: 0.13.0

오타 교정시 고려할 최대 오타 비용입니다. 이 비용을 넘어서는 오타에 대해서는 탐색하지 않습니다. 기본값은 2.5입니다.

Ancestors

  • kiwipiepy._Kiwi

Instance variables

var cutoff_threshold

Added in version: 0.10.0

Beam 탐색 시 미리 제거할 후보의 점수 차를 설정합니다. 이 값이 클 수록 더 많은 후보를 탐색하게 되므로 분석 속도가 느려지지만 정확도가 올라갑니다. 반대로 이 값을 낮추면 더 적은 후보를 탐색하여 속도가 빨라지지만 정확도는 낮아집니다. 초기값은 5입니다.

Expand source code
    @property
    def cutoff_threshold(self):
        '''.. versionadded:: 0.10.0

Beam 탐색 시 미리 제거할 후보의 점수 차를 설정합니다. 이 값이 클 수록 더 많은 후보를 탐색하게 되므로 분석 속도가 느려지지만 정확도가 올라갑니다.
반대로 이 값을 낮추면 더 적은 후보를 탐색하여 속도가 빨라지지만 정확도는 낮아집니다. 초기값은 5입니다.
        '''

        return self._ns_cutoff_threshold
var integrate_allomorph

Added in version: 0.10.0

True일 경우 음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다.

Expand source code
    @property
    def integrate_allomorph(self):
        '''.. versionadded:: 0.10.0

True일 경우 음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다.
        '''

        return self._ns_integrate_allomorph
var max_unk_form_size

Added in version: 0.11.1

분석 과정에서 허용할 미등재 형태의 최대 길이입니다. 기본값은 6입니다.

Expand source code
    @property
    def max_unk_form_size(self):
        '''.. versionadded:: 0.11.1

분석 과정에서 허용할 미등재 형태의 최대 길이입니다. 기본값은 6입니다.
        '''

        return self._ns_max_unk_form_size
var model_type

Added in version: 0.13.0

형태소 분석에 사용 중인 언어 모델의 종류 (읽기 전용)

Expand source code
    @property
    def model_type(self):
        '''.. versionadded:: 0.13.0

형태소 분석에 사용 중인 언어 모델의 종류 (읽기 전용)
        '''
        return self._ns_model_type
var num_workers

Added in version: 0.10.0

병렬처리시 사용할 스레드의 개수입니다. (읽기 전용)

Expand source code
    @property
    def num_workers(self):
        '''.. versionadded:: 0.10.0

병렬처리시 사용할 스레드의 개수입니다. (읽기 전용)
        '''
        
        return self._num_workers
var space_penalty

Added in version: 0.11.1

형태소 중간에 삽입된 공백 문자가 있을 경우 언어모델 점수에 추가하는 페널티 점수입니다. 기본값은 7.0입니다.

Expand source code
    @property
    def space_penalty(self):
        '''.. versionadded:: 0.11.1

형태소 중간에 삽입된 공백 문자가 있을 경우 언어모델 점수에 추가하는 페널티 점수입니다. 기본값은 7.0입니다.
        '''

        return self._ns_space_penalty
var space_tolerance

Added in version: 0.11.1

형태소 중간에 삽입된 공백문자를 몇 개까지 허용할지 설정합니다. 기본값은 0이며, 이 경우 형태소 중간에 공백문자가 삽입되는 걸 허용하지 않습니다.

Kiwi.space() 메소드 참고.

Expand source code
    @property
    def space_tolerance(self):
        '''.. versionadded:: 0.11.1

형태소 중간에 삽입된 공백문자를 몇 개까지 허용할지 설정합니다. 기본값은 0이며, 이 경우 형태소 중간에 공백문자가 삽입되는 걸 허용하지 않습니다.

`Kiwi.space` 메소드 참고.
        '''

        return self._ns_space_tolerance
var typo_cost_weight

Added in version: 0.13.0

오타 교정 시에 사용할 교정 가중치. 이 값이 클수록 교정을 보수적으로 수행합니다. 기본값은 6입니다.

Expand source code
    @property
    def typo_cost_weight(self):
        '''.. versionadded:: 0.13.0

오타 교정 시에 사용할 교정 가중치. 이 값이 클수록 교정을 보수적으로 수행합니다. 기본값은 6입니다.
        '''

        return self._ns_typo_cost_weight
var version

Kiwi의 버전을 반환합니다.

Deprecated since version: 0.10.0

차기 버전에서 제거될 예정입니다. 대신 kiwipiepy.__version__을 사용하십시오.

Expand source code
    @property
    def version(self):
        '''Kiwi의 버전을 반환합니다. 
.. deprecated:: 0.10.0
    차기 버전에서 제거될 예정입니다. 대신 `kiwipiepy.__version__`을 사용하십시오.
        '''

        return __version__

Methods

def add_pre_analyzed_word(self, form: str, analyzed: Iterable[Tuple[str, str]], score: Optional[float] = 0.0) ‑> bool

Added in version: 0.11.0

현재 모델에 기분석 형태소열을 추가합니다.

Parameters

form : str
추가할 형태
analyzed : Iterable[Tuple[str, str]]
form의 형태소 분석 결과. 이 값은 (형태, 품사) 모양의 tuple, 혹은 (형태, 품사, 시작지점, 끝지점) 모양의 tuple로 구성된 Iterable이어야합니다. 이 값으로 지정되는 형태소는 현재 사전 내에 반드시 존재해야 하며, 그렇지 않으면 ValueError 예외를 발생시킵니다.
score : float
추가할 형태소열의 가중치 점수. 해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.

Returns

inserted : bool
기분석 형태소열이 정상적으로 삽입된 경우 True, 이미 동일한 대상이 존재하여 삽입되지 않은 경우 False를 반환합니다.

Notes

이 메소드는 불규칙적인 분석 결과를 분석기에 추가하는 데에 용이합니다. 예를 들어 사귀다 동사의 과거형은 사귀었다가 맞지만, 흔히 사겼다로 잘못 쓰이기도 합니다. 사겼다사귀/VV + 었/EP + 다/EF로 바르게 분석되도록 하는데에 이 메소드를 사용할 수 있습니다.

kiwi.add_pre_analyzed_word('사겼다', ['사귀/VV', '었/EP', '다/EF'], -3)
kiwi.add_pre_analyzed_word('사겼다', [('사귀', 'VV', 0, 2), ('었', 'EP', 1, 2), ('다', 'EF', 2, 3)], -3)

후자의 경우 분석 결과의 각 형태소가 원본 문자열에서 차지하는 위치를 정확하게 지정해줌으로써, Kiwi 분석 결과에서 해당 형태소의 분석 결과가 정확하게 나오도록 합니다.

Expand source code
    def add_pre_analyzed_word(self,
        form:str,
        analyzed:Iterable[Tuple[str, str]],
        score:Optional[float] = 0.,
    ) -> bool:
        '''.. versionadded:: 0.11.0

현재 모델에 기분석 형태소열을 추가합니다.

Parameters
----------
form: str
    추가할 형태
analyzed: Iterable[Tuple[str, str]]
    `form`의 형태소 분석 결과.
    이 값은 (형태, 품사) 모양의 tuple, 혹은 (형태, 품사, 시작지점, 끝지점) 모양의 tuple로 구성된 Iterable이어야합니다.
    이 값으로 지정되는 형태소는 현재 사전 내에 반드시 존재해야 하며, 그렇지 않으면 `ValueError` 예외를 발생시킵니다.
score: float
    추가할 형태소열의 가중치 점수. 
    해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.

Returns
-------
inserted: bool
    기분석 형태소열이 정상적으로 삽입된 경우 True, 이미 동일한 대상이 존재하여 삽입되지 않은 경우 False를 반환합니다.

Notes
-----
이 메소드는 불규칙적인 분석 결과를 분석기에 추가하는 데에 용이합니다. 
예를 들어 `사귀다` 동사의 과거형은 `사귀었다`가 맞지만, 흔히 `사겼다`로 잘못 쓰이기도 합니다.
`사겼다`가 `사귀/VV + 었/EP + 다/EF`로 바르게 분석되도록 하는데에 이 메소드를 사용할 수 있습니다.
```python
kiwi.add_pre_analyzed_word('사겼다', ['사귀/VV', '었/EP', '다/EF'], -3)
kiwi.add_pre_analyzed_word('사겼다', [('사귀', 'VV', 0, 2), ('었', 'EP', 1, 2), ('다', 'EF', 2, 3)], -3)
```

후자의 경우 분석 결과의 각 형태소가 원본 문자열에서 차지하는 위치를 정확하게 지정해줌으로써, 
Kiwi 분석 결과에서 해당 형태소의 분석 결과가 정확하게 나오도록 합니다.
        '''
        return super().add_pre_analyzed_word(form, analyzed, score)
def add_re_rule(self, tag: str, pattern: Union[str, ForwardRef('re.Pattern')], repl: Union[str, Callable], score: Optional[float] = 0.0) ‑> List[str]

Added in version: 0.11.0

Kiwi.add_rule()과 동일한 역할을 수행하되, 변형 규칙에 정규표현식을 사용합니다.

Parameters

tag : str
추가할 형태소들의 품사
pattern : Union[str, re.Pattern]
변형시킬 형태소의 규칙. 이 값은 re.compile로 컴파일가능한 정규표현식이어야 합니다.
repl : Union[str, Callable]
pattern에 의해 발견된 패턴은 이 값으로 교체됩니다. re.sub 함수의 repl 인자와 동일합니다.
score : float
추가할 변형된 형태소의 가중치 점수. 해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.

Returns

inserted_forms : List[str]
규칙에 의해 새로 생성된 형태소의 list를 반환합니다.

Notes

이 메소드는 규칙에 의해 변형되는 이형태들을 일괄적으로 추가할 때 굉장히 용이합니다. 예를 들어 -요-염으로 교체된 종결어미들(먹어염, 뛰었구염, 배불러염 등)을 일괄 등록하기 위해서는 다음을 수행하면 됩니다.

kiwi.add_re_rule('EF', r'요$', r'염', -3.0)

이런 이형태들을 대량으로 등록할 경우 이형태가 원본 형태보다 분석결과에서 높은 우선권을 가지지 않도록 score를 -3 이하의 값으로 설정하는걸 권장합니다.

Expand source code
    def add_re_rule(self,
        tag:str,
        pattern:Union[str, 're.Pattern'],
        repl:Union[str, Callable],
        score:Optional[float] = 0.,
    ) -> List[str]:
        '''.. versionadded:: 0.11.0

`kiwipiepy.Kiwi.add_rule`과 동일한 역할을 수행하되, 변형 규칙에 정규표현식을 사용합니다.

Parameters
----------
tag: str
    추가할 형태소들의 품사
pattern: Union[str, re.Pattern]
    변형시킬 형태소의 규칙. 이 값은 `re.compile`로 컴파일가능한 정규표현식이어야 합니다.
repl: Union[str, Callable]
    `pattern`에 의해 발견된 패턴은 이 값으로 교체됩니다. `re.sub` 함수의 `repl` 인자와 동일합니다.
score: float
    추가할 변형된 형태소의 가중치 점수. 
    해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.

Returns
-------
inserted_forms: List[str]
    규칙에 의해 새로 생성된 형태소의 `list`를 반환합니다.

Notes
-----
이 메소드는 규칙에 의해 변형되는 이형태들을 일괄적으로 추가할 때 굉장히 용이합니다.
예를 들어 `-요`가 `-염`으로 교체된 종결어미들(`먹어염`, `뛰었구염`, `배불러염` 등)을 일괄 등록하기 위해서는
다음을 수행하면 됩니다.

```python
kiwi.add_re_rule('EF', r'요$', r'염', -3.0)
```

이런 이형태들을 대량으로 등록할 경우 이형태가 원본 형태보다 분석결과에서 높은 우선권을 가지지 않도록
score를 `-3` 이하의 값으로 설정하는걸 권장합니다.
        '''
        if isinstance(pattern, str):
            pattern = re.compile(pattern)
        return super().add_rule(tag, lambda x:pattern.sub(repl, x), score)
def add_rule(self, tag: str, replacer: Callable[[str], str], score: Optional[float] = 0.0) ‑> List[str]

Added in version: 0.11.0

규칙에 의해 변형된 형태소를 일괄적으로 추가합니다.

Parameters

tag : str
추가할 형태소들의 품사
replacer : Callable[[str], str]
형태소를 변형시킬 규칙. 이 값은 호출가능한 Callable 형태로 제공되어야 하며, 원본 형태소 str를 입력으로 받아 변형된 형태소의 str을 반환해야합니다. 만약 입력과 동일한 값을 반환하면 해당 변형 결과는 무시됩니다.
score : float
추가할 변형된 형태소의 가중치 점수. 해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.

Returns

inserted_forms : List[str]
규칙에 의해 새로 생성된 형태소의 list를 반환합니다.
Expand source code
    def add_rule(self,
        tag:str,
        replacer:Callable[[str], str],
        score:Optional[float] = 0.,
    ) -> List[str]:
        '''.. versionadded:: 0.11.0

규칙에 의해 변형된 형태소를 일괄적으로 추가합니다.

Parameters
----------
tag: str
    추가할 형태소들의 품사
replacer: Callable[[str], str]
    형태소를 변형시킬 규칙. 
    이 값은 호출가능한 Callable 형태로 제공되어야 하며, 원본 형태소 str를 입력으로 받아 변형된 형태소의 str을 반환해야합니다.
    만약 입력과 동일한 값을 반환하면 해당 변형 결과는 무시됩니다.
score: float
    추가할 변형된 형태소의 가중치 점수. 
    해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.

Returns
-------
inserted_forms: List[str]
    규칙에 의해 새로 생성된 형태소의 `list`를 반환합니다.
        '''
        return super().add_rule(tag, replacer, score)
def add_user_word(self, word: str, tag: Optional[str] = 'NNP', score: Optional[float] = 0.0, orig_word: Optional[str] = None) ‑> bool

현재 모델에 사용자 정의 형태소를 추가합니다.

Parameters

word : str
추가할 형태소
tag : str
추가할 형태소의 품사 태그
score : float
추가할 형태소의 가중치 점수. 해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.
orig_word : str

Added in version: 0.11.0

추가할 형태소의 원본 형태소. 추가할 형태소가 특정 형태소의 변이형인 경우 이 인자로 원본 형태소를 넘겨줄 수 있습니다. 없는 경우 생략할 수 있습니다. orig_word가 주어진 경우 현재 사전 내에 orig_word/tag 조합의 형태소가 반드시 존재해야 하며, 그렇지 않으면 ValueError 예외를 발생시킵니다.

Returns

inserted : bool
사용자 정의 형태소가 정상적으로 삽입된 경우 True, 이미 동일한 형태소가 존재하여 삽입되지 않은 경우 False를 반환합니다.
Expand source code
    def add_user_word(self,
        word:str,
        tag:Optional[str] = 'NNP',
        score:Optional[float] = 0.,
        orig_word:Optional[str] = None,
    ) -> bool:
        '''현재 모델에 사용자 정의 형태소를 추가합니다.

Parameters
----------
word: str
    추가할 형태소
tag: str
    추가할 형태소의 품사 태그
score: float
    추가할 형태소의 가중치 점수. 
    해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.
orig_word : str
    .. versionadded:: 0.11.0

    추가할 형태소의 원본 형태소.
    추가할 형태소가 특정 형태소의 변이형인 경우 이 인자로 원본 형태소를 넘겨줄 수 있습니다. 없는 경우 생략할 수 있습니다.
    `orig_word`가 주어진 경우 현재 사전 내에 `orig_word`/`tag` 조합의 형태소가 반드시 존재해야 하며, 그렇지 않으면 `ValueError` 예외를 발생시킵니다.

Returns
-------
inserted: bool
    사용자 정의 형태소가 정상적으로 삽입된 경우 True, 이미 동일한 형태소가 존재하여 삽입되지 않은 경우 False를 반환합니다.
        '''
        if re.search(r'\s', word): raise ValueError("Whitespace characters are not allowed at `word`")
        return super().add_user_word(word, tag, score, orig_word)
def analyze(self, text: Union[str, Iterable[str]], top_n: Optional[int] = 1, match_options: Optional[int] = Match.ALL, normalize_coda: Optional[bool] = False)

형태소 분석을 실시합니다.

Changed in version: 0.10.0

이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 여기를 확인해주세요.

Parameters

text : Union[str, Iterable[str]]
분석할 문자열입니다. 이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며 str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
top_n : int
분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options : Match

Added in version: 0.8.0

추출한 특수 문자열 패턴을 지정합니다. Match의 조합으로 설정할 수 있습니다.

normalize_coda : bool

Added in version: 0.10.2

True인 경우 '먹었엌ㅋㅋ'처럼 받침이 덧붙어서 분석에 실패하는 경우, 받침을 분리하여 정규화합니다.

Returns

result : List[Tuple[List[Token], float]]
text를 str으로 준 경우. 분석 결과는 최대 top_n개 길이의 리스트로 반환됩니다. 리스트의 각 항목은 (분석 결과, 분석 점수)로 구성된 튜플입니다. 분석 결과Token의 리스트로 구성됩니다.
results : Iterable[List[Tuple[List[Token], float]]]
text를 Iterable[str]으로 준 경우. 반환값은 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes

textIterable로 준 경우 멀티스레딩으로 처리됩니다. 이 때 사용되는 스레드의 개수는 처음에 Kiwi를 생성할 때 num_workers로 준 값입니다.

kiwi.analyze('형태소 분석 결과입니다')
# 반환 값은 다음과 같이 `(형태소 분석 결과, 분석 점수)`의 형태입니다.
(
    [Token(form='형태소', tag='NNG', start=0, len=3), 
    Token(form='분석', tag='NNG', start=4, len=2), 
    Token(form='결과', tag='NNG', start=7, len=2), 
    Token(form='이', tag='VCP', start=9, len=1), 
    Token(form='ᆸ니다', tag='EF', start=10, len=2)
    ],
    -34.3332
)

# 4개의 스레드에서 동시에 처리합니다.
kiwi = Kiwi(num_workers=4)
with open('result.txt', 'w', encoding='utf-8') as output:
    for res in kiwi.analyze(open('test.txt', encoding='utf-8')):
        print(' '.join(map(lambda x:x[0]+'/'+x[1], res[0][0])), file=output)
Expand source code
    def analyze(self,
        text:Union[str, Iterable[str]],
        top_n:Optional[int] = 1,
        match_options:Optional[int] = Match.ALL,
        normalize_coda:Optional[bool] = False
    ):
        '''형태소 분석을 실시합니다.

.. versionchanged:: 0.10.0
    이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 <a href="#0100">여기</a>를 확인해주세요.

Parameters
----------
text: Union[str, Iterable[str]]
    분석할 문자열입니다. 
    이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며
    str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
top_n: int
    분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options: kiwipiepy.const.Match
    
    .. versionadded:: 0.8.0
    
    추출한 특수 문자열 패턴을 지정합니다. `kiwipiepy.const.Match`의 조합으로 설정할 수 있습니다.
normalize_coda: bool

    .. versionadded:: 0.10.2

    True인 경우 '먹었엌ㅋㅋ'처럼 받침이 덧붙어서 분석에 실패하는 경우, 받침을 분리하여 정규화합니다.

Returns
-------
result: List[Tuple[List[kiwipiepy.Token], float]]
    text를 str으로 준 경우.
    분석 결과는 최대 `top_n`개 길이의 리스트로 반환됩니다. 리스트의 각 항목은 `(분석 결과, 분석 점수)`로 구성된 튜플입니다. 
    `분석 결과`는 `kiwipiepy.Token`의 리스트로 구성됩니다.

results: Iterable[List[Tuple[List[kiwipiepy.Token], float]]]
    text를 Iterable[str]으로 준 경우.
    반환값은 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes
-----
`text`를 `Iterable`로 준 경우 멀티스레딩으로 처리됩니다. 
이 때 사용되는 스레드의 개수는 처음에 `Kiwi`를 생성할 때 `num_workers`로 준 값입니다.

```python
kiwi.analyze('형태소 분석 결과입니다')
# 반환 값은 다음과 같이 `(형태소 분석 결과, 분석 점수)`의 형태입니다.
(
    [Token(form='형태소', tag='NNG', start=0, len=3), 
    Token(form='분석', tag='NNG', start=4, len=2), 
    Token(form='결과', tag='NNG', start=7, len=2), 
    Token(form='이', tag='VCP', start=9, len=1), 
    Token(form='ᆸ니다', tag='EF', start=10, len=2)
    ],
    -34.3332
)

# 4개의 스레드에서 동시에 처리합니다.
kiwi = Kiwi(num_workers=4)
with open('result.txt', 'w', encoding='utf-8') as output:
    for res in kiwi.analyze(open('test.txt', encoding='utf-8')):
        print(' '.join(map(lambda x:x[0]+'/'+x[1], res[0][0])), file=output)
```
        '''
        if normalize_coda:
            match_options |= Match.NORMALIZING_CODA
        return super().analyze(text, top_n, match_options)
def extract_add_words(self, texts, min_cnt: Optional[int] = 10, max_word_len: Optional[int] = 10, min_score: Optional[float] = 0.25, pos_score: Optional[float] = -3.0, lm_filter: Optional[bool] = True)

말뭉치로부터 새로운 단어를 추출하고 새로운 명사에 적합한 결과들만 추려냅니다. 그리고 그 결과를 현재 모델에 자동으로 추가합니다.

Changed in version: 0.10.0

이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 여기를 확인해주세요.

Parameters

texts : Iterable[str]
분석할 문자열의 리스트, 혹은 Iterable입니다.
min_cnt : int
추출할 단어의 최소 출현 빈도입니다. 이 빈도보다 적게 등장한 문자열은 단어 후보에서 제외됩니다.
max_word_len : int
추출할 단어 후보의 최대 길이입니다. 이 길이보다 긴 단어 후보는 탐색되지 않습니다.
min_score : float
단어 후보의 최소 점수입니다. 이 점수보다 낮은 단어 후보는 고려되지 않습니다. 이 값을 낮출수록 단어가 아닌 형태가 추출될 가능성이 높아지고, 반대로 이 값을 높일 수록 추출되는 단어의 개수가 줄어들므로 적절한 수치로 설정할 필요가 있습니다.
pos_score : float
단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.
lm_filter : bool

Added in version: 0.10.0

True일 경우 품사 점수 및 언어 모델을 이용한 필터링을 수행합니다.

Returns

result : List[Tuple[str, float, int, float]]
추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
Expand source code
    def extract_add_words(self,
        texts,
        min_cnt:Optional[int] = 10,
        max_word_len:Optional[int] = 10,
        min_score:Optional[float] = 0.25,
        pos_score:Optional[float] = -3.,
        lm_filter:Optional[bool] = True,
    ):
        '''말뭉치로부터 새로운 단어를 추출하고 새로운 명사에 적합한 결과들만 추려냅니다. 그리고 그 결과를 현재 모델에 자동으로 추가합니다.

.. versionchanged:: 0.10.0
    이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 <a href="#0100">여기</a>를 확인해주세요.

Parameters
----------
texts: Iterable[str]
    분석할 문자열의 리스트, 혹은 Iterable입니다.
min_cnt: int
    추출할 단어의 최소 출현 빈도입니다. 이 빈도보다 적게 등장한 문자열은 단어 후보에서 제외됩니다.
max_word_len: int
    추출할 단어 후보의 최대 길이입니다. 이 길이보다 긴 단어 후보는 탐색되지 않습니다.
min_score: float
    단어 후보의 최소 점수입니다. 이 점수보다 낮은 단어 후보는 고려되지 않습니다.
    이 값을 낮출수록 단어가 아닌 형태가 추출될 가능성이 높아지고, 반대로 이 값을 높일 수록 추출되는 단어의 개수가 줄어들므로 적절한 수치로 설정할 필요가 있습니다.
pos_score: float
    단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.
lm_filter: bool
    ..versionadded:: 0.10.0

    True일 경우 품사 점수 및 언어 모델을 이용한 필터링을 수행합니다.

Returns
-------
result: List[Tuple[str, float, int, float]]
    추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
        '''

        return super().extract_add_words(
            texts,
            min_cnt,
            max_word_len,
            min_score,
            pos_score,
            lm_filter,
        )
def extract_filter_words(self, *args, **kwargs)

Deprecated since version: 0.10.0

이 메소드의 기능은 Kiwi.extract_words()로 통합되었습니다. 현재 이 메소드를 호출하는 것은 Kiwi.extract_words()를 호출하는 것과 동일하게 처리됩니다.

Expand source code
def extract_filter_words(self, *args, **kwargs):
    '''.. deprecated:: 0.10.0
이 메소드의 기능은 `kiwipiepy.Kiwi.extract_words`로 통합되었습니다. 
현재 이 메소드를 호출하는 것은 `kiwipiepy.Kiwi.extract_words`를 호출하는 것과 동일하게 처리됩니다.
    '''

    warnings.warn(
        "`extract_filter_words` has same effect to `extract_words` and will be removed in future version.",
        DeprecationWarning
    )
    return self.extract_words(*args, **kwargs)
def extract_words(self, texts, min_cnt: Optional[int] = 10, max_word_len: Optional[int] = 10, min_score: Optional[float] = 0.25, pos_score: Optional[float] = -3.0, lm_filter: Optional[bool] = True)

말뭉치로부터 새로운 단어를 추출합니다. 이 기능은 https://github.com/lovit/soynlp 의 Word Extraction 기법을 바탕으로 하되, 문자열 기반의 확률 모델을 추가하여 명사일 것으로 예측되는 단어만 추출합니다.

Changed in version: 0.10.0

이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 여기를 확인해주세요.

Parameters

texts : Iterable[str]
분석할 문자열의 리스트, 혹은 Iterable입니다.
min_cnt : int
추출할 단어의 최소 출현 빈도입니다. 이 빈도보다 적게 등장한 문자열은 단어 후보에서 제외됩니다.
max_word_len : int
추출할 단어 후보의 최대 길이입니다. 이 길이보다 긴 단어 후보는 탐색되지 않습니다.
min_score : float
단어 후보의 최소 점수입니다. 이 점수보다 낮은 단어 후보는 고려되지 않습니다. 이 값을 낮출수록 단어가 아닌 형태가 추출될 가능성이 높아지고, 반대로 이 값을 높일 수록 추출되는 단어의 개수가 줄어들므로 적절한 수치로 설정할 필요가 있습니다.
pos_score : float

Added in version: 0.10.0

단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.

lm_filter : bool

Added in version: 0.10.0

True일 경우 품사 점수 및 언어 모델을 이용한 필터링을 수행합니다.

Returns

result : List[Tuple[str, float, int, float]]
추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
Expand source code
    def extract_words(self,
        texts,
        min_cnt:Optional[int] = 10,
        max_word_len:Optional[int] = 10,
        min_score:Optional[float] = 0.25,
        pos_score:Optional[float] = -3.,
        lm_filter:Optional[bool] = True,
    ):
        '''말뭉치로부터 새로운 단어를 추출합니다. 
이 기능은 https://github.com/lovit/soynlp 의 Word Extraction 기법을 바탕으로 하되, 
문자열 기반의 확률 모델을 추가하여 명사일 것으로 예측되는 단어만 추출합니다.

.. versionchanged:: 0.10.0
    이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 <a href="#0100">여기</a>를 확인해주세요.

Parameters
----------
texts: Iterable[str]
    분석할 문자열의 리스트, 혹은 Iterable입니다.
min_cnt: int
    추출할 단어의 최소 출현 빈도입니다. 이 빈도보다 적게 등장한 문자열은 단어 후보에서 제외됩니다.
max_word_len: int
    추출할 단어 후보의 최대 길이입니다. 이 길이보다 긴 단어 후보는 탐색되지 않습니다.
min_score: float
    단어 후보의 최소 점수입니다. 이 점수보다 낮은 단어 후보는 고려되지 않습니다.
    이 값을 낮출수록 단어가 아닌 형태가 추출될 가능성이 높아지고, 반대로 이 값을 높일 수록 추출되는 단어의 개수가 줄어들므로 적절한 수치로 설정할 필요가 있습니다.
pos_score: float
    ..versionadded:: 0.10.0

    단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.

lm_filter: bool
    ..versionadded:: 0.10.0
    
    True일 경우 품사 점수 및 언어 모델을 이용한 필터링을 수행합니다.
Returns
-------
result: List[Tuple[str, float, int, float]]
    추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
        '''

        return super().extract_words(
            texts,
            min_cnt,
            max_word_len,
            min_score,
            pos_score,
            lm_filter,
        )
def get_option(self, option: int)

현재 모델의 설정값을 가져옵니다.

Deprecated since version: 0.10.0

차기 버전에서 제거될 예정입니다. 이 메소드 대신 Kiwi.integrate_allomorph값을 직접 읽으십시오.

Parameters

option : Option
검사할 옵션의 열거값. 현재는 Option.INTEGRATE_ALLOMORPH만 지원합니다.

Returns

value : int
해당 옵션이 설정되어 있는 경우 1, 아닌 경우 0을 반환합니다.
Expand source code
    def get_option(self,
        option:int,
    ):
        '''현재 모델의 설정값을 가져옵니다.

.. deprecated:: 0.10.0
    차기 버전에서 제거될 예정입니다. 
    이 메소드 대신 `Kiwi.integrate_allomorph`값을 직접 읽으십시오.

Parameters
----------
option: kiwipiepy.const.Option
    검사할 옵션의 열거값. 현재는 `kiwipiepy.const.Option.INTEGRATE_ALLOMORPH`만 지원합니다.

Returns
-------
value: int
    해당 옵션이 설정되어 있는 경우 1, 아닌 경우 0을 반환합니다.
        '''

        warnings.warn(
            "`get_option()` will be removed in future version.",
            DeprecationWarning
        )
        if option != Option.INTEGRATE_ALLOMORPH: raise ValueError("Wrong `option` value: {}".format(option))
        return int(self._integrate_allomorph)
def glue(self, text_chunks: Iterable[str], return_space_insertions: Optional[bool] = False) ‑> Union[str, Tuple[str, List[bool]]]

Added in version: 0.11.1

여러 텍스트 조각을 하나로 합치되, 문맥을 고려해 적절한 공백을 사이에 삽입합니다.

Parameters

text_chunks : Iterable[str]
합칠 텍스트 조각들의 목록입니다.
return_space_insertions : bool
True인 경우, 각 조각별 공백 삽입 유무를 List[bool]로 반환합니다. 기본값은 False입니다.

Returns

result : str
입력 텍스트 조각의 결합결과를 반환합니다.
space_insertions : Iterable[str]
이 값은 return_space_insertions=True인 경우에만 반환됩니다. 공백 삽입 유무를 알려줍니다.

Notes

이 메소드의 공백 자동 삽입 기능은 형태소 분석에 기반합니다.

>> kiwi.glue([
    "그러나  알고보니 그 봉",
    "지 안에 있던 것은 바로",
    "레몬이었던 것이다."])
"그러나  알고보니 그 봉지 안에 있던 것은 바로 레몬이었던 것이다."

>> kiwi.glue([
    "그러나  알고보니 그 봉",
    "지 안에 있던 것은 바로",
    "레몬이었던 것이다."], return_space_insertions=True)
("그러나  알고보니 그 봉지 안에 있던 것은 바로 레몬이었던 것이다.", [False, True])
Expand source code
    def glue(self,
        text_chunks:Iterable[str],
        return_space_insertions:Optional[bool] = False,
    ) -> Union[str, Tuple[str, List[bool]]]:
        '''..versionadded:: 0.11.1

여러 텍스트 조각을 하나로 합치되, 문맥을 고려해 적절한 공백을 사이에 삽입합니다.

Parameters
----------
text_chunks: Iterable[str]
    합칠 텍스트 조각들의 목록입니다.
return_space_insertions: bool
    True인 경우, 각 조각별 공백 삽입 유무를 `List[bool]`로 반환합니다.
    기본값은 False입니다.

Returns
-------
result: str
    입력 텍스트 조각의 결합결과를 반환합니다.

space_insertions: Iterable[str]
    이 값은 `return_space_insertions=True`인 경우에만 반환됩니다.
    공백 삽입 유무를 알려줍니다.

Notes
-----
이 메소드의 공백 자동 삽입 기능은 형태소 분석에 기반합니다. 

```python
>> kiwi.glue([
    "그러나  알고보니 그 봉",
    "지 안에 있던 것은 바로",
    "레몬이었던 것이다."])
"그러나  알고보니 그 봉지 안에 있던 것은 바로 레몬이었던 것이다."

>> kiwi.glue([
    "그러나  알고보니 그 봉",
    "지 안에 있던 것은 바로",
    "레몬이었던 것이다."], return_space_insertions=True)
("그러나  알고보니 그 봉지 안에 있던 것은 바로 레몬이었던 것이다.", [False, True])
```
        '''

        all_chunks = []
        def _zip_consequences(it):
            prev = next(it).strip()
            all_chunks.append(prev)
            for s in it:
                s = s.strip()
                yield prev + ' ' + s
                yield prev + s
                prev = s
                all_chunks.append(prev)
        
        riter = super().analyze(_zip_consequences(iter(text_chunks)), 1, Match.ALL)
        i = 0
        ret = []
        space_insertions = []
        try:
            while 1:
                _, score_with_space = next(riter)[0]
                _, score_without_space = next(riter)[0]
                ret.append(all_chunks[i])
                if score_with_space >= score_without_space or re.search(r'[0-9A-Za-z]$', all_chunks[i]):
                    ret.append(' ')
                    space_insertions.append(True)
                else:
                    space_insertions.append(False)
                i += 1
        except StopIteration:
            ret.append(all_chunks[i])
        
        if return_space_insertions:
            return ''.join(ret), space_insertions
        else:
            return ''.join(ret)
def join(self, morphs: Iterable[Tuple[str, str]], lm_search: Optional[bool] = True) ‑> str

Added in version: 0.12.0

형태소들을 결합하여 문장으로 복원합니다. 조사나 어미는 앞 형태소에 맞춰 적절한 형태로 변경됩니다.

Parameters

morphs : Iterable[Union[Token, Tuple[str, str]]]
결합할 형태소의 목록입니다. 각 형태소는 Kiwi.tokenize()에서 얻어진 Token 타입이거나, (형태, 품사)로 구성된 tuple 타입이어야 합니다.
lm_search : bool
둘 이상의 형태로 복원 가능한 모호한 형태소가 있는 경우, 이 값이 True면 언어 모델 탐색을 통해 최적의 형태소를 선택합니다. False일 경우 탐색을 실시하지 않지만 더 빠른 속도로 복원이 가능합니다.

Returns

result : str
입력 형태소의 결합 결과를 반환합니다.

Notes

Kiwi.join()은 형태소를 결합할 때 Kiwi.space()에서 사용하는 것과 유사한 규칙을 사용하여 공백을 적절히 삽입합니다. 형태소 그 자체에는 공백 관련 정보가 포함되지 않으므로 특정 텍스트를 Kiwi.tokenize()로 분석 후 다시 Kiwi.join()으로 결합하여도 원본 텍스트가 그대로 복원되지는 않습니다.

>> kiwi.join([('덥', 'VA'), ('어', 'EC')])
'더워'
>> tokens = kiwi.tokenize("분석된결과를 다시합칠수있다!")
# 형태소 분석 결과를 복원. 
# 복원 시 공백은 규칙에 의해 삽입되므로 원문 텍스트가 그대로 복원되지는 않음.
>> kiwi.join(tokens)
'분석된 결과를 다시 합칠 수 있다!'
>> tokens[3]
Token(form='결과', tag='NNG', start=4, len=2)
>> tokens[3] = ('내용', 'NNG') # 4번째 형태소를 결과->내용으로 교체
>> kiwi.join(tokens) # 다시 join하면 결과를->내용을 로 교체된 걸 확인 가능
'분석된 내용을 다시 합칠 수 있다!'

# 불규칙 활용여부가 모호한 경우 lm_search=True인 경우 맥락을 고려해 최적의 후보를 선택합니다.
>> kiwi.join([('길', 'NNG'), ('을', 'JKO'), ('묻', 'VV'), ('어요', 'EF')])
'길을 물어요'
>> kiwi.join([('흙', 'NNG'), ('이', 'JKS'), ('묻', 'VV'), ('어요', 'EF')])
'흙이 묻어요'
# lm_search=False이면 탐색을 실시하지 않습니다.
>> kiwi.join([('길', 'NNG'), ('을', 'JKO'), ('묻', 'VV'), ('어요', 'EF')], lm_search=False)
'길을 묻어요'
>> kiwi.join([('흙', 'NNG'), ('이', 'JKS'), ('묻', 'VV'), ('어요', 'EF')], lm_search=False)
'흙이 묻어요'
# 동사/형용사 품사 태그 뒤에 -R(규칙 활용), -I(불규칙 활용)을 덧붙여 활용법을 직접 명시할 수 있습니다.
>> kiwi.join([('묻', 'VV-R'), ('어요', 'EF')])
'묻어요'
>> kiwi.join([('묻', 'VV-I'), ('어요', 'EF')])
'물어요'

# 과거형 선어말어미를 제거하는 예시
>> remove_past = lambda s: kiwi.join(t for t in kiwi.tokenize(s) if t.tagged_form != '었/EP')
>> remove_past('먹었다')
'먹다'
>> remove_past('먼 길을 걸었다')
'먼 길을 걷다'
>> remove_past('전화를 걸었다.')
'전화를 걸다.'
Expand source code
    def join(self, 
        morphs:Iterable[Tuple[str, str]],
        lm_search:Optional[bool] = True
    ) -> str:
        '''..versionadded:: 0.12.0

형태소들을 결합하여 문장으로 복원합니다. 
조사나 어미는 앞 형태소에 맞춰 적절한 형태로 변경됩니다.

Parameters
----------
morphs: Iterable[Union[Token, Tuple[str, str]]]
    결합할 형태소의 목록입니다. 
    각 형태소는 `Kiwi.tokenize`에서 얻어진 `Token` 타입이거나, 
    (형태, 품사)로 구성된 `tuple` 타입이어야 합니다.
lm_search: bool
    둘 이상의 형태로 복원 가능한 모호한 형태소가 있는 경우, 이 값이 True면 언어 모델 탐색을 통해 최적의 형태소를 선택합니다.
    False일 경우 탐색을 실시하지 않지만 더 빠른 속도로 복원이 가능합니다.

Returns
-------
result: str
    입력 형태소의 결합 결과를 반환합니다.

Notes
-----
`Kiwi.join`은 형태소를 결합할 때 `Kiwi.space`에서 사용하는 것과 유사한 규칙을 사용하여 공백을 적절히 삽입합니다.
형태소 그 자체에는 공백 관련 정보가 포함되지 않으므로
특정 텍스트를 `Kiwi.tokenize`로 분석 후 다시 `Kiwi.join`으로 결합하여도 원본 텍스트가 그대로 복원되지는 않습니다.


```python
>> kiwi.join([('덥', 'VA'), ('어', 'EC')])
'더워'
>> tokens = kiwi.tokenize("분석된결과를 다시합칠수있다!")
# 형태소 분석 결과를 복원. 
# 복원 시 공백은 규칙에 의해 삽입되므로 원문 텍스트가 그대로 복원되지는 않음.
>> kiwi.join(tokens)
'분석된 결과를 다시 합칠 수 있다!'
>> tokens[3]
Token(form='결과', tag='NNG', start=4, len=2)
>> tokens[3] = ('내용', 'NNG') # 4번째 형태소를 결과->내용으로 교체
>> kiwi.join(tokens) # 다시 join하면 결과를->내용을 로 교체된 걸 확인 가능
'분석된 내용을 다시 합칠 수 있다!'

# 불규칙 활용여부가 모호한 경우 lm_search=True인 경우 맥락을 고려해 최적의 후보를 선택합니다.
>> kiwi.join([('길', 'NNG'), ('을', 'JKO'), ('묻', 'VV'), ('어요', 'EF')])
'길을 물어요'
>> kiwi.join([('흙', 'NNG'), ('이', 'JKS'), ('묻', 'VV'), ('어요', 'EF')])
'흙이 묻어요'
# lm_search=False이면 탐색을 실시하지 않습니다.
>> kiwi.join([('길', 'NNG'), ('을', 'JKO'), ('묻', 'VV'), ('어요', 'EF')], lm_search=False)
'길을 묻어요'
>> kiwi.join([('흙', 'NNG'), ('이', 'JKS'), ('묻', 'VV'), ('어요', 'EF')], lm_search=False)
'흙이 묻어요'
# 동사/형용사 품사 태그 뒤에 -R(규칙 활용), -I(불규칙 활용)을 덧붙여 활용법을 직접 명시할 수 있습니다.
>> kiwi.join([('묻', 'VV-R'), ('어요', 'EF')])
'묻어요'
>> kiwi.join([('묻', 'VV-I'), ('어요', 'EF')])
'물어요'

# 과거형 선어말어미를 제거하는 예시
>> remove_past = lambda s: kiwi.join(t for t in kiwi.tokenize(s) if t.tagged_form != '었/EP')
>> remove_past('먹었다')
'먹다'
>> remove_past('먼 길을 걸었다')
'먼 길을 걷다'
>> remove_past('전화를 걸었다.')
'전화를 걸다.'
```
        '''
        return super().join(morphs, lm_search)
def load_user_dictionary(self, dict_path: str) ‑> int

사용자 정의 사전을 읽어옵니다. 사용자 정의 사전 파일은 UTF-8로 인코딩된 텍스트 파일이어야 합니다. 사용자 정의 사전으로 추가된 단어의 개수를 반환합니다.

Parameters

dict_path : str
사용자 정의 사전 파일의 경로

Returns

added_cnt : int
사용자 정의 사전 파일을 이용해 추가된 단어의 개수를 반환합니다.

Notes

사용자 정의 사전 파일의 형식에 대해서는 여기를 참조하세요.

Expand source code
    def load_user_dictionary(self,
        dict_path:str
    ) -> int:
        '''사용자 정의 사전을 읽어옵니다. 사용자 정의 사전 파일은 UTF-8로 인코딩된 텍스트 파일이어야 합니다.
사용자 정의 사전으로 추가된 단어의 개수를 반환합니다.
    
Parameters
----------
dict_path: str
    사용자 정의 사전 파일의 경로

Returns
-------
added_cnt: int
    사용자 정의 사전 파일을 이용해 추가된 단어의 개수를 반환합니다.

Notes
-----
사용자 정의 사전 파일의 형식에 대해서는 <a href='#_3'>여기</a>를 참조하세요.
        '''

        return super().load_user_dictionary(dict_path)
def morpheme(self, idx: int)
Expand source code
def morpheme(self,
    idx:int,
):
    return super().morpheme(idx)
def perform(self, texts, top_n: Optional[int] = 1, match_options: Optional[int] = Match.ALL, min_cnt: Optional[int] = 10, max_word_len: Optional[int] = 10, min_score: Optional[float] = 0.25, pos_score: Optional[float] = -3.0, lm_filter: Optional[bool] = True)

현재 모델의 사본을 만들어 Kiwi.extract_add_words()메소드로 말뭉치에서 단어를 추출하여 추가하고, Kiwi.analyze()로 형태소 분석을 실시합니다. 이 메소드 호출 후 모델의 사본은 파괴되므로, 말뭉치에서 추출된 단어들은 다시 모델에서 제거되고, 메소드 실행 전과 동일한 상태로 돌아갑니다.

Changed in version: 0.10.0

입력을 단순히 문자열의 리스트로 주고, 분석 결과 역시 별도의 receiver로 받지 않고 바로 메소드의 리턴값으로 받게 변경되었습니다. 자세한 내용은 여기를 확인해주세요.

Deprecated since version: 0.10.1

추후 버전에서 변경, 혹은 제거될 가능성이 있는 메소드입니다.

Parameters

texts : Iterable[str]
분석할 문자열의 리스트, 혹은 Iterable입니다.
top_n : int
분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options : Match

Added in version: 0.8.0

추출한 특수 문자열 패턴을 지정합니다. Match의 조합으로 설정할 수 있습니다.

min_cnt : int
추출할 단어의 최소 출현 빈도입니다. 이 빈도보다 적게 등장한 문자열은 단어 후보에서 제외됩니다.
max_word_len : int
추출할 단어 후보의 최대 길이입니다. 이 길이보다 긴 단어 후보는 탐색되지 않습니다.
min_score : float
단어 후보의 최소 점수입니다. 이 점수보다 낮은 단어 후보는 고려되지 않습니다.
pos_score : float
단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.

Returns

results : Iterable[List[Tuple[List[Token], float]]]
반환값은 Kiwi.analyze()의 results와 동일합니다.
Expand source code
    def perform(self,
        texts,
        top_n:Optional[int] = 1,
        match_options:Optional[int] = Match.ALL,
        min_cnt:Optional[int] = 10,
        max_word_len:Optional[int] = 10,
        min_score:Optional[float] = 0.25,
        pos_score:Optional[float] = -3.,
        lm_filter:Optional[bool] = True,
    ):
        '''현재 모델의 사본을 만들어
`kiwipiepy.Kiwi.extract_add_words`메소드로 말뭉치에서 단어를 추출하여 추가하고, `kiwipiepy.Kiwi.analyze`로 형태소 분석을 실시합니다.
이 메소드 호출 후 모델의 사본은 파괴되므로, 말뭉치에서 추출된 단어들은 다시 모델에서 제거되고, 메소드 실행 전과 동일한 상태로 돌아갑니다.

.. versionchanged:: 0.10.0
    입력을 단순히 문자열의 리스트로 주고, 분석 결과 역시 별도의 `receiver`로 받지 않고 바로 메소드의 리턴값으로 받게 변경되었습니다.
    자세한 내용은 <a href="#0100">여기</a>를 확인해주세요.

.. deprecated:: 0.10.1
    추후 버전에서 변경, 혹은 제거될 가능성이 있는 메소드입니다.

Parameters
----------
texts: Iterable[str]
    분석할 문자열의 리스트, 혹은 Iterable입니다.
top_n: int
    분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options: kiwipiepy.const.Match
    .. versionadded:: 0.8.0

    추출한 특수 문자열 패턴을 지정합니다. `kiwipiepy.const.Match`의 조합으로 설정할 수 있습니다.
min_cnt: int
    추출할 단어의 최소 출현 빈도입니다. 이 빈도보다 적게 등장한 문자열은 단어 후보에서 제외됩니다.
max_word_len: int
    추출할 단어 후보의 최대 길이입니다. 이 길이보다 긴 단어 후보는 탐색되지 않습니다.
min_score: float
    단어 후보의 최소 점수입니다. 이 점수보다 낮은 단어 후보는 고려되지 않습니다.
pos_score: float
    단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.

Returns
-------
results: Iterable[List[Tuple[List[kiwipiepy.Token], float]]]
    반환값은 `kiwipiepy.Kiwi.analyze`의 results와 동일합니다.
        '''

        warnings.warn(
            "`perform()` will be removed in future version.",
            DeprecationWarning
        )
        return super().perform(
            texts,
            top_n,
            match_options,
            min_cnt,
            max_word_len,
            min_score,
            pos_score,
            lm_filter,
        )
def prepare(self)

Deprecated since version: 0.10.0

0.10.0버전부터 내부적으로 prepare()가 필요한 순간에 스스로 처리를 하도록 변경되어서 이제 이 메소드를 직접 호출할 필요가 없습니다. 차기 버전에서 제거될 예정입니다.

Expand source code
def prepare(self):
    '''.. deprecated:: 0.10.0
0.10.0버전부터 내부적으로 prepare()가 필요한 순간에 스스로 처리를 하도록 변경되어서 이제 이 메소드를 직접 호출할 필요가 없습니다.
차기 버전에서 제거될 예정입니다.
    '''

    warnings.warn(
        "`prepare()` has no effect and will be removed in future version.",
        DeprecationWarning
    )
def set_cutoff_threshold(self, threshold: float)

Beam 탐색 시 미리 제거할 후보의 점수 차를 설정합니다. 이 값이 클 수록 더 많은 후보를 탐색하게 되므로 분석 속도가 느려지지만 정확도가 올라갑니다. 반대로 이 값을 낮추면 더 적은 후보를 탐색하여 속도가 빨라지지만 정확도는 낮아집니다. 초기값은 5입니다.

Added in version: 0.9.0

초기값이 8에서 5로 변경되었습니다.

Deprecated since version: 0.10.0

차기 버전에서 제거될 예정입니다. 이 메소드 대신 Kiwi.cutoff_threshold를 직접 수정하십시오.

Parameters

threshold : float
0 보다 큰 실수
Expand source code
    def set_cutoff_threshold(self,
        threshold:float
    ):
        '''Beam 탐색 시 미리 제거할 후보의 점수 차를 설정합니다. 이 값이 클 수록 더 많은 후보를 탐색하게 되므로 분석 속도가 느려지지만 정확도가 올라갑니다.
반대로 이 값을 낮추면 더 적은 후보를 탐색하여 속도가 빨라지지만 정확도는 낮아집니다. 초기값은 5입니다.

.. versionadded:: 0.9.0
    초기값이 8에서 5로 변경되었습니다.

.. deprecated:: 0.10.0
    차기 버전에서 제거될 예정입니다.
    이 메소드 대신 `Kiwi.cutoff_threshold`를 직접 수정하십시오.

Parameters
----------
threshold: float
    0 보다 큰 실수
        '''

        warnings.warn(
            "`set_cutoff_threshold(v)` will be removed in future version. Use `Kiwi.cutoff_threshold = v` instead.",
            DeprecationWarning
        )
        self._cutoff_threshold = threshold
def set_option(self, option: int, value: int)

현재 모델의 설정값을 변경합니다.

Deprecated since version: 0.10.0

차기 버전에서 제거될 예정입니다. 이 메소드 대신 Kiwi.integrate_allomorph값을 직접 수정하십시오.

Parameters

option : Option
변경할 옵션의 열거값. 현재는 Option.INTEGRATE_ALLOMORPH만 지원합니다.
value : int
0으로 설정할 경우 해당 옵션을 해제, 0이 아닌 값으로 설정할 경우 해당 옵션을 설정합니다.
Expand source code
    def set_option(self, 
        option:int,
        value:int,
    ):
        '''현재 모델의 설정값을 변경합니다.

.. deprecated:: 0.10.0
    차기 버전에서 제거될 예정입니다. 
    이 메소드 대신 `Kiwi.integrate_allomorph`값을 직접 수정하십시오.

Parameters
----------
option: kiwipiepy.const.Option
    변경할 옵션의 열거값. 현재는 `kiwipiepy.const.Option.INTEGRATE_ALLOMORPH`만 지원합니다.
value: int
    0으로 설정할 경우 해당 옵션을 해제, 0이 아닌 값으로 설정할 경우 해당 옵션을 설정합니다.
        '''

        warnings.warn(
            "`set_option()` will be removed in future version.",
            DeprecationWarning
        )
        if option != Option.INTEGRATE_ALLOMORPH: raise ValueError("Wrong `option` value: {}".format(option))
        self._integrate_allomorph = bool(value)
def space(self, text: Union[str, Iterable[str]], reset_whitespace: Optional[bool] = False) ‑> Union[str, Iterable[str]]

Added in version: 0.11.1

입력 텍스트에서 띄어쓰기를 교정하여 반환합니다.

Parameters

text : Union[str, Iterable[str]]
분석할 문자열입니다. 이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며 str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
reset_whitespace : bool
True인 경우 이미 띄어쓰기된 부분을 붙이는 교정도 적극적으로 수행합니다. 기본값은 False로, 이 경우에는 붙어 있는 단어를 띄어쓰는 교정 위주로 수행합니다.

Returns

result : str
text를 str으로 준 경우. 입력 텍스트의 띄어쓰기 교정 결과를 반환합니다.
iterable_of_results : Iterable[str]
text를 Iterable[str]으로 준 경우. 입력 텍스트의 띄어쓰기 교정 결과를 반환합니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes

이 메소드의 띄어쓰기 교정 기능은 형태소 분석에 기반합니다. 따라서 형태소 중간에 공백이 삽입된 경우 교정 결과가 부정확할 수 있습니다. 이 경우 Kiwi.space_tolerance를 조절하여 형태소 내 공백을 무시하거나, reset_whitespace=True로 설정하여 아예 기존 공백을 무시하고 띄어쓰기를 하도록 하면 결과를 개선할 수 있습니다.

>> kiwi.space("띄어쓰기없이작성된텍스트네이걸교정해줘")
"띄어쓰기 없이 작성된 텍스트네 이걸 교정해 줘."
>> kiwi.space("띄 어 쓰 기 문 제 가 있 습 니 다")
"띄어 쓰기 문 제 가 있 습 니 다"
>> kiwi.space_tolerance = 2 # 형태소 내 공백을 최대 2개까지 허용
>> kiwi.space("띄 어 쓰 기 문 제 가 있 습 니 다")
"띄어 쓰기 문제가 있습니다"
>> kiwi.space("띄 어 쓰 기 문 제 가 있 습 니 다", reset_whitespace=True) # 기존 공백 전부 무시
"띄어쓰기 문제가 있습니다"
Expand source code
    def space(self,
        text:Union[str, Iterable[str]],
        reset_whitespace:Optional[bool] = False,
    ) -> Union[str, Iterable[str]]:
        '''..versionadded:: 0.11.1

입력 텍스트에서 띄어쓰기를 교정하여 반환합니다.

Parameters
----------
text: Union[str, Iterable[str]]
    분석할 문자열입니다. 
    이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며
    str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
reset_whitespace: bool
    True인 경우 이미 띄어쓰기된 부분을 붙이는 교정도 적극적으로 수행합니다. 
    기본값은 False로, 이 경우에는 붙어 있는 단어를 띄어쓰는 교정 위주로 수행합니다.

Returns
-------
result: str
    text를 str으로 준 경우.
    입력 텍스트의 띄어쓰기 교정 결과를 반환합니다.

iterable_of_results: Iterable[str]
    text를 Iterable[str]으로 준 경우.
    입력 텍스트의 띄어쓰기 교정 결과를 반환합니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes
-----
이 메소드의 띄어쓰기 교정 기능은 형태소 분석에 기반합니다. 
따라서 형태소 중간에 공백이 삽입된 경우 교정 결과가 부정확할 수 있습니다.
이 경우 `Kiwi.space_tolerance`를 조절하여 형태소 내 공백을 무시하거나, 
`reset_whitespace=True`로 설정하여 아예 기존 공백을 무시하고 띄어쓰기를 하도록 하면 결과를 개선할 수 있습니다.

```python
>> kiwi.space("띄어쓰기없이작성된텍스트네이걸교정해줘")
"띄어쓰기 없이 작성된 텍스트네 이걸 교정해 줘."
>> kiwi.space("띄 어 쓰 기 문 제 가 있 습 니 다")
"띄어 쓰기 문 제 가 있 습 니 다"
>> kiwi.space_tolerance = 2 # 형태소 내 공백을 최대 2개까지 허용
>> kiwi.space("띄 어 쓰 기 문 제 가 있 습 니 다")
"띄어 쓰기 문제가 있습니다"
>> kiwi.space("띄 어 쓰 기 문 제 가 있 습 니 다", reset_whitespace=True) # 기존 공백 전부 무시
"띄어쓰기 문제가 있습니다"
```
        '''
        ws = re.compile(r'(?<=[가-힣])\s+(?=[가-힣.,?!:;])')
        any_ws = re.compile(r'\s+')
        space_insertable = re.compile('|'.join([
            r'(([^SUWX]|X[RS]|S[EH]).* ([NMI]|V[VAX]|VCN|XR|XPN|S[WLHN]))',
            r'(SN ([MI]|N[PR]|NN[GP]|V[VAX]|VCN|XR|XPN|S[WH]))',
            r'((S[FPL]).* ([NMI]|V[VAX]|VCN|XR|XPN|S[WH]))',
        ]))

        def _reset(t):
            return ws.sub('', t)

        def _space(arg):
            tokens, raw = arg
            tokens = tokens[0][0]
            chunks = []
            last = 0
            prev_tag = None
            for t in tokens:
                if last < t.start:
                    if (t.tag.startswith('E') or t.tag.startswith('J') or t.tag.startswith('XS')
                        or t.tag == 'VX' and t.form in '하지'
                    ):
                        s = any_ws.sub('', raw[last:t.start])
                    else:
                        s = raw[last:t.start]
                    if s: chunks.append(s)
                    last = t.start
                if prev_tag and space_insertable.match(prev_tag + ' ' + t.tag):
                    if t.tag == 'VX' and t.form in '하지':
                        pass # 보조 용언 중 `하다/지다`는 붙여쓴다.
                    elif not chunks[-1][-1].isspace():
                        # 이전에 공백이 없는 경우만 삽입
                        chunks.append(' ') 
                if last < t.end:
                    s = any_ws.sub('', raw[last:t.end])
                    if s: chunks.append(s)
                last = t.end
                prev_tag = t.tag
            if last < len(raw):
                chunks.append(raw[last:])
            return ''.join(chunks)

        if isinstance(text, str):
            if reset_whitespace: text = _reset(text)
            return _space((super().analyze(text, 1, Match.ALL), text))
        else:
            if reset_whitespace: text = map(_reset, text)
            return map(_space, super().analyze(text, 1, Match.ALL, echo=True))
def split_into_sents(self, text: Union[str, Iterable[str]], match_options: Optional[int] = Match.ALL, normalize_coda: Optional[bool] = False, return_tokens: Optional[bool] = False, return_sub_sents: Optional[bool] = True) ‑> Union[List[Sentence], Iterable[List[Sentence]]]

Added in version: 0.10.3

입력 텍스트를 문장 단위로 분할하여 반환합니다. 이 메소드는 문장 분할 과정에서 내부적으로 형태소 분석을 사용하므로 문장 분할과 동시에 형태소 분석 결과를 얻는 데 사용할 수도 있습니다.

Parameters

text : Union[str, Iterable[str]]
분석할 문자열입니다. 이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며 str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
match_options : Match
추출한 특수 문자열 패턴을 지정합니다. Match의 조합으로 설정할 수 있습니다.
normalize_coda : bool
True인 경우 '먹었엌ㅋㅋ'처럼 받침이 덧붙어서 분석에 실패하는 경우, 받침을 분리하여 정규화합니다.
return_tokens : bool
True인 경우 문장별 형태소 분석 결과도 함께 반환합니다.
return_sub_Sents : bool

Added in version: 0.14.0

True인 경우 문장 내 안긴 문장의 목록도 함께 반환합니다.

Returns

sentences : List[Sentence]
text를 str으로 준 경우. 문장 분할 결과인 Sentence의 리스트를 반환합니다.
iterable_of_sentences : Iterable[List[Sentence]]
text를 Iterable[str]으로 준 경우. 반환값은 sentences의 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes

문장 분리 기능은 형태소 분석에 기반합니다. 따라서 return_tokens의 True/False여부에 상관없이 내부적으로 형태소 분석을 수행하며, 출력 시에만 형태소 목록을 넣거나 뺄 뿐이므로 이에 따른 실행 속도 차이는 없습니다. 그러므로 문장 분리 기능과 형태소 분석을 동시에 수행해야하는 경우 return_tokens=True로 설정하는 게, 문장 분리 후 따로 형태소 분석을 수행하는 것보다 효율적입니다.

>> kiwi.split_into_sents("여러 문장으로 구성된 텍스트네 이걸 분리해줘")
[Sentence(text='여러 문장으로 구성된 텍스트네', start=0, end=16, tokens=None, subs=[]),
 Sentence(text='이걸 분리해줘', start=17, end=24, tokens=None, subs=[])]

>> kiwi.split_into_sents("여러 문장으로 구성된 텍스트네 이걸 분리해줘", return_tokens=True)
[Sentence(text='여러 문장으로 구성된 텍스트네', start=0, end=16, tokens=[
  Token(form='여러', tag='MM', start=0, len=2), 
  Token(form='문장', tag='NNG', start=3, len=2), 
  Token(form='으로', tag='JKB', start=5, len=2), 
  Token(form='구성', tag='NNG', start=8, len=2), 
  Token(form='되', tag='XSV', start=10, len=1), 
  Token(form='ᆫ', tag='ETM', start=10, len=1), 
  Token(form='텍스트', tag='NNG', start=12, len=3), 
  Token(form='이', tag='VCP', start=15, len=1), 
  Token(form='네', tag='EF', start=15, len=1)
 ], subs=[]),
 Sentence(text='이걸 분리해줘', start=17, end=24, tokens=[
  Token(form='이거', tag='NP', start=17, len=2), 
  Token(form='ᆯ', tag='JKO', start=19, len=0), 
  Token(form='분리', tag='NNG', start=20, len=2), 
  Token(form='하', tag='XSV', start=22, len=1), 
  Token(form='어', tag='EC', start=22, len=1), 
  Token(form='주', tag='VX', start=23, len=1), 
  Token(form='어', tag='EF', start=23, len=1)
 ], subs=[])]

# 0.14.0 버전부터는 문장 안에 또 다른 문장이 포함된 경우도 처리 가능
>> kiwi.split_into_sents("회사의 정보 서비스를 책임지고 있는 로웬버그John Loewenberg는" 
     "<서비스 산업에 있어 종이는 혈관내의 콜레스트롤과 같다. 나쁜 종이는 동맥을 막는 내부의 물질이다.>"
     "라고 말한다.")
[Sentence(text='회사의 정보 서비스를 책임지고 있는 로웬버그John Loewenberg는' 
  '<서비스 산업에 있어 종이는 혈관내의 콜레스트롤과 같다. 나쁜 종이는 동맥을 막는 내부의 물질이다.>'
  '라고 말한다.', start=0, end=104, tokens=None, subs=[
  Sentence(text='서비스 산업에 있어 종이는 혈관내의 콜레스트롤과 같다.', start=42, end=72, tokens=None, subs=None), 
  Sentence(text='나쁜 종이는 동맥을 막는 내부의 물질이다.', start=73, end=96, tokens=None, subs=None)
])]
Expand source code
    def split_into_sents(self, 
        text:Union[str, Iterable[str]], 
        match_options:Optional[int] = Match.ALL, 
        normalize_coda:Optional[bool] = False,
        return_tokens:Optional[bool] = False,
        return_sub_sents:Optional[bool] = True,
    ) -> Union[List[Sentence], Iterable[List[Sentence]]]:
        '''..versionadded:: 0.10.3

입력 텍스트를 문장 단위로 분할하여 반환합니다. 
이 메소드는 문장 분할 과정에서 내부적으로 형태소 분석을 사용하므로 문장 분할과 동시에 형태소 분석 결과를 얻는 데 사용할 수도 있습니다.

Parameters
----------
text: Union[str, Iterable[str]]
    분석할 문자열입니다. 
    이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며
    str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
match_options: kiwipiepy.const.Match
    추출한 특수 문자열 패턴을 지정합니다. `kiwipiepy.const.Match`의 조합으로 설정할 수 있습니다.
normalize_coda: bool
    True인 경우 '먹었엌ㅋㅋ'처럼 받침이 덧붙어서 분석에 실패하는 경우, 받침을 분리하여 정규화합니다.
return_tokens: bool
    True인 경우 문장별 형태소 분석 결과도 함께 반환합니다.
return_sub_Sents: bool
    ..versionadded:: 0.14.0

    True인 경우 문장 내 안긴 문장의 목록도 함께 반환합니다.

Returns
-------
sentences: List[kiwipiepy.Sentence]
    text를 str으로 준 경우.
    문장 분할 결과인 `kiwipiepy.Sentence`의 리스트를 반환합니다.

iterable_of_sentences: Iterable[List[kiwipiepy.Sentence]]
    text를 Iterable[str]으로 준 경우.
    반환값은 `sentences`의 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes
-----
문장 분리 기능은 형태소 분석에 기반합니다. 따라서 return_tokens의 True/False여부에 상관없이 내부적으로 형태소 분석을 수행하며,
출력 시에만 형태소 목록을 넣거나 뺄 뿐이므로 이에 따른 실행 속도 차이는 없습니다.
그러므로 문장 분리 기능과 형태소 분석을 동시에 수행해야하는 경우 `return_tokens=True`로 설정하는 게, 
문장 분리 후 따로 형태소 분석을 수행하는 것보다 효율적입니다.

```python
>> kiwi.split_into_sents("여러 문장으로 구성된 텍스트네 이걸 분리해줘")
[Sentence(text='여러 문장으로 구성된 텍스트네', start=0, end=16, tokens=None, subs=[]),
 Sentence(text='이걸 분리해줘', start=17, end=24, tokens=None, subs=[])]

>> kiwi.split_into_sents("여러 문장으로 구성된 텍스트네 이걸 분리해줘", return_tokens=True)
[Sentence(text='여러 문장으로 구성된 텍스트네', start=0, end=16, tokens=[
  Token(form='여러', tag='MM', start=0, len=2), 
  Token(form='문장', tag='NNG', start=3, len=2), 
  Token(form='으로', tag='JKB', start=5, len=2), 
  Token(form='구성', tag='NNG', start=8, len=2), 
  Token(form='되', tag='XSV', start=10, len=1), 
  Token(form='ᆫ', tag='ETM', start=10, len=1), 
  Token(form='텍스트', tag='NNG', start=12, len=3), 
  Token(form='이', tag='VCP', start=15, len=1), 
  Token(form='네', tag='EF', start=15, len=1)
 ], subs=[]),
 Sentence(text='이걸 분리해줘', start=17, end=24, tokens=[
  Token(form='이거', tag='NP', start=17, len=2), 
  Token(form='ᆯ', tag='JKO', start=19, len=0), 
  Token(form='분리', tag='NNG', start=20, len=2), 
  Token(form='하', tag='XSV', start=22, len=1), 
  Token(form='어', tag='EC', start=22, len=1), 
  Token(form='주', tag='VX', start=23, len=1), 
  Token(form='어', tag='EF', start=23, len=1)
 ], subs=[])]

# 0.14.0 버전부터는 문장 안에 또 다른 문장이 포함된 경우도 처리 가능
>> kiwi.split_into_sents("회사의 정보 서비스를 책임지고 있는 로웬버그John Loewenberg는" 
     "<서비스 산업에 있어 종이는 혈관내의 콜레스트롤과 같다. 나쁜 종이는 동맥을 막는 내부의 물질이다.>"
     "라고 말한다.")
[Sentence(text='회사의 정보 서비스를 책임지고 있는 로웬버그John Loewenberg는' 
  '<서비스 산업에 있어 종이는 혈관내의 콜레스트롤과 같다. 나쁜 종이는 동맥을 막는 내부의 물질이다.>'
  '라고 말한다.', start=0, end=104, tokens=None, subs=[
  Sentence(text='서비스 산업에 있어 종이는 혈관내의 콜레스트롤과 같다.', start=42, end=72, tokens=None, subs=None), 
  Sentence(text='나쁜 종이는 동맥을 막는 내부의 물질이다.', start=73, end=96, tokens=None, subs=None)
])]
```
        '''
        def _make_result(arg):
            sents, raw_input = arg
            ret = []
            for sent in sents:
                start = sent[0].start
                end = sent[-1].end
                tokens = sent if return_tokens else None
                subs = None
                if return_sub_sents:
                    subs = []
                    sub_toks = []
                    last = 0
                    for tok in sent:
                        if tok.sub_sent_position != last:
                            if last:
                                subs.append(Sentence(raw_input[sub_start:last_end], sub_start, last_end, sub_toks if return_tokens else None, None))
                                sub_toks = []
                            sub_start = tok.start
                        if tok.sub_sent_position:
                            sub_toks.append(tok)
                        last = tok.sub_sent_position
                        last_end = tok.end
                ret.append(Sentence(raw_input[start:end], start, end, tokens, subs))
            return ret

        if isinstance(text, str):
            return _make_result((self._tokenize(text, match_options=match_options, normalize_coda=normalize_coda, split_sents=True), text))

        return map(_make_result, self._tokenize(text, match_options=match_options, normalize_coda=normalize_coda, split_sents=True, echo=True))
def tokenize(self, text: Union[str, Iterable[str]], match_options: Optional[int] = Match.ALL, normalize_coda: Optional[bool] = False, split_sents: Optional[bool] = False, stopwords: Optional[Stopwords] = None, echo: Optional[bool] = False)

Added in version: 0.10.2

analyze와는 다르게 형태소 분석결과만 간단하게 반환합니다.

Parameters

text : Union[str, Iterable[str]]
분석할 문자열입니다. 이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며 str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
match_options : Match
추출한 특수 문자열 패턴을 지정합니다. Match의 조합으로 설정할 수 있습니다.
normalize_coda : bool
True인 경우 '먹었엌ㅋㅋ'처럼 받침이 덧붙어서 분석에 실패하는 경우, 받침을 분리하여 정규화합니다.
split_sents : bool

Added in version: 0.10.3

True인 경우 형태소 리스트를 문장별로 묶어서 반환합니다. 자세한 내용은 아래의 Returns 항목을 참조하세요.

stopwords : Stopwords

Added in version: 0.10.3

이 인자로 None이 아닌 Stopwords 객체를 줄 경우, 형태소 분석 결과 중 그 객체에 포함되는 불용어를 제외한 나머지 결과만을 반환합니다.

echo : bool

Added in version: 0.11.2

이 값이 True이고 text를 str의 Iterable로 준 경우, 분석 결과뿐만 아니라 원본 입력을 함께 반환합니다. text가 단일 str인 경우 이 인자는 무시됩니다.

Returns

result : List[Token]
split_sents == False일때 text를 str으로 준 경우. Token의 리스트를 반환합니다.
results : Iterable[List[Token]]
split_sents == False일때 text를 Iterable[str]으로 준 경우. 반환값은 result의 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.
results_with_echo : Iterable[Tuple[List[Token], str]]
split_sents == False이고 echo=True일때 text를 Iterable[str]으로 준 경우. 반환값은 (result의 iterator, raw_input)으로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.
result_by_sent : List[List[Token]]
split_sents == True일때 text를 str으로 준 경우. 형태소 분석 결과가 문장별로 묶여서 반환됩니다. 즉, 전체 문장이 n개라고 할 때, result_by_sent[0] ~ result_by_sent[n-1]에는 각 문장별 분석 결과가 들어갑니다.
results_by_sent : Iterable[List[List[Token]]]
split_sents == True일때 text를 Iterable[str]으로 준 경우. 반환값은 result_by_sent의 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.
results_by_sent_with_echo : Iterable[Tuple[List[List[Token]], str]]
split_sents == True이고 echo=True일때 text를 Iterable[str]으로 준 경우. 반환값은 (result_by_sent의 iterator, raw_input)으로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes

>> kiwi.tokenize("안녕하세요 형태소 분석기 키위입니다.")
[Token(form='안녕', tag='NNG', start=0, len=2),
 Token(form='하', tag='XSA', start=2, len=1),
 Token(form='시', tag='EP', start=4, len=1),
 Token(form='어요', tag='EC', start=3, len=2),
 Token(form='형태소', tag='NNG', start=6, len=3),
 Token(form='분석', tag='NNG', start=10, len=2),
 Token(form='기', tag='NNG', start=12, len=1),
 Token(form='키위', tag='NNG', start=14, len=2),
 Token(form='이', tag='VCP', start=16, len=1),
 Token(form='ᆸ니다', tag='EF', start=17, len=2),
 Token(form='.', tag='SF', start=19, len=1)]

# normalize_coda 옵션을 사용하면 
# 덧붙은 받침 때문에 분석이 깨지는 경우를 방지할 수 있습니다.
>> kiwi.tokenize("ㅋㅋㅋ 이런 것도 분석이 될까욬ㅋㅋ?", normalize_coda=True)
[Token(form='ㅋㅋㅋ', tag='SW', start=0, len=3),
 Token(form='이런', tag='MM', start=4, len=2),
 Token(form='것', tag='NNB', start=7, len=1),
 Token(form='도', tag='JX', start=8, len=1),
 Token(form='분석', tag='NNG', start=10, len=2),
 Token(form='이', tag='JKS', start=12, len=1),
 Token(form='되', tag='VV', start=14, len=1),
 Token(form='ᆯ까요', tag='EC', start=15, len=2),
 Token(form='ㅋㅋㅋ', tag='SW', start=17, len=2),
 Token(form='?', tag='SF', start=19, len=1)]

# Stopwords 클래스를 바로 적용하여 불용어를 걸러낼 수 있습니다.
>> from kiwipiepy.utils import Stopwords
>> stopwords = Stopwords()
>> kiwi.tokenize("분석 결과에서 불용어만 제외하고 출력할 수도 있다.", stopwords=stopwords)
[Token(form='분석', tag='NNG', start=0, len=2),
 Token(form='결과', tag='NNG', start=3, len=2),
 Token(form='불', tag='XPN', start=8, len=1),
 Token(form='용어', tag='NNG', start=9, len=2),
 Token(form='제외', tag='NNG', start=13, len=2),
 Token(form='출력', tag='NNG', start=18, len=2)]
Expand source code
    def tokenize(self, 
        text:Union[str, Iterable[str]], 
        match_options:Optional[int] = Match.ALL,
        normalize_coda:Optional[bool] = False,
        split_sents:Optional[bool] = False,
        stopwords:Optional[Stopwords] = None,
        echo:Optional[bool] = False,
    ):
        '''.. versionadded:: 0.10.2

`analyze`와는 다르게 형태소 분석결과만 간단하게 반환합니다.

Parameters
----------
text: Union[str, Iterable[str]]
    분석할 문자열입니다. 
    이 인자를 단일 str로 줄 경우, 싱글스레드에서 처리하며
    str의 Iterable로 줄 경우, 멀티스레드로 분배하여 처리합니다.
match_options: kiwipiepy.const.Match
    추출한 특수 문자열 패턴을 지정합니다. `kiwipiepy.const.Match`의 조합으로 설정할 수 있습니다.
normalize_coda: bool
    True인 경우 '먹었엌ㅋㅋ'처럼 받침이 덧붙어서 분석에 실패하는 경우, 받침을 분리하여 정규화합니다.
split_sents: bool
    .. versionadded:: 0.10.3

    True인 경우 형태소 리스트를 문장별로 묶어서 반환합니다. 자세한 내용은 아래의 Returns 항목을 참조하세요.
stopwords: Stopwords
    .. versionadded:: 0.10.3

    이 인자로 None이 아닌 `kiwipiepy.utils.Stopwords` 객체를 줄 경우, 형태소 분석 결과 중 그 객체에 포함되는 불용어를 제외한 나머지 결과만을 반환합니다.
echo: bool
    .. versionadded:: 0.11.2

    이 값이 True이고 `text`를 str의 Iterable로 준 경우, 분석 결과뿐만 아니라 원본 입력을 함께 반환합니다. `text`가 단일 str인 경우 이 인자는 무시됩니다.

Returns
-------
result: List[kiwipiepy.Token]
    split_sents == False일때 text를 str으로 준 경우.
    `kiwipiepy.Token`의 리스트를 반환합니다.

results: Iterable[List[kiwipiepy.Token]]
    split_sents == False일때 text를 Iterable[str]으로 준 경우.
    반환값은 `result`의 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

results_with_echo: Iterable[Tuple[List[kiwipiepy.Token], str]]
    split_sents == False이고 echo=True일때 text를 Iterable[str]으로 준 경우.
    반환값은 (`result`의 iterator, `raw_input`)으로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

result_by_sent: List[List[kiwipiepy.Token]]
    split_sents == True일때 text를 str으로 준 경우.
    형태소 분석 결과가 문장별로 묶여서 반환됩니다.
    즉, 전체 문장이 n개라고 할 때, `result_by_sent[0] ~ result_by_sent[n-1]`에는 각 문장별 분석 결과가 들어갑니다.

results_by_sent: Iterable[List[List[kiwipiepy.Token]]]
    split_sents == True일때 text를 Iterable[str]으로 준 경우.
    반환값은 `result_by_sent`의 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

results_by_sent_with_echo: Iterable[Tuple[List[List[kiwipiepy.Token]], str]]
    split_sents == True이고 echo=True일때 text를 Iterable[str]으로 준 경우.
    반환값은 (`result_by_sent`의 iterator, `raw_input`)으로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.

Notes
-----

```python
>> kiwi.tokenize("안녕하세요 형태소 분석기 키위입니다.")
[Token(form='안녕', tag='NNG', start=0, len=2),
 Token(form='하', tag='XSA', start=2, len=1),
 Token(form='시', tag='EP', start=4, len=1),
 Token(form='어요', tag='EC', start=3, len=2),
 Token(form='형태소', tag='NNG', start=6, len=3),
 Token(form='분석', tag='NNG', start=10, len=2),
 Token(form='기', tag='NNG', start=12, len=1),
 Token(form='키위', tag='NNG', start=14, len=2),
 Token(form='이', tag='VCP', start=16, len=1),
 Token(form='ᆸ니다', tag='EF', start=17, len=2),
 Token(form='.', tag='SF', start=19, len=1)]

# normalize_coda 옵션을 사용하면 
# 덧붙은 받침 때문에 분석이 깨지는 경우를 방지할 수 있습니다.
>> kiwi.tokenize("ㅋㅋㅋ 이런 것도 분석이 될까욬ㅋㅋ?", normalize_coda=True)
[Token(form='ㅋㅋㅋ', tag='SW', start=0, len=3),
 Token(form='이런', tag='MM', start=4, len=2),
 Token(form='것', tag='NNB', start=7, len=1),
 Token(form='도', tag='JX', start=8, len=1),
 Token(form='분석', tag='NNG', start=10, len=2),
 Token(form='이', tag='JKS', start=12, len=1),
 Token(form='되', tag='VV', start=14, len=1),
 Token(form='ᆯ까요', tag='EC', start=15, len=2),
 Token(form='ㅋㅋㅋ', tag='SW', start=17, len=2),
 Token(form='?', tag='SF', start=19, len=1)]

# Stopwords 클래스를 바로 적용하여 불용어를 걸러낼 수 있습니다.
>> from kiwipiepy.utils import Stopwords
>> stopwords = Stopwords()
>> kiwi.tokenize("분석 결과에서 불용어만 제외하고 출력할 수도 있다.", stopwords=stopwords)
[Token(form='분석', tag='NNG', start=0, len=2),
 Token(form='결과', tag='NNG', start=3, len=2),
 Token(form='불', tag='XPN', start=8, len=1),
 Token(form='용어', tag='NNG', start=9, len=2),
 Token(form='제외', tag='NNG', start=13, len=2),
 Token(form='출력', tag='NNG', start=18, len=2)]
```
        '''
        return self._tokenize(text, match_options, normalize_coda, split_sents, stopwords, echo)
class Sentence (text, start, end, tokens, subs)

문장 분할 결과를 담기 위한 namedtuple입니다.

Ancestors

  • builtins.tuple

Instance variables

var end

전체 텍스트 내에서 분할된 문장이 끝나는 위치 (문자 단위)

var start

전체 텍스트 내에서 분할된 문장이 시작하는 위치 (문자 단위)

var subs

Added in version: 0.14.0

현 문장 내에 포함된 안긴 문장의 목록

var text

분할된 문장의 텍스트

var tokens

분할된 문장의 형태소 분석 결과

class Token (*args, **kwargs)

Token은 분석 결과 얻어진 형태소 정보를 담는 데이터 클래스입니다. (form, tag, start, len) 형태의 길이 4의 tuple로 변환 가능합니다.

Instance variables

var base_form

Added in version: 0.11.0

이형태의 경우 원본 형태소의 형태. 일반 형태소의 경우 form과 동일.

var base_id

Added in version: 0.11.0

이형태의 경우 원본 형태소의 고유 ID. 일반 형태소의 경우 id와 동일.

var end

형태소의 입력 텍스트 내 끝 위치 (문자 단위)

var form

형태소의 형태

var id

형태소의 내부 고유 ID

var len

형태소의 입력 텍스트 내 차지 길이 (문자 단위)

var line_number

Added in version: 0.10.3

형태소의 입력 텍스트 내 줄 번호 (0부터 시작)

var raw_form

Added in version: 0.13.0

텍스트 상에 실제로 등장한 형태. 오타가 교정된 경우 form과 다를 수 있음.

var regularity

Added in version: 0.12.0

동/형용사가 규칙 활용하는 경우 True, 불규칙 활용하는 경우 False를 반환합니다. 그 외의 품사에 대해서는 None을 반환합니다.

var score

Added in version: 0.12.0

현재 형태소의 언어 모델 상의 점수를 반환합니다.

var sent_position

Added in version: 0.10.3

형태소의 입력 텍스트 내 문장 번호 (0부터 시작)

var start

형태소의 입력 텍스트 내 시작 위치 (문자 단위)

var sub_sent_position

Added in version: 0.14.0

형태소가 안긴 문장에 속한 경우, 현 문장 내의 안긴 문장 번호. (1부터 시작. 0일 경우 안긴 문장이 아님)

var tag

형태소의 품사 태그

var tagged_form

Added in version: 0.11.1

form과 tag를 형태/품사태그꼴로 합쳐서 반환합니다.

var typo_cost

Added in version: 0.13.0

현재 형태소의 오타 교정 비용을 반환합니다.

var word_position

Added in version: 0.10.2

형태소의 입력 텍스트 내 어절 위치 (공백 기준, 문장별로 0부터 시작)

class TypoDefinition (orig: List[str], error: List[str], cost: float, condition: Optional[str] = None)

Added in version: 0.13.0

오타 생성 규칙을 정의하는 dataclass

Parameters

orig : List[str]
원본 문자열
error : List[str]
교체될 오타의 문자열
cost : float
교체 비용
condition : str
오타 교체가 가능한 환경 조건. None, 'any'(아무 글자 뒤), 'vowel'(모음 뒤), 'applosive'(불파음 뒤) 중 하나. 생략 시 기본값은 None입니다.

Notes

origerror는 완전한 음절 혹은 모음이나 자음을 포함할 수 있습니다. 자음의 경우 종성은 ''로 escape해주어야 합니다.

TypoDefinition(['개'], ['게'], 1.0) # '개'를 '게'로 교체
TypoDefinition(['ㅐ'], ['ㅔ'], 1.0) # 모든 'ㅐ'를 'ㅒ'로 교체
TypoDefinition(['ㄲ'], ['ㄱ'], 1.0) # 모든 초성 'ㄲ'을 초성 'ㄱ'으로 교체
TypoDefinition(['ㄳ'], ['ㄱ'], 1.0) # 'ㄳ'에 해당하는 초성은 없으므로 ValueError 발생
TypoDefinition(['\ㄳ'], ['\ㄱ'], 1.0) # 모든 종성 'ㄳ'을 종성 'ㄱ'으로 교체

Class variables

var condition : Optional[str]
var cost : float
var error : List[str]
var orig : List[str]
class TypoTransformer (defs: List[TypoDefinition])

Added in version: 0.13.0

오타 교정 기능에 사용되는 오타 생성기를 정의합니다.

Parameters

defs : List[TypoDefinition]
오타 생성 규칙을 정의하는 TypoDefinition의 List입니다.

Notes

이 클래스의 인스턴스를 Kiwi 생성시의 typos 인자로 주면 Kiwi의 오타 교정 기능이 활성화됩니다.

>> from kiwipiepy import Kiwi, TypoTransformer, TypoDefinition
>> typos = TypoTransformer([
    TypoDefinition(["ㅐ", "ㅔ"], ["ㅐ", "ㅔ"], 1.), # ㅐ 혹은 ㅖ를 ㅐ 혹은 ㅖ로 교체하여 오타를 생성. 생성 비용은 1
    TypoDefinition(["ㅔ"], ["ㅖ"], 2.), # ㅔ를 ㅖ로 교체하여 오타를 생성. 생성 비용은 2
])
>> typos.generate('과제', 1.) # 생성 비용이 1.0이하인 오타들을 생성
[('과제', 0.0), ('과재', 1.0)]
>> typos.generate('과제', 2.) # 생성 비용이 2.0이하인 오타들을 생성
[('과제', 0.0), ('과재', 1.0), ('과졔', 2.0)]

>> kiwi = Kiwi(typos=typos, typo_cost_threshold=2.) # typos에 정의된 오타들을 교정 후보로 삼는 Kiwi 생성.
>> kiwi.tokenize('과재를 했다') 
[Token(form='과제', tag='NNG', start=0, len=2), 
 Token(form='를', tag='JKO', start=2, len=1), 
 Token(form='하', tag='VV', start=4, len=1), 
 Token(form='었', tag='EP', start=4, len=1), 
 Token(form='다', tag='EF', start=5, len=1)]

Ancestors

  • kiwipiepy._TypoTransformer

Instance variables

var defs

현재 오타 생성기의 정의자 목록

Expand source code
@property
def defs(self):
    '''현재 오타 생성기의 정의자 목록'''
    return self._defs

Methods

def generate(self, text: str, cost_threshold: float = 2.5) ‑> List[Tuple[str, float]]

입력 텍스트로부터 오타를 생성합니다.

Parameters

text : str
원본 텍스트
cost_threshold : float
생성 가능한 오타의 최대 비용

Returns

errors : List[Tuple[str, float]]
생성된 오타와 그 생성 비용의 List
Expand source code
    def generate(self, text:str, cost_threshold:float = 2.5) -> List[Tuple[str, float]]:
        '''입력 텍스트로부터 오타를 생성합니다.

Parameters
----------
text: str
    원본 텍스트
cost_threshold: float
    생성 가능한 오타의 최대 비용

Returns
-------
errors: List[Tuple[str, float]]
    생성된 오타와 그 생성 비용의 List
        '''
        return super().generate(text, cost_threshold)