텍스트 분석이란?
텍스트 정규화
◆ 텍스트 정규화:
텍스트를 피처화 하기 전에, 텍스트를 가공하는 준비 작업이 필요한데, 텍스트를 머신러닝 알고리즘이나 NLP 애플리케이션에 입력 데이터로 사용하기 위해 클렌징, 정제, 토큰화, 어근화 등의 다양한 텍스트 데이터의 사전 작업을 수행하는 것을 의미.
[텍스트 정규화 작업 분류]
- 클렌징(Cleansing): 텍스트에서 분석에 방해가 되는 불필요한 문자, 기호 등을 사전에 제거하는 작업. (예. HTML, XML 태그나 특정 기호 등을 사전에 제거)
- 토큰화(Tokenization): 토큰화ㅓ의 유형은 문서에서 문장을 분리하는 문장 토큰화 / 문장에서 단어를 토큰으로 분리하는 단어 토큰화로 나눌 수 있다.
- 필터링 / 불용어 처리 / 철자 수정: 불용어(스톱 워드, Stop word)는 분석에 큰 의미가 없는 단어를 지칭한다.
- Stemming: 문법적 또는 의미적으로 변화하는 단어의 원형을 찾는 것. 원형 단어로 변환 시 일반적인 방법을 적용하거나 더 단순화된 방법을 적용해 원래 단어에서 일부 철자가 훼손된 어근 단어를 추출하는 경향이 있다.
- Lemmatization: Stemming과 유사하나, 보다 정교하며 의미론적인 기반에서 단어의 원형을 찾는다. 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안해 정확한 철자로 된 어근 단어를 찾아준다. (Stemming 보다 변환에 더 오랜 시간을 필요로 한다)
텍스트 토큰화
◆ 문장 토큰화(sentence tokenization):
문장의 마침표, 개행문자(\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 church or pay your taxes.'
sentences = sent_tokenize(text=text_sample)
print(type(sentences), len(sentences))
print(sentences)
▶ sent_tokenize() 가 반환하는 것은 각각의 문장으로 구성된 list 객체이며, 반환된 list 객체가 3개의 문장으로 된 문자열을 가지고 있는 것을 알 수 있다.
◆ 단어 토큰화(Word tokenization):
단어 토큰화는 문장을 단어로 토큰화하는 것이며, 기본적으로 공백, 콤마, 마침표, 개행문자 등으로 단어를 분리하지만, 정규 표현식을 이용해 다양한 유형으로 토큰화를 수행할 수 있다.
NLTK에서 기본으로 제공하는 word_tokenize() 를 이용해 단어로 토큰화 할 수 있다.
from nltk import word_tokenize
sentence = "The Matrix is everywhere its all around us, here even in this room."
words = word_tokenize(sentence)
print(type(words), len(words))
print(words)
[단어 토큰화, 문장 토큰화를 조합해 모든 단어 토큰화]
sent_tokenize 와 word_tokenize 를 조합해 문서에 대해 모든 단어를 토큰화 해 본다.
문서를 먼저 문장으로 나누고, 개별 문장을 다시 단어로 토큰화하는 tokenize_text() 함수를 생성.
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)
▶ 3개 문장을 문장별로 먼저 토큰화했으므로 word_tokens 변수는 3개의 리스트 객체를 내포하는 리스트이며, 내포된 개별 리스트 객체는 각각 문장별로 토큰화된 단어를 요소로 가지고 있다.
[n-gram]
※ n-gram: 연속된 n개의 단어를 하나의 토큰화 단어로 분리해 내는 것.
문장을 단어별로 하나씩 토큰화 할 경우 문맥적인 의미는 무시될 수 밖에 없기 때문에 n-gram을 도입하여 n개 단어 크기 윈도를 만들어 문장의 처음부터 오른쪽으로 움직이면서 토큰화를 수행한다.
text = 'Agent Smith knocks the door'
words = text.split() # 공백을 기준으로 문자열을 분리하여 리스트로 만듦
for i in range(len(words) - 1): # 2-gram이므로 리스트의 마지막에서 요소 한 개 앞까지만 반복함
print(words[i], words[i + 1]) # 현재 문자열과 그다음 문자열 출력
스톱 워드 제거
◆ 스톱 워드(Stop word):
분석에 큰 의미가 없는 단어. 예. 영어의 is, the, a, will 등 문장을 구성하는 필수 문법 요소이나, 문맥적으로 큰 의미가 없는 단어.
해당 단어의 경우 문법적인 특성으로 인해 특히 빈번하게 텍스트에 나타나므로 이것들을 사전에 제거하지 않으면 빈번함으로 인해 중요한 단어로 인식될 수 있어 제거하는 것이 중요한 전처리 작업이다.
NLTK의 경우 가장 다양한 언어의 스톱 워드를 제공한다.
NLTK의 stopwords 목록을 내려 받아본다.
import nltk
nltk.download('stopwords')
다운로드가 완료된 후 NLTK의 English의 경우 몇 개의 stopwords 가 있는지, 그리고 그 중 20개만 확인
print('영어 stop words 개수:', len(nltk.corpus.stopwords.words('english')))
print(nltk.corpus.stopwords.words('english')[:20])
▶ 영어의 경우 스톱 워드의 개수가 179개이다.
[앞선 예제에 대해 stopwords 필터링]
앞선 예제에서 3개의 문장별로 단어를 토큰화해 생성된 word_tokens 리스트에 대해 stopwords 를 필터링으로 제거해 분석을 위한 의미 있는 단어만 추출해 본다.
import nltk
stopwords = nltk.corpus.stopwords.words('english')
all_tokens = []
# 예제에서 얻은 word_tokens list에 대해 스톱 워드 제거하는 반복문
for sentence in word_tokens:
filtered_words = []
# 개별 문장별로 토큰화된 문장 list에 대해 스톱 워드 제거하는 반복문
for word in sentence:
# 소문자로 모두 변환
word = word.lower()
# 토큰화된 개별 단어가 스톱 워드의 단어에 포함되지 않으면 word_tokens에 추가
if word not in stopwords:
filtered_words.append(word)
all_tokens.append(filtered_words)
print(all_tokens)
▶ is, this 와 같은 스톱 워드가 필터링을 통해 제거되었다.
Stemming과 Lemmatization
- Stemming: 원형 단어로 변환 시 일반적인 방법을 적용하거나 더 단순화된 방법을 적용해 원래 단어에서 일부 철자가 훼손된 어근 단어를 추출하는 경향이 있다.
- Lemmatization: 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안해 정확한 철자로 된 어근 단어를 찾아주며, Stemming에 비해 보다 정교하며 변환에 더 오랜 시간을 필요로 한다.
NLTK는 다양한 Stemmer를 제공하며, 대표적으로 Porter, Lancaster, Snowball Stemmer가 있다.
또한, Lemmatization을 위해서는 WordNetLemmatizer를 제공한다.
[Stemming과 Lemmatization 비교]
NLTK의 LancasterStemmer, WordNetLemmatizer를 이용해 Stemmer와 Lemmatization 수행
from nltk.stem import LancasterStemmer
stemmer = LancasterStemmer()
print(stemmer.stem('working'), stemmer.stem('works'), stemmer.stem('worked'))
print(stemmer.stem('amusing'), stemmer.stem('amuses'), stemmer.stem('amused'))
print(stemmer.stem('happier'), stemmer.stem('happiest'))
print(stemmer.stem('fancier'), stemmer.stem('fanciest'))
▶ 진행형, 3인칭 단수, 과거형에 따른 동사, 비교, 최상에 따른 형용사의 변화에 따른 Stemming은 더 단순하게 원형 단어를 찾아준다.
stem('단어') 메서드를 호출하면 원하는 '단어'의 Stemming이 가능하다.
from nltk.stem import WordNetLemmatizer
import nltk
nltk.download('wordnet')
lemma = WordNetLemmatizer()
print(lemma.lemmatize('amusing', 'v'), lemma.lemmatize('amuses', 'v'), lemma.lemmatize('amused', 'v'))
print(lemma.lemmatize('happier', 'a'), lemma.lemmatize('happiest', 'a'))
print(lemma.lemmatize('fancier', 'a'), lemma.lemmatize('fanciest', 'a'))
▶ 일반적으로 Lemmatization은 보다 정확한 원형 단어 추출을 위해 단어의 '품사'를 입력해줘야 하며, lemmatize()의 파라미터로 동사의 경우 'v', 형용사의 경우 'a' 입력.
Stemmer 보다 정확하게 원형 단어를 추출해준다.
다음 내용
[출처]
파이썬 머신러닝 완벽 가이드
'[파이썬 Projects] > <파이썬 머신러닝>' 카테고리의 다른 글
[머신러닝] 텍스트 분석: 분류 실습 (0) | 2024.10.30 |
---|---|
[머신러닝] 텍스트 분석: BOW(Bag of Words) (1) | 2024.10.30 |
[머신러닝] 텍스트 분석 (0) | 2024.10.28 |
[머신러닝] 군집화: 실습 - 고객 세그먼테이션 (1) | 2024.10.28 |
[머신러닝] 군집화: DBSCAN (0) | 2024.10.27 |