본문 바로가기
국비 교육/머신러닝, 딥러닝

[텍스트 마이닝] 텍스트 분석 -1 (전처리 작업)

by 육츠 2024. 8. 1.
Contents 접기

토큰화

패키지 다운

!pip install nltk

# nltk site: https://www.nltk.org

 

NLTK :: Natural Language Toolkit

Natural Language Toolkit NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries

www.nltk.org

from nltk import sent_tokenize
import nltk

nltk.download('punkt') # 불용어..

 

문장 토큰화

문장 마침표(.)나 개행문자(\n)를 통해 구분

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_sample)
print(sentences)  # 결과 타입 : 리스트, 길이 = 3
['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.']

 

단어 토큰화

문장을 단어로 토큰화 하는 것 (공백 기준)

from nltk import word_tokenize
sentence = 'The Matrix is everywhere its all around us, here even in this room.'
words = word_tokenize(sentence)
print(words)


# ',' 와 같은 불용어 이기 때문에 나중에 제외!
['The', 'Matrix', 'is', 'everywhere', 'its', 'all', 'around', 'us', ',', 'here', 'even', 'in', 'this', 'room', '.']

 

동시에 진행하려면?

전체 리스트 안에 문장마다 리스트 안에 있으며, 단어로 토큰화된 형태로 담겨져 있다.

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(word_tokens)
print(len(word_tokens))
[['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', '.']]
3

 

 

불용어 Stopwords

: 분석에 큰 의미가 없는 단어를 지칭한다.

Stopwords 제거

패키지

import nltk
nltk.download('stopwords') # 불용어 목록을 다운로드

# 불용어 지원 언어 목록 확인할 수 있다.

nltk.corpus.stopwords.fileids()

 

print('영어 stop word 개수:', len(nltk.corpus.stopwords.words('english')))
print(nltk.corpus.stopwords.words('english')[:20])
영어 stop word 개수: 179
['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your', 'yours', 'yourself', 'yourselves', 'he', 'him', 'his']

 

소문자 변경 lower()

불용어 제거를 하기 위해서는 문장을 소문자로 만들어 주어야 한다.

stopwords = nltk.corpus.stopwords.words('english')
all_tokens = []
print('[원본단어]')
print(word_tokens)

print('[불용어제거 단어]')

for sentence in word_tokens:
    # print(sentence)
    filltered_words = []
    for word in sentence:
        word = word.lower()
        if word not in stopwords:
            filltered_words.append(word)
    all_tokens.append(filltered_words)

print(all_tokens)
[원본단어]
[['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', '.']]
[불용어제거 단어]
[['matrix', 'everywhere', 'around', 'us', ',', 'even', 'room', '.'], ['see', 'window', 'television', '.'], ['feel', 'go', 'work', ',', 'go', 'church', 'pay', 'taxes', '.']]

 

어간 추출(Stemming)과 표제어 추출(Lemmatization)

문법적 또는 의미적으로 변화하는 단어의 원형을 찾는다
ex) worked, works, working 의 동사 원형인 work를 찾아준다.

 

어간 추출(Stemming)

동사의 원형을 못 찾아주는 경우도 많다. (밑에 단어가 그 예시)

from nltk.stem import LancasterStemmer

stemmer = LancasterStemmer()
print(stemmer.stem('working'),stemmer.stem('worked'), stemmer.stem('works')) 
print(stemmer.stem('happier'),stemmer.stem('happiest'))
work work work
happy happiest

 

표제어 추출(Lemmatization)

품사를 지정해준다. 품사를 지정해 줌으로써 더 정확한 단어의 의미를 찾을 수 있게 되는 것이다.

from nltk.stem import WordNetLemmatizer
import nltk
nltk.download('wordnet') # 사전 다운
lemma = WordNetLemmatizer()

# 매개변수로 품사를 지정한다.
# n 명사 v 동사, a 형용사, r 부사
print(lemma.lemmatize('happier','a'), lemma.lemmatize('happiest','a'))
happy happy

 

Bag of Words - BoW

(1) CountVectorizer 이용

DTM Document-Term Matrix, 문서 단어 행렬

from sklearn.feature_extraction.text import CountVectorizer 

corpus = ['you know I want your love. because I Love you']
cv = CountVectorizer() 

# 'I' 는 BoW를 만드는 과정에서 사라진 이유는 
# CountVertorize 가 기본적으로 길이가 2 이상인 문자에 대해서만 토큰으로 인식하기 때문에 포함이 안됐다
# 구두점이나 특수기호((,{,..})})는 알아서 제거.. # 불용어 지정 가능..

print('BoW Vector: ', cv.fit_transform(corpus)) # 밀집벡터
print('BoW Vector: ', cv.fit_transform(corpus).toarray()) # 희소행렬
print(cv.vocabulary_)
BoW Vector:    (0, 4)	2
  (0, 1)	1
  (0, 3)	1
  (0, 5)	1
  (0, 2)	2
  (0, 0)	1
BoW Vector:  [[1 1 2 1 2 1]]
{'you': 4, 'know': 1, 'want': 3, 'your': 5, 'love': 2, 'because': 0}

.toarray() 를 통해 밀집 벡터에서 희소 행렬로 변경할 수 있다.
.vocabulary_ 는 단어와 함께 배당된 인덱스 번호를 딕셔너리 형태로 반환해준다.

 

불용어를 제거한 BoW 만들기

사용자가 만든 불용어 제거 ( nltk 의 stopwords )

(1) 사용자 정의 불용어 사용

text = ["Family is not an important thing. It's everything."]
cv= CountVectorizer(stop_words= ['the','a','an','is'])

print('BoW Vecctor:', cv.fit_transform(text).toarray())
print(cv.vocabulary_)
BoW Vecctor: [[1 1 1 1 1 1]]
{'family': 1, 'not': 4, 'important': 2, 'thing': 5, 'it': 3, 'everything': 0}

 

(2) NLTK에서 지원하는 불용어 사용

from nltk.corpus import stopwords

text = ["Family is not an important thing. It's everything."]
stop_words = stopwords.words('english')
cv= CountVectorizer(stop_words= stop_words)

print('BoW Vector:', cv.fit_transform(text).toarray())
print(cv.vocabulary_)
BoW Vector: [[1 1 1 1]]
{'family': 1, 'important': 2, 'thing': 3, 'everything': 0}

 

(2) TfidfVectorizer 이용

TF - IDF : TfidfVectorizer 사용 (영문서빈도) 자주 등장하는 단어에 가중치를 준다.

from sklearn.feature_extraction.text import TfidfVectorizer

corpus = ['you know I want your love', #문서 1
         'I Like you',                 # 문서 2
         'What should I do']           # 문서 3

tfidf= TfidfVectorizer()
print(tfidf.fit_transform(corpus).toarray())
print(tfidf.vocabulary_)
[[0.         0.46735098 0.         0.46735098 0.         0.46735098
  0.         0.35543247 0.46735098]
 [0.         0.         0.79596054 0.         0.         0.
  0.         0.60534851 0.        ]
 [0.57735027 0.         0.         0.         0.57735027 0.
  0.57735027 0.         0.        ]]
{'you': 7, 'know': 1, 'want': 5, 'your': 8, 'love': 3, 'like': 2, 'what': 6, 'should': 4, 'do': 0}