티스토리 뷰

반응형

텍스트 전처리 개론(Text preprocessing)

자연어 처리에 있어서 텍스트 전처리는 매우 중요하다. 왜냐하면 사용하는 목적에 따라 전처리를 다르게 해야하기 때문이다. 전처리를 위한 여러 기법에 대해 알아보자.

우선은 우리는 여러가지 방식으로 말뭉치(corpus)를 모았다고 가정해보다. 이러한 말뭉치 데이터가 전처리 되지 않았다면, 사용하고자 하는 목적에 맞게 토큰화(tokenization), 정제(cleaning), 정규화(normalization)을 거쳐 정규화가 진행이 된다.

토큰화(Tokenization)

토큰화란 말뭉치(corpus)에서 토큰(token)이라 불리는 단위로 나누는 작업이다. 토큰의 단위는 보통 의미를 가지는 단위로 선정된다. 토큰의 단위를 단어(word)로 잡으면 Word Tokenization이라하고, 문장(sentence)으로 잡으면 Sentence Tokenization이라고 한다. 우리가 토큰화 시 중점적으로 생각해야할 부분은 다음의 두 가지 이다.

  • 어떤 기준으로 나눌 것인가?
  • 어떤 구두점(punctuation)을 제외 할 것인가?

사실 간단히 생각하면, 띄어쓰기 기준으로 토큰을 나누고 모든 구두점을 생략하면 쉽게 토큰화가 된다고 생각 할 수 있다.

1. 한국어 토큰화(Word Tokenization)

영어와 다르게 한국어에서는 조사가 존재한다. 예를 들어 "나는", "나에게", "나를"과 같은 이런 단어가 다른 단어로 인식되면 자연어처러기 힘들다. 따라서 한국어 토큰화에서는 형태소(morpheme)란 개념을 반드시 이해해야 한다. 아래의 두 가지 형태소를 이해하자.

  • 자립 형태소 : 체언(명사, 대명사, 수사), 수식언(관형사, 부사), 감탄사 와 같이 그 자체로 단어가 되어 자립하리 수 있는 형태소를 나타낸다.
  • 의존 형태소 : 접사, 어미, 조사, 어간과 같이 다른 형태소와 결합하여 사용되는 형태소를 나타낸다.

즉, 한국어는 영어와 비슷한 토큰화를 얻기 위해서는 어절 토큰화가 아닌 형태소 토큰화를 해야한다.

한국어는 띄어쓰기를 하지 않아도 글을 이해 할 수 가 있다. 따라서 영어와 다르게 다른 토큰화가 필요하다는 것을 알 수있다. 이러한 특성들은 나라마다 다르고 언어마다 다르기 때문에 반드시 자연어처리를 하려는 언어에 대한 특정을 이해하는 것이 필요하다.

그렇다면 어떻게 하면 이러한 어려움을 해결 할 수 있을까? 기본적으로 우리는 품사 태깅(part-of-speech tagging)을 사용하여, 단어를 형태소 토큰화를 하고 추가로 각 단어가 어떤 품사로 쓰였는지도 태깅하여 문제를 해결한다. 그러면 어떻게 하는지 실습으로 알아보자.

2. KoNLPy

우리는 KoNLPy(코엔엘파이)라는 파이선 패키지를 사용하여 한국어 자연어 처리를 한다. KoNLPy를 통해 사용할 수 있는 형태소 분석기는 Okt(Open Korea Text), Mecab(메캅), Komoran(코모란), Hannanum(한나눔), 꼬꼬마(Kkma)가 있다.

성능을 비교해 보면, Mecab(=은전한닢)이 다른 분석기 대비 속도가 빠르다. 그래서 주로 Mecab을 사용한다. 어떤 형태소 분석기를 사용할지는 자신이 가진 데이터로 분석을 해보고 속도나 품질을 비교해 보는 것을 추천한다. 사용법에 대해 알아보자.

 

KoNLPy의 형태소 분석기는 공통적으로 다음과 같은 메소드를 제공한다.

  • morphs : 형태소 추출
  • pos: 품사 태깅(Part-of-speech tagging)
  • nouns : 명사 추출

각각의 분석기를 사용한 예시는 아래와 같다. 결과 값을 참고해 보길 바란다. 코드는 Colab기준으로 작성하였다.

# konlpy 설치
pip install --upgrade pip
pip install konlpy

 

Okt(Open Korea Text)

# Okt(Open Korea Text)
from konlpy.tag import Okt  
okt=Okt()  
text = "싸피에서 열공한 우린, 대한민국을 이끌 IT인재"
print(okt.morphs(text))
print(okt.pos(text))  
print(okt.nouns(text))  

> ['싸', '피에서', '열공', '한', '우린', ',', '대한민국', '을', '이끌', 'IT', '인재']
> [('싸', 'VerbPrefix'), ('피에서', 'Verb'), ('열공', 'Noun'), ('한', 'Josa'), ('우린', 'Noun'), (',', 'Punctuation'), ('대한민국', 'Noun'), ('을', 'Josa'), ('이끌', 'Verb'), ('IT', 'Alpha'), ('인재', 'Noun')]
> ['열공', '우린', '대한민국', '인재']

 

Komoran(코모란)

# Komoran(코모란)
from konlpy.tag import Komoran
komoran=Komoran()  
text = "싸피에서 열공한 우린, 대한민국을 이끌 SW인재"
print(komoran.morphs(text))
print(komoran.pos(text))  
print(komoran.nouns(text))  

> ['싸', '아', '피', '에서', '열', '공', '하', 'ㄴ', '우리', 'ㄴ', ',', '대한민국', '을', '이끌', 'ㄹ', 'SW', '인재']
> [('싸', 'VV'), ('아', 'EC'), ('피', 'NNG'), ('에서', 'JKB'), ('열', 'NNG'), ('공', 'NNG'), ('하', 'XSV'), ('ㄴ', 'ETM'), ('우리', 'NP'), ('ㄴ', 'JX'), (',', 'SP'), ('대한민국', 'NNP'), ('을', 'JKO'), ('이끌', 'VV'), ('ㄹ', 'ETM'), ('SW', 'SL'), ('인재', 'NNG')]
> ['피', '열', '공', '대한민국', '인재']

 

Hannanum(한나눔)

# Hannanum(한나눔)
from konlpy.tag import Hannanum
tokenizer=Hannanum()  
text = "싸피에서 열공한 우린, 대한민국을 이끌 SW인재"
print(tokenizer.morphs(text))
print(tokenizer.pos(text))  
print(tokenizer.nouns(text))  

> ['싸피', '에서', '열공한', '우', '이', '리ㄴ', ',', '대한민국', '을', '이끌', 'ㄹ', 'SW', '인재']
> [('싸피', 'N'), ('에서', 'J'), ('열공한', 'N'), ('우', 'N'), ('이', 'J'), ('리ㄴ', 'E'), (',', 'S'), ('대한민국', 'N'), ('을', 'J'), ('이끌', 'P'), ('ㄹ', 'E'), ('SW', 'F'), ('인재', 'N')]
> ['싸피', '열공한', '우', '대한민국', '인재']

 

꼬꼬마(Kkma)

from konlpy.tag import Kkma
tokenizer=Kkma()  
text = "싸피에서 열공한 우린, 대한민국을 이끌 SW인재"
print(tokenizer.morphs(text))
print(tokenizer.pos(text))  
print(tokenizer.nouns(text))  

> ['싸', '아', '피', '에서', '열', '공한', '우리', 'ㄴ', ',', '대한민국', '을', '이끌', 'ㄹ', 'SW', '인재']
> [('싸', 'VV'), ('아', 'ECS'), ('피', 'NNG'), ('에서', 'JKM'), ('열', 'NNG'), ('공한', 'NNG'), ('우리', 'VV'), ('ㄴ', 'ETD'), (',', 'SP'), ('대한민국', 'NNG'), ('을', 'JKO'), ('이끌', 'VV'), ('ㄹ', 'ETD'), ('SW', 'OL'), ('인재', 'NNG')]
> ['피', '열', '열공한', '공한', '대한', '대한민국', '민국', '인재']

 

Mecab(은전한닢)

Mecab(은전한닢)은 import Mecab로 사용이 불가능하다. 따라서 따로 설치가 필요하다. (window 설치도 지원을 안하여 까다롭다.)

! git clone https://github.com/SOMJANG/Mecab-ko-for-Google-Colab.git
! bash Mecab-ko-for-Google-Colab/install_mecab-ko_on_colab190912.sh

설치가 완성된 후에 pip install eunjeon을 받으면 사용이 가능하다.

from eunjeon import Mecab

tokenizer= Mecab()
text = "싸피에서 열공한 우린, 대한민국을 이끌 SW인재"
print(tokenizer.morphs(text))
print(tokenizer.pos(text))  
print(tokenizer.nouns(text))  

> ['싸', '피', '에서', '열공', '한', '우린', ',', '대한민국', '을', '이끌', 'SW', '인재']
> [('싸', 'VV+EC'), ('피', 'NNG'), ('에서', 'JKB'), ('열공', 'NNG'), ('한', 'XSA+ETM'), ('우린', 'NP+JX'), (',', 'SC'), ('대한민국', 'NNP'), ('을', 'JKO'), ('이끌', 'VV+ETM'), ('SW', 'SL'), ('인재', 'NNG')]
> ['피', '열공', '우린', '대한민국', '인재']

 

여기까지가 전처리 단계이다. 여기서 성능을 높이고 싶으면, 정제(cleaning), 정규화(normalization)를 추가하면 된다.
정제란, 불필요한 text를 지우는 것이다. 예를들면 ㄱ~ㅎ나 ㅏ~ㅣ 같이 오탈자 같은 것들을 지운다고 생각하면 된다.
정규화란크기가 무한히 성장하지 않도록 범위를 줄여주는 것이라고 쉽게 생각할 수 있다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함