텍스트 분석은 단어마다 쪼개는게 상당히 어렵고,
내 나름대로 진입장벽이 꽤 높다고 생각해서 쉽게 도전하지 못했던 분야였다.
이번에 데이콘 NLP대회에 경험삼아 참가해서 여러 코드도 참고해서 따라해보고 적용해봐야겠다는 생각에 기초부터 다지자!! 결심했다.
[파이썬 머신러닝 완벽가이드]에서 나오는 텍스트분석은 어떤 프로세스로 분석을 전개해가야 하는지 틀을 잡을 수 있게 도와주었다.
텍스트 분석 수행 프로세스
1) 텍스트 사전 준비작업 ( 텍스트 전처리 ) : 텍스트를 피처로 만들기 전, 미리 클렌징, 대/소문자 변경, 특수문자 삭제, 단어토큰화 작업, 스탑워드 제거, 어근추출 등의 텍스트 정규화를 진행
2) 피처 백터화/추출 : 사전 준비작업으로 가공된 텍스트에서 피처를 추출하고, 이에 백터값 할당 => BOW(Count기반, TF-IDF), Word2Vec
3) ML모델 수립 및 학습/예측/평가
텍스트 분석 패키지
- NLTK
- Gensim
- SpaCy
최근 가장 주목받고 있는 패키지는 SpaCy,,
보통은 모든 패키지를 함께 결합하여 애플리케이션을 작성하는 경우가 많다.
텍스트 정규화
( 클렌징, 토큰화, 스톱워드제거, Stemming과 Lemmatization)
NLP에서는 텍스트 정규화가 무엇보다 중요하다!
1) 클렌징
텍스트에서 분석에 오히려 방해가 되는 불필요한 문자, 기호 등을 사전에 제거하는 작업
ex) HTML, XML 태그,,
2) 텍스트 토큰화
토큰화의 유형은 문장토큰화와 워드토큰화로 나누어볼 수 있음
- 문장토큰화
문장의 마침표(.), 개행문자(\n)등 문장의 마지막을 뜻하는 기호에 따라 분리하는 것이 일반적
NLTK에서 일반적으로 많이 쓰이는 sent_tokenize를 이용해 토큰화를 수행해본다.
### nltk.download('punkt')은 마침표, 개행문자 등의 데이터셋을 다운로드
from nltk import sent_tokenize
import nltk
nltk.download('punkt')
text_sample = 'The Matrix is everywhere its all around us, here even in this room. \
You can see it out your window or on your television.\
You feel it when you go to work, or go to chruch or pay your taxes.'
sentences = sent_tokenize(text=text_sample)
print(type(sentences), len(sentences))
print(sentences)
- 단어토큰화
문장을 단어로 토큰화하는 것
기본적으로 공백, 콤마, 마침표, 개행문자 등으로 단어를 분리하지만, 정규 표현식을 이용해 다양한 유형으로 토큰화를 수행할 수 있다.
### 보통 단어의 순서가 중요하지 않은 경우 활용 ###
nltk의 word_tokenize()를 활용해 단어로 토큰화 진행
from nltk import word_tokenize
setence = 'The Matrix is everywhere its all around us, here even in this room.'
words = word_tokenize(sentence)
print(type(words), len(words))
print(words)
- 문장토큰화와 단어토큰화의 조합
문서를 문장으로 나눈뒤, 개별 문장을 다시 단어토큰화 진행
from nltk import word_tokenize, sent_tokenize
## 여러 개의 문장으로 된 입력 데이터를 문장별로 단어 토큰화하게 만드는 함수 생성
def tokenize_text(text):
# 문장별로 분리 토큰
sentences = sent_tokenize(text)
# 분리된 문장별로 단어 토큰
word_tokens = [word_tokenize(sentence) for sentence in sentences]
return word_tokens
#여러 문장에 대해 문장별 단어 토큰화 수행
word_tokens = tokenize_text(text_sample)
print(type(word_tokens), len(word_tokens))
print(word_tokens)
- n-gram
연속된 n개의 단어를 하나의 토큰화 단위로 분리해 내는 것
단어토큰화는 문장토큰화와 달리 문맥적인 의미를 무시하기 때문에 이를 조금이나마 보완해보고자 도입됨
ex) "Agent Smith knocks the door"
을 n-gram하게 되면 (Agent Smith) (Smith Knocks) (Knocks the) (the door) 과 같은 형식으로 분리되는 것을 의미함
3) 스톱워드 제거
* 스톱워드 : 분석에 큰 의미가 없는 단어 ex) a, the, i, my, you,,,
언어별로 스톱워드가 목록화되어 있는데 NLTK의 경우 가장 다양한 언어의 스톱워드를 제공함
문법적인 특성으로 인해 특히 빈번하게 테스트에 나타나면 오히려 중요한 단어로 인식할 수 있기 때문에 사전에 제거하는 것이 중요
import nltk
nltk.download('stopwords')
nltk의 스톱워드를 다운로드하고, 영어에 포함되어있는 스톱워드의 일부 살펴보기
print('영어 스톱워드 개수 : {0}'.format(len(nltk.corpus.stopwords.words('english'))))
print(nltk.corpus.stopwords.words('english')[:20])
앞서 작성한 예시에서 스톱워드에 포함된 단어를 제외하고 추출해보기
import nltk
stopwords = nltk.corpus.stopwords.words('english')
all_tokens = []
## 앞선 예제에서 3개의 문장별로 얻은 word_tokens에서 스톱워드를 제거하는 반복문
for sentence in word_tokens:
filtered_words = []
## 개별 문장별로 토큰화된 문장 list에 대해 스톱워드를 제거하는 반복문
for word in sentence :
word = word.lower()
if word not in stopwords:
filtered_words.append(word)
all_tokens.append(filtered_words)
print(all_tokens)
4) Stemming과 Lemmatization
단어가 문법적 요소에 의해서 다양한 형태로 변화한 경우, 원형으로 변환시켜주는 작업
ex) worked, working, works => work
일반적으로 Lemmatization이 Stemming보다 성능이 우수함
- Lemmatization
nltk는 Lemmatization을 위해서 WordNetLemmatizer을 제공
Stemming과 다르게 Lemmatization의 경우 정확도를 높이기 위해 '품사'를 함께 적어주어야 함
from nltk.stem import WordNetLemmatizer
import nltk
nltk.download('wordnet')
lemma = WordNetLemmatizer()
print(lemma.lemmatize('amusing','v'),lemma.lemmatize('amused','v'))
print(lemma.lemmatize('happier','a'),lemma.lemmatize('happiest','a'))
print(lemma.lemmatize('fancier','a'),lemma.lemmatize('fanciest','a'))
우측의 정확도가 더욱 높은 것을 볼 수 있음!!
'python > 파이썬 머신러닝 완벽가이드' 카테고리의 다른 글
[NLP] pipeline을 활용한 직관적인 코드짜기! (0) | 2022.05.03 |
---|---|
[NLP] 피처백터화 / 희소행렬 (0) | 2022.05.02 |
[python] SMOTE를 활용한 오버샘플링 (0) | 2022.03.26 |
[python] LGBMClassifier 단번에 성능 높이기 (0) | 2022.03.26 |
[python] 교차검증을 간단하게 cross_val_score() (0) | 2022.03.15 |