Skip to main content

Sequence-To-Sequence 모델을 활용한 한국어 형태소 분석기

Project description

DeepPosTagger

Sequence-To-Sequence 모델을 활용한 한국어 형태소 분석기

1. 특징

  • 세종 말뭉치와 국립국어원의 모두의 말뭉치 말뭉치를 사용하여 학습
    위 말뭉치들를 가공하여 만들어진 약 1,550,000 문장 중에서 약 2%인 31,000을 검증셋으로 사용, 검증셋에 대한 문장 단위 정확도(문장의 태깅 결과가 정확히 일치할 확률)는 69.65% 입니다.
  • LSTM기반에 Sequence-To-Sequence 모델에, 인코더에 LSTM과 Self-Attention Layer를 결합하여 사용하여 성능을 향상.(이 모델은 저자의 아이디어이므로 이를 사용하고자 할 때는 반드시 Reference를 표기 바랍니다.)
  • 세종 품사 태그 사용
  • 단어 사전이 없습니다 - 모델 특성상 Corpus에 있던 언어 패턴으로 단어의 품사를 도출하여 사전이 필요 없어 간편합니다.

2. 설치

pip install deeppostagger

3. 사용법

import os
# GPU를 사용하지 않을 경우
# 본 모듈이 동시에 처리하는 문장의 수(decode_net_size)가 크지 않을 경우에는 GPU를 사용하는 것은 오히려 역효과가 있다.
# 또한, 경험상 Windows에서 사용할 때 GPU 상에서 RNN을 구동시킬때 불안정하여 사용을 하지 않는게 좋다.
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
from deeppostagger import tagger

# decode_net_size: 디코더의 사이즈(디코더의 네트워크수, Default: 32, 클수록 초기화와 메모리가 많이 필요, 반면 실행 속도는 빨라진다.)
# concurrent_sent_size: 동시 처리 문단수 (한 번에 처리할 문단수, Default: 8)
# lazy_start는 parser의 초기화 시점 지정(True: 처음 parse를 할 때 초기화, False: 태거를 생성할 때 초기화)
# 출력은 iterable 형태로 나오며, 문단 단위(개행문자 단위로 구분)로 반환이 됩니다.
_tagger = tagger.create_tagger(lazy_start=False, decode_net_size=32, concurrent_sent_size=8)
for res in _tagger.parse("Sequence-To-Sequence 모델을 활용한 한국어 형태소 분석기입니다.\n빠른 형태소 분석 보다는 정확한 분석에 유리하지만, 다수의 문장을 동시에 처리할 수 있게 하는 구조를 가지고 있어 사용하기에 따라서 성능을 최적화할 수 있다."):
    print(res)

실행 결과

[[('Sequence', 'SL'), ('-', 'SS'), ('To', 'SL'), ('-', 'SS'), ('Sequence', 'SL')], [('모델', 'NNG'), ('을', 'JKO')], [('활용', 'NNG'), ('하', 'XSV'), ('ㄴ', 'ETM')], [('한국어', 'NNP')], [('형태소', 'NNG')], [('분석기', 'NNG'), ('이', 'VCP'), ('ㅂ니다', 'EF'), ('.', 'SF')]]
[[('빠르', 'VA'), ('ㄴ', 'ETM')], [('형태소', 'NNG')], [('분석', 'NNG')], [('보다', 'JKB'), ('는', 'JX')], [('정확', 'NNG'), ('하', 'XSA'), ('ㄴ', 'ETM')], [('분석', 'NNG'), ('에', 'JKB')], [('유리', 'NNG'), ('하', 'XSA'), ('지만', 'EC'), (',', 'SP')], [('다수', 'NNG'), ('의', 'JKG')], [('문장', 'NNG'), ('을', 'JKO')], [('동시', 'NNG'), ('에', 'JKB')], [('처리', 'NNG'), ('하', 'XSV'), ('ㄹ', 'ETM')], [('수', 'NNB')], [('있', 'VV'), ('게', 'EC')], [('하', 'VX'), ('는', 'ETM')], [('구조', 'NNG'), ('를', 'JKO')], [('가지', 'VV'), ('고', 'EC')], [('있', 'VX'), ('어', 'EC')], [('사용', 'NNG'), ('하', 'XSV'), ('기', 'ETN'), ('에', 'JKB')], [('따르', 'VV'), ('아서', 'EC')], [('성능', 'NNG'), ('을', 'JKO')], [('최적', 'NNG'), ('화', 'XSN'), ('하', 'XSV'), ('ㄹ', 'ETM')], [('수', 'NNB')], [('있', 'VV'), ('다', 'EF'), ('.', 'SF')]]
  • 성능향상 팁: decode_net_size에서 지정한 단위로 처리하는데, 이는 입력한 Paragraph 단위로 동시에 처리합니다. 따라서, 많은 단일 문단 단위의 작업으로 변환이 가능할 경우에는 단일 문단 마다 넣는 것보다 동시에 여러 decode_net_size 단위로 나누어 개행문자로 묶어서 넣는 것이 훨씬 빠릅니다.

Ex)

import timeit
txts = [
    "decode_net_size: 디코더의 사이즈(동시 처리할 문장의 수, Default: 32)",
    "lazy_start는 parser의 초기화 시점 지정(True: 처음 parse를 할 때 초기화, False: 태거를 생성할 때 초기화)",
    "출력은 iterable 형태로 나오며, paragraph 단위로 반환이 됩니다"
]
st  = timeit.default_timer()
for txt in txts:
    for res in _tagger.parse(txt):
        print(res)
print("{}sec".format(timeit.default_timer() - st))

st  = timeit.default_timer()
for res in _tagger.parse("\n".join(txts)):
    print(res)
print("{}sec".format(timeit.default_timer() - st))

실행 결과

[[('decode', 'SL'), ('_', 'SW'), ('net', 'SL'), ('_', 'SS'), ('size', 'SL'), (':', 'SP')], [('디코더', 'NNG'), ('의', 'JKG')], [('사이즈', 'NNG'), ('(', 'SS'), ('동시', 'NNG')], [('처리', 'NNG'), ('하', 'XSV'), ('ㄹ', 'ETM')], [('문장', 'NNG'), ('의', 'JKG')], [('수', 'NNG'), (',', 'SP')], [('Default', 'SL'), (':', 'SP')], [('32', 'SN'), (')', 'SS')]]
[[('lazy', 'SL'), ('_', 'SW'), ('start', 'SL'), ('는', 'JX')], [('parser', 'SL'), ('의', 'JKG')], [('초기', 'NNG'), ('화', 'XSN')], [('시점', 'NNG')], [('지정', 'NNG'), ('(', 'SS'), ('True', 'SL'), (':', 'SP')], [('처음', 'NNG')], [('parse', 'SL'), ('를', 'JKO')], [('하', 'VV'), ('ㄹ', 'ETM')], [('때', 'NNG')], [('초기', 'NNG'), ('화', 'XSN'), (',', 'SP')], [('False', 'SL'), (':', 'SP')], [('태거', 'NNG'), ('를', 'JKO')], [('생성', 'NNG'), ('하', 'XSV'), ('ㄹ', 'ETM')], [('때', 'NNG')], [('초기', 'NNG'), ('화', 'XSN'), (')', 'SS')]]
[[('출력', 'NNG'), ('은', 'JX')], [('iterable', 'SL')], [('형태', 'NNG'), ('로', 'JKB')], [('나오', 'VV'), ('며', 'EC'), (',', 'SP')], [('paragraph', 'SL')], [('단위', 'NNG'), ('로', 'JKB')], [('반환', 'NNG'), ('이', 'JKC')], [('되', 'VV'), ('ㅂ니다', 'EC')]]
0.6064547000005405sec
[[('decode', 'SL'), ('_', 'SW'), ('net', 'SL'), ('_', 'SS'), ('size', 'SL'), (':', 'SP')], [('디코더', 'NNG'), ('의', 'JKG')], [('사이즈', 'NNG'), ('(', 'SS'), ('동시', 'NNG')], [('처리', 'NNG'), ('하', 'XSV'), ('ㄹ', 'ETM')], [('문장', 'NNG'), ('의', 'JKG')], [('수', 'NNG'), (',', 'SP')], [('Default', 'SL'), (':', 'SP')], [('32', 'SN'), (')', 'SS')]]
[[('lazy', 'SL'), ('_', 'SW'), ('start', 'SL'), ('는', 'JX')], [('parser', 'SL'), ('의', 'JKG')], [('초기', 'NNG'), ('화', 'XSN')], [('시점', 'NNG')], [('지정', 'NNG'), ('(', 'SS'), ('True', 'SL'), (':', 'SP')], [('처음', 'NNG')], [('parse', 'SL'), ('를', 'JKO')], [('하', 'VV'), ('ㄹ', 'ETM')], [('때', 'NNG')], [('초기', 'NNG'), ('화', 'XSN'), (',', 'SP')], [('False', 'SL'), (':', 'SP')], [('태거', 'NNG'), ('를', 'JKO')], [('생성', 'NNG'), ('하', 'XSV'), ('ㄹ', 'ETM')], [('때', 'NNG')], [('초기', 'NNG'), ('화', 'XSN'), (')', 'SS')]]
[[('출력', 'NNG'), ('은', 'JX')], [('iterable', 'SL')], [('형태', 'NNG'), ('로', 'JKB')], [('나오', 'VV'), ('며', 'EC'), (',', 'SP')], [('paragraph', 'SL')], [('단위', 'NNG'), ('로', 'JKB')], [('반환', 'NNG'), ('이', 'JKC')], [('되', 'VV'), ('ㅂ니다', 'EC')]]
0.28463689999989583sec

4. 맺음말

프로그램은 저자의 첫 번쨰 공개 프로젝트입니다. 공개 프로젝트에 대한 경험이 없어 운영이 미숙합니다. 여러 의견 부탁드립니다. 본 프로그램은 상업적인 사용은 허용하지 않습니다.

※ 학습 데이터 및 모듈은 제공하지 않습니다.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deeppostagger-0.16.tar.gz (20.8 MB view details)

Uploaded Source

File details

Details for the file deeppostagger-0.16.tar.gz.

File metadata

  • Download URL: deeppostagger-0.16.tar.gz
  • Upload date:
  • Size: 20.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.21.0 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.28.1 importlib-metadata/4.11.3 keyring/17.0.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.7.1

File hashes

Hashes for deeppostagger-0.16.tar.gz
Algorithm Hash digest
SHA256 a6ce3f9bf0ffe1fad734512025468663d120d6b8dd63bab2c3120f027bdac612
MD5 a5b41f5cf027c5cbf8f2065c5a10ce1f
BLAKE2b-256 c7a903d653c7634ff67ddbc635bc2e1143e0d53caf40e4ba5792d599a0db37cf

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page