Package kiwipiepy

Kiwipiepy란?

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

현재 Kiwipiepy의 최신 버전은 0.9.2입니다.

Star Issue

시작하기

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

::

$ pip install kiwipiepy

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

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

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

::

$ python -m kiwipiepy

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

::

>> 안녕?
[('안녕', 'IC', 0, 2), ('?', 'SF', 2, 3)]

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

예제

간단한 분석

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

::

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

# 위 코드를 실행하면 다음과 같은 결과가 나옵니다.
# -34.40869140625   [('형태소', 'NNG', 0, 3), ('분석', 'NNG', 4, 2), ('결과', 'NNG', 7, 2), ('이', 'VCP', 9, 1), ('ᆸ니다', 'EF', 10, 2)]
# -41.41796875  [('형태소', 'NNG', 0, 3), ('분석', 'NNG', 4, 2), ('결과', 'NNG', 7, 2), ('이', 'MM', 9, 1), ('ᆸ니다', 'EF', 10, 2)]
# -54.265869140625  [('형태소', 'NNG', 0, 3), ('분석', 'NNG', 4, 2), ('결과', 'NNG', 7, 2), ('입', 'NNG', 9, 1), ('니', 'EC', 10, 1), ('다', 'EC', 11, 1)]
# -54.470458984375  [('형태소', 'NNG', 0, 3), ('분석', 'NNG', 4, 2), ('결과', 'NNG', 7, 2), ('입', 'NNG', 9, 1), ('니다', 'EF', 10, 2)]
# -54.705078125 [('형태소', 'NNG', 0, 3), ('분석', 'NNG', 4, 2), ('결과', 'NNG', 7, 2), ('입', 'NNG', 9, 1), ('이', 'VCP', 10, 1), ('니', 'EC', 10, 1), ('다', 'EC', 11, 1)]

사용자 단어 추가

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

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

::

from kiwipiepy import Kiwi

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

kiwi = Kiwi()
kiwi.prepare()

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)
kiwi.prepare()

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)
kiwi.prepare()

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)
kiwi.load_user_dictionary('userDict.txt')
kiwi.prepare()
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

아래 코드는 0.9.0버전 이전에서 사용되던 멀티스레딩 코드입니다. 현재는 추천되지 않습니다. 아래의 기능은 0.10.0버전부터 제거될 예정입니다.

::

from kiwipiepy import Kiwi

class IOHandler:
    def __init__(self, input, output):
        self.input = open(input, encoding='utf-8')
        self.output = open(output, 'w', encoding='utf-8')

    def read(self, sent_id):
        if sent_id == 0:
            self.input.seek(0)
            self.iter = iter(self.input)
        try:
            return next(self.iter)
        except StopIteration:
            return None

    def write(self, sent_id, res):
        print('Analyzed %dth row' % sent_id)
        self.output.write(' '.join(map(lambda x:x[0]+'/'+x[1], res[0][0])) + '\n')

    def __del__(self):
        self.input.close()
        self.output.close()

kiwi = Kiwi()
kiwi.load_user_dictionary('userDict.txt')
kiwi.prepare()
handle = IOHandler('test.txt', 'result.txt')
kiwi.analyze(handle.read, handle.write)

async_analyze 예제

다음 예제 코드에서는 async_analyze를 사용해 멀티스레딩 분석을 진행합니다. async_analyze 메소드 역시 0.10.0버전부터 제거될 예정입니다. 위의 analyze 메소드를 사용하길 권장합니다.

::

from kiwipiepy import Kiwi
kiwi = Kiwi()
kiwi.prepare()
ret = []
# input.txt 파일의 라인별로 분석 작업을 할당합니다.
for line in open('input.txt', encoding='utf-8'):
    ret.append(kiwi.async_analyze(line))

for r in ret:
    print(r()) # r을 호출하여 분석 결과를 얻습니다.

사용자 정의 사전 포맷

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

#주석은 #으로 시작합니다.

단어1 [탭문자] 품사태그 [탭문자] 단어점수

단어2 [탭문자] 품사태그 [탭문자] 단어점수

단어3 [탭문자] 품사태그 [탭문자] 단어점수

단어점수는 생략 가능하며, 생략 시 기본값인 0으로 처리됩니다.

데모

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인용 부호 및 괄호(' " ( ) [ ] < > { } ― ‘ ’ “ ” ≪ ≫ 등)
SE줄임표(…)
SO붙임표(- ~)
SW기타 특수 문자
SL알파벳(A-Z a-z)
SH한자
SN숫자(0-9)
분석 불능UN분석 불능*
웹(W)W_URLURL 주소*
W_EMAIL이메일 주소*
W_HASHTAG해시태그(#abcd)*
W_MENTION멘션(@abcd)*

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

역사

  • 0.9.2 (2021-01-20)

    • 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.rst
"""
from _kiwipiepy import *
from kiwipiepy._version import __version__
from enum import IntEnum

class Option(IntEnum):
    """
    Kiwi 인스턴스 생성 시 사용 가능한 옵션 열거형. 
    bitwise or 연산으로 여러 개 선택하여 사용가능합니다.
    """

    LOAD_DEFAULT_DICTIONARY = 1
    """
    인스턴스 생성시 자동으로 기본 사전을 불러옵니다. 기본 사전은 위키백과와 나무위키에서 추출된 고유 명사 표제어들로 구성되어 있습니다.
    """
    INTEGRATE_ALLOMORPH = 2
    """
    음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다.
    """
    DEFAULT = 3
    """
    Kiwi 생성시의 기본 옵션으로 LOAD_DEFAULT_DICTIONARY | INTEGRATE_ALLOMORPH 와 같습니다.
    """

class Match(IntEnum):
    """
    .. versionadded:: 0.8.0

    분석 시 특수한 문자열 패턴 중 어떤 것들을 추출할 지 선택할 수 있습니다.
    bitwise OR 연산으로 여러 개 선택하여 사용가능합니다.
    """
    URL = 1
    """
    인터넷 주소 형태의 텍스트를 W_URL이라는 태그로 추출합니다.
    """
    EMAIL = 2
    """
    이메일 주소 형태의 텍스트를 W_EMAIL이라는 태그로 추출합니다.
    """
    HASHTAG = 4
    """
    해시태그(#해시태그) 형태의 텍스트를 W_HASHTAG라는 태그로 추출합니다.
    """
    MENTION = 8
    """
    멘션(@멘션) 형태의 텍스트를 W_MENTION이라는 태그로 추출합니다.
    
    .. versionadded:: 0.8.2
    """
    ALL = 15
    """
    URL, EMAIL, HASHTAG, MENTION를 모두 사용합니다.
    """

del IntEnum

Classes

class Kiwi (*args, **kwargs)

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

Parameters

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

Instance variables

var version

get version

Methods

def addUserWord(...)

Deprecated since version: 0.7.6

PEP8 규약을 따라 Kiwi.add_user_word()를 사용하는 것을 권장합니다.

(0.10.0 버전에서 제거될 예정)

def add_user_word(self, word, tag='NNP', score=0)

현재 모델에 사용자 정의 단어를 추가합니다.

Parameters

word : str
추가할 단어
tag : str
추가할 단어의 품사 태그
score : float
추가할 단어의 가중치 점수. 해당 형태에 부합하는 형태소 조합이 여러 개가 있는 경우, 이 점수가 높을 단어가 더 우선권을 가집니다.
def analyze(self, text, top_n=1, match_options=Match.ALL)

형태소 분석을 실시합니다. 이 분석은 단일 스레드에서 진행됩니다.

Parameters

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

Added in version: 0.8.0

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

Returns

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

Deprecated since version: 0.9.0

이 함수는 또 다른 호출 방법을 가지고 있습니다. text를 인자로 직접 넘겨주는 대신 분석할 문자열을 생성할 함수와 분석 결과를 받을 함수를 지정해줄 수 있습니다. 그러나 이 방법은 사용이 복잡하고 Pythonic하지 않기 때문에 0.10.0 버전에서 제거될 예정입니다.

analyze(self, reader, receiver, top_n=1, match_options=kiwipiepy.Match.ALL)

Parameters

reader : Callable[int, str]
분석할 문자열을 읽어들이는 호출 가능한 객체입니다.
receiver : Callable[[int, Any], None]
분석된 결과물을 받아들이는 호출 가능한 객체입니다. 첫번째 인자는 분석 결과의 인덱스 번호이며, 두번째 인자는 분석 결과입니다. 분석 결과는 위의 반환값과 동일한 형태입니다.
top_n : int
분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options : int

Added in version: 0.8.0

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

Returns

none : None
이 경우는 분석 결과를 반환하지 않습니다. 분석 결과는 receiver에서 지정한 호출 가능한 객체에게 전달됩니다.
def async_analyze(self, text, top_n=1, match_options=Match.ALL)

Added in version: 0.7.6

형태소 분석을 비동기로 실행합니다. 이 메소드를 호출하면 Kiwi는 내부적으로 할당된 스레드에 작업을 할당하고, Python에는 결과물을 받을 수 있는 객체를 돌려줍니다. 따라서 Python 코드에서 멀티스레딩을 지원하지 않아도 이 메소드를 여러번 호출함으로써 멀티스레드 분석이 가능합니다.

Deprecated since version: 0.9.0

이 방법은 사용이 복잡하고 Pythonic하지 않기 때문에 0.10.0 버전에서 제거될 예정입니다.

Parameters

text : str
분석할 문자열입니다.
top_n : int
분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options : int

Added in version: 0.8.0

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

Returns

future : Callable[[], Any]
결과값을 생성하는 호출가능한 객체입니다. 이 결과값을 호출하면 내부 작업 스레드에서 분석이 완료되었다면 즉시 그 결과를 반환하고, 아직 분석이 진행중이라면 완료될때까지 대기합니다. 이 객체는 단 한 번만 호출할 수 있습니다. 이 객체의 호출 반환값은 Kiwi.analyze()의 반환값과 동일한 형태입니다.
def extractAddWords(...)

Deprecated since version: 0.7.6

PEP8 규약을 따라 Kiwi.extract_add_words()를 사용하는 것을 권장합니다.

(0.10.0 버전에서 제거될 예정)

def extractFilterWords(...)

Deprecated since version: 0.7.6

PEP8 규약을 따라 Kiwi.extract_filter_words()를 사용하는 것을 권장합니다.

(0.10.0 버전에서 제거될 예정)

def extractWords(...)

Deprecated since version: 0.7.6

PEP8 규약을 따라 Kiwi.extract_words()를 사용하는 것을 권장합니다.

(0.10.0 버전에서 제거될 예정)

def extract_add_words(self, reader, min_cnt=10, max_word_len=10, min_score=0.25, pos_score=-3)

말뭉치로부터 새로운 단어를 추출하고 새로운 명사에 적합한 결과들만 추려냅니다. 그리고 그 결과를 현재 모델에 자동으로 추가합니다. 이 메소드는 Kiwi.prepare()를 호출하기 전에만 사용 가능합니다.

Parameters

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

Returns

result : List[Tuple[str, float, int, float]]
추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
def extract_filter_words(self, reader, min_cnt=10, max_word_len=10, min_score=0.25, pos_score=-3)

말뭉치로부터 새로운 단어를 추출하고 새로운 명사에 적합한 결과들만 추려냅니다.

Parameters

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

Returns

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

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

Parameters

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

Returns

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

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

Parameters

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

Returns

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

Deprecated since version: 0.7.6

PEP8 규약을 따라 Kiwi.load_user_dictionary()를 사용하는 것을 권장합니다.

(0.10.0 버전에서 제거될 예정)

def load_user_dictionary(self, dict_path)

사용자 정의 사전을 읽어옵니다. 사용자 정의 사전 파일은 UTF-8로 인코딩된 텍스트 파일이어야 합니다.

Parameters

dict_path : str
사용자 정의 사전 파일의 경로
def perform(self, reader, receiver, top_n=1, match_options=Match.ALL, min_cnt=10, max_word_len=10, min_score=0.25, pos_score=-3)

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

Parameters

reader : Callable[int, str]
분석할 문자열을 읽어들이는 호출 가능한 객체입니다.
receiver : Callable[[int, Any], None]
분석된 결과물을 받아들이는 호출 가능한 객체입니다. 첫번째 인자는 분석 결과의 인덱스 번호이며, 두번째 인자는 분석 결과입니다. 분석 결과는 Kiwi.analyze()의 반환값과 동일한 형태입니다.
top_n : int
분석 결과 후보를 상위 몇 개까지 생성할 지 설정합니다.
match_options : int

Added in version: 0.8.0

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

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

현재 모델을 최적화하여 형태소 분석을 수행할 수 있도록 준비합니다. 이 메소드를 호출한 이후로는 Kiwi.add_user_word(), Kiwi.load_user_dictionary(), Kiwi.extract_add_words() 등을 사용하여 사용자 사전에 단어를 추가할 수 없습니다.

def setCutOffThreshold(...)

Deprecated since version: 0.7.6

PEP8 규약을 따라 Kiwi.set_cutoff_threshold()를 사용하는 것을 권장합니다.

(0.10.0 버전에서 제거될 예정)

def set_cutoff_threshold(self, threshold)

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

Added in version: 0.9.0

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

Parameters

threshold : float
0 보다 큰 실수
def set_option(self, option, value)

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

Parameters

option : Option
변경할 옵션의 열거값. 현재는 Option.INTEGRATE_ALLOMORPH만 지원합니다.
value : int
0으로 설정할 경우 해당 옵션을 해제, 0이 아닌 값으로 설정할 경우 해당 옵션을 설정합니다.
class Match (value, names=None, *, module=None, qualname=None, type=None, start=1)

Added in version: 0.8.0

분석 시 특수한 문자열 패턴 중 어떤 것들을 추출할 지 선택할 수 있습니다. bitwise OR 연산으로 여러 개 선택하여 사용가능합니다.

Expand source code
class Match(IntEnum):
    """
    .. versionadded:: 0.8.0

    분석 시 특수한 문자열 패턴 중 어떤 것들을 추출할 지 선택할 수 있습니다.
    bitwise OR 연산으로 여러 개 선택하여 사용가능합니다.
    """
    URL = 1
    """
    인터넷 주소 형태의 텍스트를 W_URL이라는 태그로 추출합니다.
    """
    EMAIL = 2
    """
    이메일 주소 형태의 텍스트를 W_EMAIL이라는 태그로 추출합니다.
    """
    HASHTAG = 4
    """
    해시태그(#해시태그) 형태의 텍스트를 W_HASHTAG라는 태그로 추출합니다.
    """
    MENTION = 8
    """
    멘션(@멘션) 형태의 텍스트를 W_MENTION이라는 태그로 추출합니다.
    
    .. versionadded:: 0.8.2
    """
    ALL = 15
    """
    URL, EMAIL, HASHTAG, MENTION를 모두 사용합니다.
    """

Ancestors

  • enum.IntEnum
  • builtins.int
  • enum.Enum

Class variables

var ALL

URL, EMAIL, HASHTAG, MENTION를 모두 사용합니다.

var EMAIL

이메일 주소 형태의 텍스트를 W_EMAIL이라는 태그로 추출합니다.

var HASHTAG

해시태그(#해시태그) 형태의 텍스트를 W_HASHTAG라는 태그로 추출합니다.

var MENTION

멘션(@멘션) 형태의 텍스트를 W_MENTION이라는 태그로 추출합니다.

Added in version: 0.8.2

var URL

인터넷 주소 형태의 텍스트를 W_URL이라는 태그로 추출합니다.

class Option (value, names=None, *, module=None, qualname=None, type=None, start=1)

Kiwi 인스턴스 생성 시 사용 가능한 옵션 열거형. bitwise or 연산으로 여러 개 선택하여 사용가능합니다.

Expand source code
class Option(IntEnum):
    """
    Kiwi 인스턴스 생성 시 사용 가능한 옵션 열거형. 
    bitwise or 연산으로 여러 개 선택하여 사용가능합니다.
    """

    LOAD_DEFAULT_DICTIONARY = 1
    """
    인스턴스 생성시 자동으로 기본 사전을 불러옵니다. 기본 사전은 위키백과와 나무위키에서 추출된 고유 명사 표제어들로 구성되어 있습니다.
    """
    INTEGRATE_ALLOMORPH = 2
    """
    음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다.
    """
    DEFAULT = 3
    """
    Kiwi 생성시의 기본 옵션으로 LOAD_DEFAULT_DICTIONARY | INTEGRATE_ALLOMORPH 와 같습니다.
    """

Ancestors

  • enum.IntEnum
  • builtins.int
  • enum.Enum

Class variables

var DEFAULT

Kiwi 생성시의 기본 옵션으로 LOAD_DEFAULT_DICTIONARY | INTEGRATE_ALLOMORPH 와 같습니다.

var INTEGRATE_ALLOMORPH

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

var LOAD_DEFAULT_DICTIONARY

인스턴스 생성시 자동으로 기본 사전을 불러옵니다. 기본 사전은 위키백과와 나무위키에서 추출된 고유 명사 표제어들로 구성되어 있습니다.