한국어 전처리 패키지(Text Preprocessing Tools for Korean Text)

ganta·2021년 3월 4일
4

자연어 전처리

목록 보기
8/8
post-thumbnail

이 글은 Wikidocks의 딥 러닝을 이용한 자연어 치리 입문을 공부한 내용을 정리 한 글입니다.

✔️ 이번 포스팅에서는 한국어 전처리 패키지를 별도로 공부해본 내용입니다.

PyKoSpacing


✔️ 한국어 띄어쓰기 패키지로 띄어쓰기가 되어있지 않은 문장을 띄어쓰기를 한 문장으로 변환해주는 패키지

패키지 설치

!pip install git+https://github.com/haven-jeon/PyKoSpacing.git

띄어쓰기를 한 문장으로 변환

from pykospacing import spacing

new_sent = sent.replace(" ", '') # 띄어쓰기가 없는 문장으로 만들기
print(new_sent)
이것은simple한예시입니다.
kospacing_sent = spacing(new_sent)
print(sent)
print(kospacing_sent)
이것은 simple한 예시입니다.
이것은 simple한 예시입니다.

Py-Hanspell


✔️ 네이버 한글 맞춤법 검사기를 바탕으로 만들어진 패키지로써 맞춤법을 고친 문장을 반환하도록 해 준다.

패키지 설치

!pip install git+https://github.com/ssut/py-hanspell.git

맞춤법에 맞는 문장을 반환

from hanspell import spell_checker

sent = "맞춤법이 틀린 문장이 돼었습니다."
spelled_sent = spell_checker.check(sent)

hanspell_sent = spelled_sent.checked
print(hanspell_sent)

띄어쓰기 또한 맞춤법을 보정하여 결과물을 반환해 준다.

sent = '이것은 simple한 예시입니다.'
new_sent = sent.replace(" ", '')

spelled_sent = spell_checker.check(new_sent)

hanspell_sent = spelled_sent.checked
print(hanspell_sent)
print(kospacing_sent)
이것은 simple 한 예시입니다.
이것은 simple한 예시입니다.

SOYNLP


✔️ 기존 형태소 분석기는 신조어나 형태소 분석기에 등록되지 않은 단어의 경우 제대로 구분하지 못하는 단점이 있기 때문에 soynlp는 이러한 단점을 해결하기 위해 이러한 단어의 앞, 뒤에 독립된 다른 단어들이 계속해서 등장하는 것을 파악하여 만약 그렇다면 한 단어로 파악하는 과정을 거쳐 작업을 진행한다.

✔️ soynlp는 기본적으로 학습에 기반한 토크나이저이고 학습을 진행 해 주워야 한다.

1️⃣ 한국어 문서의 다운로드

import urllib.request
from soynlp import DoublespaceLineCorpus
from soynlp.word import WordExtractor
urllib.request.urlretrieve("https://raw.githubusercontent.com/lovit/soynlp/master/tutorials/2016-10-20.txt", filename="2016-10-20.txt")

2️⃣ 훈련데이터를 다수의 문서로 분리 후 학습이 진행이 된다.(전체 코퍼스로부터 응집 확률과 브랜칭 엔트로피 단어 점수표를 만들게 된다.)

훈련 데이터를 다수의 문서로 분리

corpus = DoublespaceLineCorpus("2016-10-20.txt")
len(corpus) #30091
word_extractor = WordExtractor()
word_extractor.train(corpus)
word_score_table = word_extractor.extract() # 전체 코퍼스에 대한 단어 점수표 계산
training was done. used memory 1.517 Gb
all cohesion probabilities was computed. # words = 223348
all branching entropies was computed # words = 361598
all accessor variety was computed # words = 361598

SOYNLP 응집 확률

✔️응집 확률은 내부 문자열이 얼마나 응집하여 자주 등장하는지에 판단하는 척도이다.

✔️ 내부 문자열을 만드는 과정에서 왼쪽부터 순서대로 문자열을 추가하면서 각 문자열이 주어졌을 시 다음 문자가 나올 확률을 계산한다.
이 값을 높을수록 전체 코퍼스에서 문자열 시퀀스는 하나의 단어로 등장할 확률이 높다는 뜻이다.


➡️ cohension(n)=(i=1n1P(c1:i+1c1:i))cohension(n) = (\prod_{i=1}^{n-1}P(c_{1:i+1}|c_{1:i}))
예시)
만약, "디스플레이"라는 단어의 스코어를 구하는 과정은 다음과 같다.
cohension(2)=P(디스)cohension(2) = P(디스 | 디)
cohension(3)=P(디스)P(디스플디스)2cohension(3) = \sqrt[2]{P(디스 | 디) \cdot P(디스플 | 디스)}
cohension(4)=P(디스)P(디스플디스)P(디스플레디스플)3cohension(4) = \sqrt[3]{P(디스 | 디) \cdot P(디스플 | 디스) \cdot P(디스플레 | 디스플)}
cohension(5)=P(디스)P(디스플디스)P(디스플레디스플)P(디스플레이디스플레)4cohension(5) = \sqrt[4]{P(디스 | 디) \cdot P(디스플 | 디스) \cdot P(디스플레 | 디스플) \cdot P(디스플레이 | 디스플레)}

이를 코드로써 확인해보면 다음과 같다.

word_score_table["디스플"].cohesion_forward # 0.21245395148200436
word_score_table["디스플레"].cohesion_forward # 0.3556306966566586
word_score_table["디스플레이"].cohesion_forward # 0.45929564695810293

# 같은 단어가 아닐시는 오히려 값이 떨어지는 현상을 보게 된다.
word_score_table["디스플레이를"].cohesion_forward # 0.30995365234146033

위에 따라, 디스플레이가 적합한 단어라고 알 수 있고 이를 이용하여 분리를 수행 할 수 있음을 알 수 있다.

SOYNLP의 브랜칭 엔트로피

✔️ Branching Entropy는 확률 분포의 엔트로피값을 사용함으로써 주어진 문자열에서 얼마나 다음 문자가 등장할 수 있는지 판단할 수 있는 척도의 값이다.(다음에 나올 문자의 선택지가 많을수록 값이 커지게 된다.)

예시)

word_score_table["디스"].right_branching_entropy # 1.6371694761537934

# 값이 0으로 된 이유는 다음에 올 문자가 명확해졌기 때문이다.
word_score_table["디스플"].right_branching_entropy # -0.0
word_score_table["디스플레"].right_branching_entrop # -0.0

# 값이 다시 올라간 이유는 문자 시퀀스 다음에는 조사나 다른 단어와 같은 다양한 경우가 있을 수 있기 떄문이다.
word_score_table["디스플레이"].right_branching_entropy # 3.1400392861792916

SOYNLP의 L tokenizer

✔️ 한국어에서 띄어쓰기 단위로 나눈 어절 토큰은 L토큰 + R토큰의 형식을 가지는 경우가 많은데 분리 기준을 점수가 가장 높은 L토큰을 찾는 원리를 가지고 있다.

최대 점수 tokenizer

✔️ 띄어쓰기가 되지 않는 문장에서 점수가 높은 글자 시퀀스를 순차적으로 찾아내는 토크나이저이다.

SOYNLP를 이용한 반복되는 문자 정제

✔️ SNS나 채팅의 경우 'ㅋㅋㅋ', 'ㅎㅎ' 같은 이모티콘의 경우 불필요하게 연속되는 경우가 많은데 반복되는 것을 하나로 정규화시켜줄 수 있다.

from soynlp.normalizer import 

print(emoticon_normalize('앜ㅋㅋㅋㅋㅋㅋㅎㅎㅎㅎㅎㅎㅎ', num_repeats=2))
print(emoticon_normalize('앜ㅋㅋㅋㅋㅋㅋㅋㅋㅎㅎㅎ', num_repeats=2))
print(emoticon_normalize('앜ㅋㅋㅋㅋㅋ큐ㅠㅠ', num_repeats=2))
print(emoticon_normalize('앜ㅋㅋㅋㅋㅋㅋㅎㅎㅎㅎ', num_repeats=2))
아ㅋㅋㅎㅎ
아ㅋㅋㅎㅎㅎ
아ㅋㅋㅠㅠㅠ
아ㅋㅋㅎㅎ
print(repeat_normalize('와아아아아아아', num_repeats=2))
print(repeat_normalize('우아아아아아아아아아아아아', num_repeats=2))
print(repeat_normalize('와아아아', num_repeats=2))
와아아
우아아
와아아아

Customized KoNLPy


✔️ 영어는 띄어쓰기만해도 단어가 잘 분리되나 한국어는 경우가 다르다. 형태소 분석기를 사용할 때 이러한 상황을 극복하기 위해 하나의 해결책으로써 형태소 분석기에 사용자 사전을 추가해 주는 경우가 있다.

예시)

pip install customized_konlpy
from ckonlpy.tag import Twitter
twitter = Twitter()
twitter.morphs('동현이는 오늘도 학교에 갑니다.')
['동', '현이', '는', '오늘', '도', '학교', '에', '갑니다', '.']
twitter.add_dictionary('동현이', 'Noun')

twitter.morphs('동현이는 오늘도 학교에 갑니다.')
['동현이', '는', '오늘', '도', '학교', '에', '갑니다', '.']

위의 예시에서 '동현이'라는 단어를 사전에 추가해 하나의 토큰으로 인식 될 수 있다.

profile
한걸음씩 꾸준히

0개의 댓글