Package kiwipiepy
Kiwipiepy란?
Kiwipiepy는 한국어 형태소 분석기인 Kiwi(Korean Intelligent Word Identifier)의 Python 모듈입니다. C++로 작성되었고 다른 패키지에 의존성이 없으므로 C++ 컴파일이 가능한 환경이라면 어디에서나 Kiwipiepy를 사용 가능합니다.
시작하기
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
위 명령어는 대화형 인터페이스를 시작합니다. 인터페이스에 원하는 문장을 입력하면 형태소 분석 결과를 확인할 수 있습니다.
::
>> 안녕?
[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)]
사용자 단어 추가
사용자 정의 단어를 추가하여 형태소 분석을 수행하는 예제입니다. 사용자 정의 단어를 등록하면 이는 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)
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.10.0 버전 변경사항
0.10.0 버전에서는 일부 불편한 메소드들이 좀 더 편한 형태로 개량되었습니다.
변경된 메소드들은 analyze
, perform
, extract_words
, extract_filter_words
, extract_add_words
입니다.
그리고 async_analyze
함수는 analyze
함수의 멀티스레딩 버전으로 통합되어 제거되었습니다.
또한 prepare
함수를 별도로 호출할 필요가 없도록 변경되었습니다.
0.9.3 버전까지의 analyze, perform 사용법 ::
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)
# perform 함수의 경우
kiwi.perform(handle.read, handle.write)
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.9.3 버전까지의 extract_words의 사용법 ::
class ReaderExam:
def __init__(self, filePath):
self.file = open(filePath)
def read(self, id):
if id == 0: self.file.seek(0)
return self.file.readline()
reader = ReaderExam('test.txt')
kiwi.extract_words(reader.read, 10, 10, 0.25)
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로 인코딩된 텍스트 파일이어야 하며, 다음과 같은 구조를 띄어야 합니다.
#주석은 #으로 시작합니다.
단어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_URL | URL 주소* |
W_EMAIL | 이메일 주소* | |
W_HASHTAG | 해시태그(#abcd)* | |
W_MENTION | 멘션(@abcd)* |
* 세종 품사 태그와 다른 독자적인 태그입니다.
역사
-
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% 작아졌습니다.
- API를 Python에 걸맞게 개편하였습니다. 일부 불편한 메소드들은 사용법이 변경되거나 삭제되었습니다. 이에 대해서는
-
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
파라미터로 이 기능의 사용 유무를 설정할 수 있습니다. - 치(하지), 컨대(하건대), 토록(하도록), 케(하게) 축약형이 포함된 동사 활용형을 제대로 분석하지 못하는 문제를 해결했습니다.
- 사용자 사전에 알파벳이나 숫자, 특수 기호가 포함된 단어가 있을 때, 형태소 분석시 알파벳, 숫자, 특수 기호가 포함된 문장이 제대로 분석되지 않는 문제를 수정했습니다.
- 사용자 사전에 형태는 같으나 품사가 다른 단어를 등록할 수 없는 제한을 해제하였습니다.
- URL, 이메일, 해시태그를 검출하는 기능이 추가되었습니다.
-
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 연산으로 여러 개 선택하여 사용가능합니다.
.. deprecated:: 0.10.0
추후 버전에서 제거될 예정입니다.
"""
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
을 확인하십시오.Deprecated since version: 0.10.0
차기 버전에서 제거될 예정입니다.options
대신integrate_allormoph
및load_default_dict
를 사용해주세요. integrate_allormoph
:bool
- True일 경우 음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다.
load_default_dict
:bool
- True일 경우 인스턴스 생성시 자동으로 기본 사전을 불러옵니다. 기본 사전은 위키백과와 나무위키에서 추출된 고유 명사 표제어들로 구성되어 있습니다.
Instance variables
var cutoff_threshold
-
Added in version: 0.10.0
Beam 탐색 시 미리 제거할 후보의 점수 차를 설정합니다. 이 값이 클 수록 더 많은 후보를 탐색하게 되므로 분석 속도가 느려지지만 정확도가 올라갑니다. 반대로 이 값을 낮추면 더 적은 후보를 탐색하여 속도가 빨라지지만 정확도는 낮아집니다. 초기값은 5입니다.
var integrate_allomorph
-
Added in version: 0.10.0
True일 경우 음운론적 이형태를 통합하여 출력합니다. /아/와 /어/나 /았/과 /었/ 같이 앞 모음의 양성/음성에 따라 형태가 바뀌는 어미들을 하나로 통합하여 출력합니다.
var num_workers
-
Added in version: 0.10.0
병렬처리시 사용할 스레드의 개수입니다. (읽기 전용)
var version
-
Kiwi의 버전을 반환합니다.
Deprecated since version: 0.10.0
차기 버전에서 제거될 예정입니다. 대신
kiwipiepy.__version__
을 사용하십시오.
Methods
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)
-
형태소 분석을 실시합니다.
Changed in version: 0.10.0
이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 https://bab2min.github.io/kiwipiepy/v0.10.0/kr/#0100 를 확인해주세요.
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[Token], float]]
- text를 str으로 준 경우.
분석 결과는 최대
top_n
개 길이의 리스트로 반환됩니다. 리스트의 각 항목은(분석 결과, 분석 점수)
로 구성된 튜플입니다.분석 결과
는Token
의 리스트로 구성됩니다. results
:Iterable[List[Tuple[List[Token], float]]]
- text를 Iterable[str]으로 준 경우. 반환값은 iterator로 주어집니다. iterator가 차례로 반환하는 분석결과 값은 입력으로 준 text의 순서와 동일합니다.
def extract_add_words(self, texts, min_cnt=10, max_word_len=10, min_score=0.25, pos_score=-3, lm_filter=True)
-
말뭉치로부터 새로운 단어를 추출하고 새로운 명사에 적합한 결과들만 추려냅니다. 그리고 그 결과를 현재 모델에 자동으로 추가합니다.
Changed in version: 0.10.0
이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 https://bab2min.github.io/kiwipiepy/v0.10.0/kr/#0100 를 확인해주세요.
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]]
- 추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
def extract_filter_words(self, texts, min_cnt=10, max_word_len=10, min_score=0.25, pos_threshold=-3, lm_filter=True)
-
Deprecated since version: 0.10.0
이 메소드의 기능은
Kiwi.extract_words()
로 통합되었습니다. 현재 이 메소드를 호출하는 것은Kiwi.extract_words()
를 호출하는 것과 동일하게 처리됩니다. def extract_words(self, texts, min_cnt=10, max_word_len=10, min_score=0.25, pos_threshold=-3, lm_filter=True)
-
말뭉치로부터 새로운 단어를 추출합니다. 이 기능은 https://github.com/lovit/soynlp 의 Word Extraction 기법을 바탕으로 하되, 문자열 기반의 확률 모델을 추가하여 명사일 것으로 예측되는 단어만 추출합니다.
Changed in version: 0.10.0
이 메소드는 0.10.0 버전에서 사용법이 일부 변경되었습니다. 자세한 내용은 https://bab2min.github.io/kiwipiepy/v0.10.0/kr/#0100 를 확인해주세요.
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]]
- 추출된 단어후보의 목록을 반환합니다. 리스트의 각 항목은 (단어 형태, 최종 점수, 출현 빈도, 품사 점수)로 구성된 튜플입니다.
def get_option(self, option)
-
현재 모델의 설정값을 가져옵니다.
Deprecated since version: 0.10.0
차기 버전에서 제거될 예정입니다. 이 메소드 대신
Kiwi.integrate_allomorph
값을 직접 읽으십시오.Parameters
option
:Option
- 검사할 옵션의 열거값. 현재는
Option.INTEGRATE_ALLOMORPH
만 지원합니다.
Returns
value
:int
- 해당 옵션이 설정되어 있는 경우 1, 아닌 경우 0을 반환합니다.
def load_user_dictionary(self, dict_path)
-
사용자 정의 사전을 읽어옵니다. 사용자 정의 사전 파일은 UTF-8로 인코딩된 텍스트 파일이어야 합니다. 사용자 정의 사전으로 추가된 단어의 개수를 반환합니다.
Parameters
dict_path
:str
- 사용자 정의 사전 파일의 경로
def morpheme(...)
def perform(self, texts, 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()
로 형태소 분석을 실시합니다. 이 메소드 호출 후 모델의 사본은 파괴되므로, 말뭉치에서 추출된 단어들은 다시 모델에서 제거되고, 메소드 실행 전과 동일한 상태로 돌아갑니다.Changed in version: 0.10.0
입력을 단순히 문자열의 리스트로 주고, 분석 결과 역시 별도의
receiver
로 받지 않고 바로 메소드의 리턴값으로 받게 변경되었습니다. 자세한 내용은 https://bab2min.github.io/kiwipiepy/v0.10.0/kr/#0100 를 확인해주세요.Parameters
texts
:Iterable[str]
- 분석할 문자열의 리스트, 혹은 Iterable입니다.
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
- 단어 후보의 품사 점수입니다. 품사 점수가 이 값보다 낮은 경우 후보에서 제외됩니다.
Returns
results
:Iterable[List[Tuple[List[Token], float]]]
- 반환값은
Kiwi.analyze()
의 results와 동일합니다.
def prepare(self)
-
Deprecated since version: 0.10.0
0.10.0버전부터 내부적으로 prepare()가 필요한 순간에 스스로 처리를 하도록 변경되어서 이제 이 메소드를 직접 호출할 필요가 없습니다. 차기 버전에서 제거될 예정입니다.
def set_cutoff_threshold(self, threshold)
-
Beam 탐색 시 미리 제거할 후보의 점수 차를 설정합니다. 이 값이 클 수록 더 많은 후보를 탐색하게 되므로 분석 속도가 느려지지만 정확도가 올라갑니다. 반대로 이 값을 낮추면 더 적은 후보를 탐색하여 속도가 빨라지지만 정확도는 낮아집니다. 초기값은 5입니다.
Added in version: 0.9.0
초기값이 8에서 5로 변경되었습니다.
Deprecated since version: 0.10.0
차기 버전에서 제거될 예정입니다. 이 메소드 대신
Kiwi.cutoff_threshold
를 직접 수정하십시오.Parameters
threshold
:float
- 0 보다 큰 실수
def set_option(self, option, value)
-
현재 모델의 설정값을 변경합니다.
Deprecated since version: 0.10.0
차기 버전에서 제거될 예정입니다. 이 메소드 대신
Kiwi.integrate_allomorph
값을 직접 수정하십시오.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 연산으로 여러 개 선택하여 사용가능합니다.
Deprecated since version: 0.10.0
추후 버전에서 제거될 예정입니다.
Expand source code
class Option(IntEnum): """ Kiwi 인스턴스 생성 시 사용 가능한 옵션 열거형. bitwise or 연산으로 여러 개 선택하여 사용가능합니다. .. deprecated:: 0.10.0 추후 버전에서 제거될 예정입니다. """ 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
-
인스턴스 생성시 자동으로 기본 사전을 불러옵니다. 기본 사전은 위키백과와 나무위키에서 추출된 고유 명사 표제어들로 구성되어 있습니다.
class Token (*args, **kwargs)
-
Token은 분석 결과 얻어진 형태소 정보를 담는 데이터 클래스입니다. (
form
,tag
,start
,len
) 형태의 길이 4의tuple
로 변환 가능합니다.Instance variables
var end
-
형태소의 입력 텍스트 내 끝 위치 (문자 단위)
var form
-
형태소의 형태
var id
-
형태소의 내부 고유 ID
var len
-
형태소의 입력 텍스트 내 차지 길이 (문자 단위)
var start
-
형태소의 입력 텍스트 내 시작 위치 (문자 단위)
var tag
-
형태소의 품사 태그