愛林

[Text Mining] 텍스트 마이닝 - 카운트 기반 문서 표현 본문

Data Science/Text Mining, 자연어처리

[Text Mining] 텍스트 마이닝 - 카운트 기반 문서 표현

愛林 2022. 8. 27. 00:10
반응형

거의 한 달만에 해보는 텍스트 마이닝 ..

 


카운트 기반의 문서 표현

 

컴퓨터는 바보다.

그래서 바로바로 글자를 읽지 못해서, 우리가 숫자로 이루어진 벡터로 바꾸어주어야 안다.

그래서 이전에는 텍스트 전처리를 배웠다.

이렇게 숫자로 이루어진 벡터로 바꾸어주었음에도 불구하고,

우리의 컴퓨터는 맥락을 이해하지 못한다. 전체 글의 맥락을 파악하지 못한다.

 

전설적, 어휘적, 다변적 사랑이라는 책이 있다.

개념 예술가인 캐런 라이머의 1996년 책인데, 연애 소설 한 편을 골라서 전체 텍스트를

알파벳 순으로 재배열한 책이다.

알파벳 순으로 단어들이 나열된 345쪽짜리 긴 목록이다.

 

X 로 시작하는 단어가 없었기에 25장으로 이루어져있는 책이다.

왜 이런 책을 썼는 지는 모른다.

항상 예술가는 어려운 것 같다.

그러나, 의미없는 이 책이 보여주는 통찰력이 하나 있는데, 이는 사용된 단어들의 빈도로

책의 성향을 짐작할 수 있다는 것이다.

연애소설의 원작 내용은 사라졌으나, 이 책이 남아있기에 우리는 그 원작 책의 성향을

짐작할 수 있는 것이다.

 

여기서 , 우리 컴퓨터도 문서에 있는 글자의 개수를 통해서 문서의 맥락을

파악할 수 있게 하면 된다 ! 라는 통찰을 얻게 된 것이다.

그래서 시작하게 된 카운트 기반의 문서 표현.

우리가 할 카운트 기반의 문서 표현은 텍스트의 특성을 단어의 사용 여부나 빈도로 표현하게 된다.

어떤 단어가 몇 번 쓰였는 지만 파악해도 문서에 대한 대체적인 내용을 파악할 수 있게 되는 것이다.

 

 

 

텍스트 마이닝을 위해서는 비정형 텍스트로부터 우리가 관심이 있는 특성을 정형 데이터로 추출해야 한다.

 

이것이 텍스트마이닝의 기본이다.

이를 위해 대상이 갖고 있는 정보 중 우리가 관심이 있는 것을 표현하는 특성 을 알아야 한다.

이 텍스트를 이해할 수 있는 특성이 바로 단어의 빈도인 것이다.

 

 


BOW 기반의 카운트 벡터 생성

 

 

Count 기반의 문서 특성 표현은 문서를 단어의 나열이 아니라 단어의 통계로 보려는 시각이다.

단어가 텍스트에서 사용된 횟수를 특성값으로 사용한다.

 

 

BOW ( Bag Of Words)

 

Bag of words 는 문서들을 단어의 나열인 Sequence 가 아닌,

가방으로 표현한다. 물건들을 가방에 넣으면 순서가 흐트러지는 것과 같이 단어를 가방에 넣으면

원래 문장에서 사용되었던 단어의 순서들이 모두 사라지게 된다.

단어를 가방에서 꺼내서 정리하게 되었을 때 남는 것은 어떤 단어들이 몇 개가 들어있었는 지에 대한

통계만 남게 된다. 이것이 바로 Bag Of Words 인 것이다.

이렇게 꺼내서 정리한 것에 대한 통게를 우리는 특성 벡터라고 부르게 된다.

 

 

 

특성 집합

 

말뭉치에서 사용된 단어들 혹은 그 일부의 집합으로, 다양한 기준에 의해 생성되는 집합이다.

유사한 특성을 가지는 단어들의 집합이라고 보면 된다.

이 특성 집합을 여러가지로 처리하여 특성 벡터로 만드는 것이다.

 

문서는 하나의 일관된 목적이나 주제를 갖고 쓰여진 글이었다. (뉴스기사, 메일, 영화리뷰 등)

그리고 말뭉치는 이러한 문서들의 집합이다.

 

텍스트 마이닝은 문서 집합, 즉 말뭉치를 대상으로 이루어지기 때문에, 

특성 추출 역시 하나의 문서가 아닌 말뭉치를 대상으로 한다.

따라서 특성 집합은 전체 말뭉치에서 사용된 단어 전체의 집합인 것에 주의해야 한다.

 

특성 벡터로 변환하게 되었을 때,

가변길이의 문서가 일정한 길이의 벡터로 변환되게 되는데, 이 이후에는 통계적 분석이나

모든 머신러닝 기법들을 사용할 수 있기 때문에 할 수 있는 것이 많아지게 된다.

 

특성집합 예시 :)

 

doc1_token = ['two', 'two', 'four']

doc2_token = ['one','two','one','three']

doc3_token = ['three','four','four','five']

 

word_features = ['one','two','three','four','five']

 

doc1_features = [0,2,0,1,0]

doc2_features = [0,0,1,2,1]

doc3_features = [0,0,1,2,1]

 

 


NLTK 영화 리뷰 데이터를 사용한 특성 벡터 실습

 

NLTK 영화 리뷰 데이터를 사용해서 특성 벡터를 실습해보자.

NLTK 영화 리뷰 데이터는 NLTK 가 제공하는 말뭉치 중에 하나이다.

연구를  위해 수집된 2000개의 영화 리뷰와 그 리뷰의 긍정,부정의 감성값을 함께 제공한다.

NLTK Package 를 사용해서 import 가능하다.

 

import nltk
nltk.download('movie_reviews')
from nltk.corpus import movie_reviews

 

movie_reviews

 

 fileids() : 영화리뷰 문서들의 id를 반환한다. 

매개 변수 categories 를 사용하면 특성 분류에 속하는 문서들의 id만 가져올 수 있다.


 categoreis() : 리뷰 문서들에 대한 분류, 라벨을 보여준다. 

여기서는 감성을 표현하는 긍정('pos')와 부정('neg') 값을 갖는다.


 raw() : 리뷰 문서의 원문을 문자열 리스트 형태로 반환한다. 인수로 fileid 를 주면 특성 문서만 가져올 수 있다.

 

documents = [movie_reviews.raw(fileid) for fileid in movie_reviews.fileids()]
print("리뷰의 수 :", len(documents))
리뷰의 수 : 2000

리뷰의 수는 총 2000개이다.

 

 


Sklearn 을 이용한 카운터 벡터 생성

 

Sklearn 을 이용해서 카운트 벡터를 생성해보자.

 

sklearn.featrue_extraction 도구를 사용해서 카운트 벡터를 생성해볼것이다.

CountVectorizer 을 사용하면 카운트 기반 문서 표현을 쉽게 할 수 있다.

 

 

CountVectorizer

 

● tokenizer : 함수 형태로 외부 토크나이저를 지정한다. 지정하지 않았을 때는 자체 토크나이저를

사용하게 되며, 한글을 토큰화 시키기 위해서는 필수적으로 지정해주어야 한다.

 

stop_words : 리스트 형태로 불용어 사전을 지정한다 . 'english' 로 값을 주면 자체 영어 불용어

사전을 사용하게 된다. 마찬가지로 한글 불용어 사전은 필수이다.

 

max_df : 단어로 특성을 구성할 때, 문서에 나타난 빈도가 max_df 보다 크면 제외시킨다.

The 같은 경우를 제외시키는 것이다. 비율이나 문서의 수로 지정이 가능하다.

 

min_df : 단어로 특성을 구성할 때, 문서에 나타난 빈도가 min_df 보다 작으면 제외한다.

마찬가지로 너무 작은 빈도가 사용된 경우 필요없는 경우가 많기 때문에 제외시킨다.

이 또한 비율이나 문서 수로 지정이 가능하다.

 

max_features : 최대 특성의 수를 지정한다. 지정하지 않을 시 전체 단어를 다 사용한다.

 

vocabulary :  특성집합을 직접 지정한다.

 

binary : True 값을 주면 빈도 대신에 단어의 유무 (1/0) 로 특성 값을 생성한다.

 

fit(raw_documents) : 인수로 주어진 문서 집합(raw_documents) 에 대해서 토큰화를

수행하고, 특성 집합을 생성한다.

 

transform(raw_documents) : fit() 에서 생성한 특성 집합을 이용해서 인수로 주어진 문서집합에 대해

카운트 벡터로 변환하여 반환한다.

 

fit_transform(raw_documents) : 인수로 주어진 문서집합에 대해서 fit과 transform 을 동시에 수행한다.

 

get_feature_names_out() : 특성 집합에 있는 특성의 이름.

즉 단어를 순서대로 반환한다. 

 

 

자체적으로 제공하는 토큰화 기능을 사용해서 특성 벡터 변환을 해보자.

최대 특성 수는 2000, 단어 사용 문서 수가 5  미만이거나 50% 이상이면 그 단어는 특성에서 제외한다.

 

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features = 2000, min_df = 5, max_df = 0.5)
# 리뷰 문서에 대해서 fit_transform 적용
reviews_cv = cv.fit_transform(documents)

#특성 집합의 단어명을 앞에서부터 10개 출력
print(cv.get_feature_names_out()[:10])

#첫째 리뷰 문서의 앞 10개 특성을 출력
print(reviews_cv[0, :10])
['000' '10' '100' '13' '15' '1995' '1996' '1997' '1998' '1999']
  (0, 1)	10

 

위에 출력된 것은 특성이다. 숫자 다음에 문자가 나오기 때문에 아쉽게도 숫자만 나왔으나..

뒤로 가면 문자 특성도 나온다.

이하는 (0,1) 좌표값이 10이라는 뜻이다.

 

# 일반적인 행렬로 변환한 형태
print(reviews_cv.toarray()[:5, :5]) # 5개 문서
[[ 0 10  0  0  0]
 [ 0  0  0  0  0]
 [ 0  0  0  0  0]
 [ 0  0  0  0  0]
 [ 0  0  0  0  0]]

위를 값이 있는 셀만 저장해서 확인해보자.

 

# 값이 있는 셀만 저장한 형태
print(reviews_cv[:5, :5])
  (0, 1)	10

0번째 문서의 1번째 특성 columns 을 추출한 결과가 10이라는 뜻이다.

 

 

 


한국어 텍스트의 카운트 벡터 변환

 

다음 영화 리뷰 사이트에서 수집한 리뷰 데이터를 사용해서 카운트 벡터로 변환해보자.

7개 영화에 대한 14,725개의 리뷰를 포함한다.

pandas 를 이용해 데이터를 읽고, 아래와 같이 내용을 확인한다.

 

import pandas as pd
df = pd.read_csv("./daum_movie_review.csv")
df

인피니티 워 재밌는데 왜

 

sklearn 은 자체적인 토크나이저를 제공하지만, 한글은 지원하지 않는다.

따라서 한글 토크나이저를 사용하도록 지정해야 한다.

우리는 앞서 배웠던 KoNLPy 의 형태소 분석기를 사용하여 함수르 정의해보자.

형태소 분석 결과에서 명사, 동사, 형용사만 뽑아내서 반환하도록 함수를 구현했다.

 

KoNLPy 는 이 링크를 참조하자.

https://wndofla123.tistory.com/53?category=1079409 

 

[Text Mining] 텍스트 마이닝 - KoNLPy 를 사용한 한글 텍스트 전처리

한글 텍스트 전처리 영어는 띄어쓰기를 이용해서 분리만으로도 단어가 확실하게 분리가 되고, 단어 별로 뜻을 가지고 있기 때문에 높은 토큰화가 가능하지만, 한글은 단어의 변화가 매우 다양

wndofla123.tistory.com

 

from konlpy.tag import Okt
okt = Okt()
def my_tokenizer(doc) : # 트위터 형태소 분석기의 pos() 매서드 사용
    return [token for token, pos in okt.pos(doc)
           if pos in['Noun', 'Verb', 'Adjective']] # 명사, 동사, 형용사만을 변환
print("my_tokenizer 결과 : ", my_tokenizer(df.review[1]))
my_tokenizer 결과 :  ['몰입', '할수밖에', '없다', '어렵게', '생각', '할', '필요없다', '내', '전투', '참여', '듯', '손', '땀', '이남']

[1] 인덱스의 리뷰를 token 화 시켜주었다.

원문은 '몰입할수밖에 없다. 어렵게 생각할 필요없다. 내가 전투에 참여한듯 손에 땀이 남.'

이었다.

어느정도 잘 분리된 것 같다.

 

CountVectorizer 의 tokenizer 매개변수에 my_tokenizer 를 넣어주자.

그 외에는 영어 문서와 사용법이 동일하다.

my_tokenizer 대신 okt.nouns, okt.morphs 사용도 가능하다.

 

from sklearn.feature_extraction.text import CountVectorizer

# 토크나이저와 특성의 최대 개수를 지정
daum_cv = CountVectorizer(max_features = 1000, tokenizer = my_tokenizer)

# review 를 특성 벡터로 변환
daum_result = daum_cv.fit_transform(df.review)
print(daum_cv.get_feature_names_out()[:10]) # 특성 집합 앞 열 개 단어 출력
['가' '가는' '가는줄' '가면' '가서' '가슴' '가장' '가족' '가족영화' '가지']

가로 묶인 것 같다.

 

다음에는 이렇게 만든 카운트 벡터를 통해서 토픽모델링을 진행하여 주제를 찾아보자.

 

 

 

 ※ 해당 자료는 모두 공공 빅데이터 청년 인턴 교육자료들을 참고합니다.

Comments