이번 포스팅은 자연어 토크나이징 도구에 대한 내용이다.
먼저 토크나이징이란 예측해야 할 입력 정보(문장 또는 발화)를 하나의 특정 기본 단위(기본적으로 단어를 단위로 함)로 자르는 것을 말한다.
파이썬을 이용하면 이러한 작업을 라이브러리를 통해 간편하게 처리가 가능하며, 언어의 특징에 따라 처리 방법이 달라지므로 영어 토크나이징과 한글 토크나이징을 구분해서 배우자.
[ 영어 토크나이징 라이브러리 ]
영어의 경우 NLTK(Natural Language Toolkit)와 Spacy가 토크나이징에 많이 쓰이는 대표적인 라이브러리다.
이 두 라이브러리는 영어 텍스트에 대해 전처리 및 분석을 하기 위한 도구로 유명하다.
▶ NLTK
NLTK는 파이썬에서 영어 텍스트 전처리 작업을 하는 데 많이 쓰이는 라이브러리다.
50여 개가 넘는 말뭉치 리소스를 활용하여 영어 텍스트를 분석 할 수 있도록 제공하며 직관적으로 함수를 쉽게 사용할 수 있게 구성되어 있어 빠르게 텍스트 전처리를 할 수 있다.
1. 라이브러리 설치
설치방법은 이전 포스팅과 마찬가지로 아나콘다를 통해 설치한다.
명령어는 다음과 같다.
conda isntall nltk
정상적으로 설치가 완료되었다면 이 라이브러리를 활용하기 위해 말뭉치(corpus)를 내려받아 연동하자.
이 작업을 생략하면 토크나이징을 할 수 없기 때문에 꼭 해주자!
import nltk
nltk.download()
위의 함수를 실행하면 다음의 창이 나타난다.
여기서 설치할 항목이 나오는데 여기서 다운로드할 자료는 'all-corpora'와 'book'이다.
'all-corpora'는 텍스트 언어 분석을 위한 말뭉치 데이터셋으로 보면 되며 토크나이징 또는 구문 분석을 위해서는 이 자료가 필요하기 때문에 다운로드를 해주어야 한다.
'book'은 NLTK언어 분석을 하기 위한 예시 데이터셋이다. 만약 컴퓨터 저장 공간이 부족하다면 이 데이터셋은 다운로드하지 않아도 된다.
말뭉치 설치를 완료하었다면 영어 텍스트를 토크나이징하기 위한 모든 준비를 끝냈다.
이제 토크나이징에 대해 살펴보도록 하자.
토크나이징이란 앞서 말했듯이 텍스트에 대해 특정 기준 단위로 문장을 나누는 것을 의미하는데, 예를 들어 문장을 단어 기준으로 나누거나 전체 글을 문장 단위로 나누는 것을 말한다.
파이썬에서는 간단하게 문자열에 대해 split함수를 사용하여 나눌 수 있지만 라이브러리를 활용하면 훨씬 더 간편하고 효과적으로 토크나이징이 가능하다.
먼저 단어 단위로 토크나이징을 해보자.
라이브러리의 tokenize모듈에서 word_tokenize를 불러와 사용하면 된다.
from nltk.tokenize import word_tokenize
sentence = "Natural language processing (NLP) is a subfield of computer science, \
information engineering, and artificial intelligence concerned \
with the interactions between computers and human (natural) languages,\
in particular how to program computers to process and analyze large amounts of natural language data."
print(word_tokenize(sentence))
결과 :
['Natural', 'language', 'processing', '(', 'NLP', ')', 'is', 'a', 'subfield', 'of', 'computer', 'science', ',', 'information', 'engineering', ',', 'and', 'artificial', 'intelligence', 'concerned', 'with', 'the', 'interactions', 'between', 'computers', 'and',
'human', '(', 'natural', ')', 'languages', ',', 'in', 'particular', 'how', 'to', 'program', 'computers', 'to', 'process', 'and', 'analyze', 'large', 'amounts', 'of', 'natural', 'language', 'data', '.']
정의된 영어 텍스트에 대하여 word_tokenize 함수를 적용하면 위와 같이 구분된 리스트를 받을 수 있다.
결과를 보면 모두 단어로 구분되어 있으며, 특수 문자의 경우 따로 구분된 것을 볼 수 있다.
이렇게 별다른 설정 없이 간단하게 토크나이징된 결과를 받을 수 있다.
다음으로 문장 단위로 토크나이징을 해보자.
from nltk.tokenize import sent_tokenize
sentence = "Natural language processing (NLP) is a subfield of computer science, \
information engineering, and artificial intelligence concerned with the \
interactions between computers and human (natural) languages, \
in particular how to program computers to process and analyze \
large amounts of natural language data. Challenges in natural language processing \
frequently involve speech recognition, natural language understanding, \
and natural language generation."
print(sent_tokenize(sentence))
결과 :
['Natural language processing (NLP) is a subfield of computer science, information engineering, and artificial intelligence concerned with the interactions between computers and human (natural) languages, in particular how to
program computers to process and analyze large amounts of natural language data.', 'Challenges in natural language processing frequently involve speech recognition, natural language understanding, and natural language generation.']
사용법은 단어 토크나이징과 다르지 않다. 함수만 sent_tokenize로 바꾸었을 뿐이다.
결과를 보면 위의 텍스트가 2개의 문장으로 나눠진 리스트로 나오는 것을 알 수 있다.
이처럼 라이브러리를 사용하면 원하는 기준으로 간단하게 토크나이징이 가능하다.
이뿐만 아니라 NLTK 라이브러리의 경우 토크나이징 외에도 자연어 처리에 유용한 기능들을 제공한다.
대표적으로 텍스트 데이터를 전처리할 때 경우에 따라 불용어('a', 'the'와 같은 관사나 'is'와 같이 자주 출현하지만 큰 의미를 가지지 않는 단어를 뜻함)를 제거해야 할 때가 있는데, NLTK 라이브러리에는 불용어 사전이 내장되어 있어 불용어 정의할 필요 없이 바로 사용이 가능하다.
▶ Spacy
Spacy역시 아나콘다를 통해 설치하며, 명령어는 다음과 같다.
conda install spacy
NLTK와 마찬가지로 영어에 대한 텍스트를 전처리하려면 언어 데이터 자료를 별도로 내려받아야 한다.
다음 명령어를 입력해서 'en'자료를 설치하면 된다.
python -m spacy download en_core_web_sm
위의 명령어를 통해 언어 데이터까지 설치하고 나면 텍스트 데이터를 토크나이징할 준비가 모두 끝났다.
NLTK와 마찬가지로 단어 기준으로 토크나이징 하는 방법부터 문장 기준 토크나이징까지 살펴보자.
NLTK에서는 단어 단위의 토크나이징 함수와 문장 단위의 토크나이징 함수가 서로 구분되어 있었다.
하지만 Spacy에서는 두 경우 모두 동일한 모듈을 통해 토크나이징한다.
우선 객체를 생성하기 위해 라이브러리를 불러온 후, 불러온 라이브러리를 이용해 토그나이징을 한다.
import spacy
nlp = spacy.load('en_core_web_sm')
sentence = "Natural language processing (NLP) is a subfield of computer science,information engineering,\
and artificial intelligence concerned with the interactions\
between computers and human (natural) languages,\
in particular how to program computers to process and analyze large amounts of natural language data."
doc = nlp(sentence)
먼저 spacy.load('en_core_web_sm')을 통해 객체 생성을 하여 nlp에 할당한다.
후에 sentence에 할당해서 nlp(sentence)를 실행해 nlp 객체에 대해 호출한다.
그러면 텍스트에 대해 구문 분석 객체를 반환하는데 이를 doc 변수에 할당한다.
그럼 doc 객체를 가지고 입력한 텍스트에 대해 단어 토크나이징과 문장 토크나이징을 수행할 수 있다.
word_tokenized_sentence = [token.text for token in doc]
sentence_tokenized_list = [sent.text for sent in doc.sents]
print(word_tokenized_sentence)
print(sentence_tokenized_list)
결과 : ['Natural', 'language', 'processing', '(', 'NLP', ')', 'is', 'a', 'subfield', 'of', 'computer', 'science', ',', 'information', 'engineering', ',', 'and', 'artificial', 'intelligence', 'concerned', 'with', 'the', 'interactions', ' ', 'between', 'computers', 'and', 'human', '(', 'natural', ')', 'languages', ',', ' ', 'in', 'particular', 'how', 'to', 'program', 'computers', 'to', 'process', 'and', 'analyze', 'large', 'amounts', 'of', 'natural', 'language', 'data', '.']
['Natural language processing (NLP) is a subfield of computer science, information engineering, and artificial intelligence concerned with the interactions between computers and human (natural) languages, in particular how to program computers to process and analyze large amounts of natural language data.']
Spacy는 [token.text for token in doc]와 같이 리스트 컴프리헨션을 활용하면 간단하게 토크나이징 결과 확인이 가능하다.
(리스트 컴프리헨션이란 파이썬에서 제공하는 기능으로 한 리스트의 모든 원소 각각에 어떤 함수를 적용한 다음, 그 반환값을 원소로 가지는 다른 리스트를 만드는 기능을 말한다.)
이처럼 단어 기준, 문장 기준 토크나이징은 매우 유사하지만 조금 다른 구조로 생성할 수 있다.
NLTK는 함수를 통해 토크나이징을 처리하며 Spacy는 객체를 생성하는 방식으로 구현된다.
이처럼 객체를 생성하는 이유는 객체를 통해 단순이 토크나이징 뿐만 아니라 다른 자연어 전처리 기능을 제공할 수 있기 때문이다.
두 라이브러리 모두 간단하게 사용이 가능하지만 사용법에 따라 특색이 있고 토크나이징 이외에는 제공되는 기능이 서로 다르기 때문에 모두 알아두는 것이 좋다.
이번에는 한글 토크나이징에 대하여 알아보자.
[ 한글 토크나이징 라이브러리 ]
영어 자연어 처리에는 NLTK와 Spacy가 있다면, 한글 자연어 처리에는 KoNLPy가 있다.
KoNLPy는 형태소 분석으로 형태소 단위의 토크나이징을 가능하게 할 뿐만 아니라 구문 분석을 가능하게 해서 언어 분석을 하는 데 유용한 도구이다.
▶ KoNLPy
KoNLPy는 한글 자연어 처리를 쉽고 간결하게 처리할 수 있도록 만들어진 오픈 소스 라이브러리다.
또한 국내에 이미 만들어져 사용되고 있는 여러 형태소 분석기를 사용하도록 허용한다.
일반적인 어절 단위에 대한 토크나이징은 NLTK로 충분히 해결이 가능하므로 형태소 단위에 대한 토크나이징에 대하여 공부해보자.
우선 라이브러리를 설치해보자.
이 라이브러리는 운영체제에 따라 설치 방법이 다르므로 사용하고자 하는 운영체제에 해당하는 설치법에 따라 설치하자.
1. 윈도우
KoNLPy는 자바로 쓰인 형태소 분석기를 사용하기 때문에 1.7 이상 버전의 자바가 설치되어 있어야 한다.
자바가 설치되어 있다면 환경변수를 설정해준다. (자세한 설명은 생략!)
다음으로 0.5.7 버전 이상의 JPype1을 설치한다.
JPype1는 KoNLPy에서 필요하며 파이썬에서 자바 클래스를 사용할 수 있도록 만들어주는 라이브러리다.
JPype1 설치 홈페이지(http://www.lfd.uci.edu/~gohlke/pythonlibs/#jpype)에 들어가서 자신의 파이썬 버전과 윈도우 아키텍처에 해당하는 버전을 설치하고, 커맨드 라인에서 다음과 같은 명령을 입력하자.
pip install JPype1버전이름
# ex : pip install JPype1-0.63-cp36-cp36m-win_amd64.whl
이때 설치할 파일이 해당 경로에 있어야 제대로 설치가 가능하다.
이제 커맨드 라인에서 KoNLPy 설치 명령어를 실행한다.
pip install konlpy
설치가 완료되면 해당 라이브러리를 불러온다.
import konlpy
별다른 오류가 없다면 제대로 설치가 완료된 것이다.
2. macOS
macOS에서는 자바를 설치하는 작업 없이 명령행에서 파이썬 버전에 맞게 다음의 명령어만 입력하면 된다.
pip install konlpy # 파이썬 2.x 버전
pip3 install konlpy # 파이썬 3.x 버전
설치가 완료되면 해당 라이브러리를 불러온다.
import konlpy
별다른 오류가 없다면 제대로 설치가 완료된 것이다.
이제 KoNLPy 사용법에 대해서 알아보자.
▷ 형태소 단위 토크나이징
한글 텍스트의 경우 형태소 단위로 토크나이징이 필요할 때가 있는데, KoNLPy에서는 여러 형태소 분석기를 제공하며, 각 형태소 분석기 별로 분석한 결과는 다를 수 있다.
각 형태소 분석기는 클래스 형태로 되어 있으며, 이를 객체로 생성한 후 메서드를 호출해서 토크나이징을 한다.
· 형태소 분석 및 품사 태깅
먼저 형태소란, 의미를 가지는 가장 작은 단위로서 더 쪼개지면 의미를 상실하는 것들을 말한다.
따라서 형태소 분석이란 의미를 가지는 단위를 기준으로 문장을 살펴보는 것을 의미한다.
이러한 기능을 가지는 KoNLPy에 포함된 형태소 분석기의 목록은 다음과 같다.
- Hannanum
- Kkma
- Komoran
- Mecab
- Okt(Twitter였으나 0.5.0 버전 이후로 이름이 바뀜)
위 객체들은 모두 동일하게 형태소 분석 기능을 제공하지만 성능이 조금씩 다르므로 직접 비교하면서 사용하는 것을 권장한다. 또한 Mecab의 경우 윈도우에서 사용하기가 매우 까다로우니 참고하길 바란다.
실습에서는 Okt를 사용해보기로 하자.
먼저 Okt를 사용하기 위해 불러온 후, 객체를 생성한다.
from konlpy.tag import Okt
okt = Okt()
Okt객체는 다음과 같은 4개의 함수를 제공한다.
1. okt.morphs()
: 텍스트를 형태소 단위로 나눈다. 옵션으로는 norm과 stem이 있으며, norm은 문장을 정규화하는 역할을 하고, stem은 각 단어에서 어간을 추출하는 기능이다. 각각 True 혹은 False 값을 받는다. True로 설정하면 기능이 적용되며 옵션을 지정하지 않으면 둘 다 False로 설정된다.
2. okt.nouns()
: 텍스트에서 명사만 뽑아낸다.
3. okt.phrases()
: 텍스트에서 어절을 뽑아낸다.
4. okt.pos()
: 각 품사를 태깅하는 역할을 한다. 즉, 주어진 텍스트를 형태소 단위로 나누고, 나눠진 각 형태소를 해당하는 품사와 함께 리스트화 한다. 옵션으로는 morphs와 마찬가지로 norm, stem 옵션이 있으며 추가적으로 join 함수가 있다.
join함수는 True로 설정하면 나눠진 형태소와 품사를'형태소/품사'로 같이 붙여서 리스트화한다.
이제 위의 함수를 직접 적용해보자.
text = "한글 자연어 처리는 재밌닼ㅋㅋㅋ 이제부터 열심히 해야짛ㅎㅎㅎㅎ!!"
print(okt.morphs(text))
print(okt.morphs(text, norm=True)) # 문장 정규화 수행
print(okt.morphs(text, stem=True)) # 형태소 단위로 나눈 후 어간 추출
print(okt.morphs(text, norm=True, stem=True)) # 문장 정규화 수행 & 형태소 단위로 나눈 후 어간 추출
결과 :
['한글', '자연어', '처리', '는', '재밌닼', 'ㅋㅋㅋ', '이제', '부터', '열심히', '해야짛', 'ㅎㅎㅎㅎ', '!!']
['한글', '자연어', '처리', '는', '재밌다', 'ㅋㅋㅋ', '이제', '부터', '열심히', '해야지', 'ㅎㅎㅎ', '!!']
['한글', '자연어', '처리', '는', '재밌닼', 'ㅋㅋㅋ', '이제', '부터', '열심히', '해야짛', 'ㅎㅎㅎㅎ', '!!']
['한글', '자연어', '처리', '는', '재밌다', 'ㅋㅋㅋ', '이제', '부터', '열심히', '하다', 'ㅎㅎㅎ', '!!']
정규화 작업을 수행한 경우 '재밌닼ㅋㅋㅋ'의 부분이 '재밌다ㅋㅋㅋ'로 바뀌었으며 '해야짛ㅎㅎㅎㅎ'도 마찬가지로 '해야지ㅎㅎㅎㅎ'로 바뀐 것을 알 수 있다.
정규화 작업의 중요성을 세 번째와 네 번째의 차이에서 볼 수 있는데, 정규화를 거치지 않으면 어간 추출이 되지 않았지만 정규화를 거치면 어간 추출이 되는 것을 확인할 수 있었다.
다음은 명사와 어절을 추출해보자.
text = "한글 자연어 처리는 재밌닼ㅋㅋㅋ 이제부터 열심히 해야짛ㅎㅎㅎㅎ!!"
print(okt.nouns(text))
print(okt.phrases(text))
text = ''.join(okt.morphs(text, norm=True)) # 한글 자연어 처리는 재밌다ㅋㅋㅋ 이제부터 열심히 해야지ㅎㅎㅎ!!
print(okt.nouns(text))
print(okt.phrases(text))
결과 :
['한글', '자연어', '처리', '재밌닼', '이제', '해야짛']
['한글', '한글 자연어', '한글 자연어 처리', '재밌닼', '이제', '해야짛', '자연어', '처리']
['한글', '자연어', '처리', '이제']
['한글자연어처리', '이제', '한글', '자연어', '처리']
nouns함수를 사용한 경우에는 명사만 추출됐고 phrases함수의 경우에는 어절 단위로 나뉘어서 추출되었다.
여기서 정규화를 거치지 않은 문장은 정확도가 떨어지지만 정규화를 거치면 잘 수행하는 것을 볼 수 있다.
다음은 품사 태깅 함수인 pos함수를 사용해보자.
text = "한글 자연어 처리는 재밌닼ㅋㅋㅋ 이제부터 열심히 해야짛ㅎㅎㅎㅎ!!"
print(okt.pos(text))
# 문장 정규화 수행 & 형태소 단위로 나눈 후 어간 추출
print(okt.pos(text, norm=True, stem=True))
# 문장 정규화 수행 & 형태소 단위로 나눈 후 어간 추출 & 형태소와 품사를 붙여 리스트화
print(okt.pos(text, norm=True, stem=True, join=True))
결과 :
[('한글', 'Noun'), ('자연어', 'Noun'), ('처리', 'Noun'), ('는', 'Josa'), ('재밌닼', 'Noun'), ('ㅋㅋㅋ', 'KoreanParticle'), ('이제', 'Noun'), ('부터', 'Josa'), ('열심히', 'Adverb'), ('해야짛', 'Noun'), ('ㅎㅎㅎㅎ', 'KoreanParticle'), ('!!', 'Punctuation')]
[('한글', 'Noun'), ('자연어', 'Noun'), ('처리', 'Noun'), ('는', 'Josa'), ('재밌다', 'Adjective'), ('ㅋㅋㅋ', 'KoreanParticle'), ('이제', 'Noun'), ('부터', 'Josa'), ('열심히', 'Adverb'), ('하다', 'Verb'), ('ㅎㅎㅎ', 'KoreanParticle'), ('!!', 'Punctuation')]
['한글/Noun', '자연어/Noun', '처리/Noun', '는/Josa', '재밌다/Adjective', 'ㅋㅋㅋ/KoreanParticle', '이제/Noun', '부터/Josa', '열심히/Adverb', '하다/Verb', 'ㅎㅎㅎ/KoreanParticle', '!!/Punctuation']
join옵션을 True로 설정한 경우 형태소와 품사가 함께 나오는 것을 볼 수 있다.
'정리 > 텐서플로와 머신러닝으로 시작하는 자연어처리' 카테고리의 다른 글
chap03. 자연어 처리 개요_단어 표현 (0) | 2021.07.06 |
---|---|
chap02. 자연어 처리 개발 준비_numpy, pandas, matplotlib, Re, Beautiful Soup (0) | 2021.07.05 |
chap02. 자연어 처리 개발 준비_사이킷런(Scikit-learn) (0) | 2021.07.01 |
chap02. 자연어 처리 개발 준비_TensorFlow (0) | 2021.06.30 |
chap01. 들어가며 (0) | 2021.06.29 |