Data Analysis & ML/Text Mining

[Text Mining][텍스트마이닝][NLP] Feature Vectorize(DTM/TDM, CountVectorizer)

YSY^ 2020. 9. 15. 16:47

Feature vectorization 개요

  • 텍스트를 숫자형값의 정형테이터로 변환하는 것을 Feature vectorization(피처 벡터화) 라고 한다.

BOW (Bag Of Words)

많이 나온 단어가 중요한 단어

  • 문서내에 단어 빈도수에 기반하여 Vector화 하는 모델
  • DTM/TDM (Document Term Matrix)
    • 문서안에서 문서를 구성하는 단어들이 몇번 나왔는지를 표현하는 행렬
    • 행:단어, 열: 문서 - DTM
    • 행:문서, 열:단어 - TDM
    • Value: 개수
  • TF-IDF (Term Frequency Inverse Document Frequency)
    • CountVectorize의 문제: 문장 구조상 많이 나오는 단어들의 경우 카운트 값이 많이 나오게 되고 중요한 단어로 인식된다. (ex: 관사, 접속사, 주제어 등) 이 문제를 보완한 모델이 TF-IDF 모델이다.
    • 개별 문서에 많이 나오는 단어가 높은 값을 가지도록 하되 동시에 여러 문서에 자주 나오는 단어에는 페널티를 주는 방식

DTM/TDM (Document Term Matrix)

  • 단어들이 각 문서에 몇번 나왔는지 행렬로 구성
  • 많이 나온 단어가 중요한 단어라는 것을 기반으로 한다.
  • 문서 단어 행렬(Document Term Matrix)
    • 문서별로 각 단어가 나타난 횟수를 정리한 표
    • 컬럼(Feature): 전체 문서에 나오는 모든 단어
    • 행 : 문서
    • 값(value) : 각 단어가 문서에 나온 횟수
  • 단어 문서 행렬(Term Document Matrix)
    • DTM을 전치 시킨 것
    • 컬럼(Feature): 문서
    • 행: 전체 문서에 나오는 모든 단어
    • 값(value) : 각 단어가 문서에 나온 횟수
  • scikit-learn의 CountVectorizer 이용

CountVectorizer

주요 생성자 매개변수

  • stop_word :stopword 지정
    • str: "english" - 영문 불용어는 제공됨
    • list: stopword 리스트
  • max_df: 특정 횟수 이상나오는 것은 무시하도록 설정(무시할 횟수/비율 지정)
    • int(횟수), float(비율)
  • min_df: 특정 횟수 이하로 나오는 것은 무시하도록 설정(무시할 횟수/비율 지정)
  • max_features: 최대 token 수
    • 빈도수가 높은 순서대로 정렬 후 지정한 max_features 개수만큼만 사용한다.
  • ngram_range: n_gram 범위 지정
    • n_gram:
    • 튜플 (범위 최소값, 범위 최대값)
    • (1, 2) : 토큰화된 단어를 1개씩 그리고 순서대로 2개씩 묶어서 Feature를 추출

메소드

  • fit(X)
    • 학습
    • 매개변수: raw document - 문장을 원소로 가지는 1차원 배열형태(list, ndarray)
    • Train(훈련) 데이터셋 으로 학습한다. Test 데이터셋은 Train 셋으로 학습한 CountVectorizer를 이용해 변환만 한다.
  • transform(X)
    • DTM 변환
  • fit_transform(X)
    • 학습/변환 한번에 처리

n-gram

DTM는 문맥상에서 단어의 의미는 무시된다. 이것을 보완하는 것이 n-gram 기법이다.
n개의 단어를 묶어서 feature로 구성한다.

train = ["He really likes football. He wants to be a football player.",  #문서(document)
         "Football is a popular sport in Europe.",                       #문서
         "Which country started football?"]                              #문서
test = ["He really likes baseball. He wants to be a baseball player.", 
        "Baseball is a popular sport in Korea."]
# 텍스트 전처리 함수
import nltk
from nltk.stem import SnowballStemmer
from nltk.corpus import stopwords

def text_preprocessing(documents):
    """documents(매개변수): document 리스트"""
    stemmer = SnowballStemmer("english")
    stop_words = stopwords.words('english')

    return_list = []
    for doc in documents:
        doc = doc.lower()
        tokens = nltk.regexp_tokenize(doc, r'[A-Za-z]+')
        #불용어 처리
        tokens = [token for token in tokens if token not in stop_words]
        #stemming(어간추출)
        tokens = [stemmer.stem(token) for token in tokens]

        return_list.append(' '.join(tokens))

    return return_list
print(train)
# ['He really likes football. He wants to be a football player.', 'Football is a popular sport in Europe.', 'Which country started football?']

print(text_preprocessing(train))
# ['realli like footbal want footbal player', 'footbal popular sport europ', 'countri start footbal']


train_pre = text_preprocessing(train)
test_pre = text_preprocessing(test)

train 셋을 이용해 학습 및 변환

# 학습: Train, 변환: Train, Test
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
# cv = CountVectorizer(ngram_range=(1,3))  #1-gram, 2-gram, 3-gram
# cv = CountVectorizer(ngram_range=(3,3))  #3-gram
train_cv = cv.fit_transform(train_pre)
test_cv = cv.transform(test_pre)

 

import pandas as pd
dtm_train = pd.DataFrame(train_cv.toarray(), columns = cv.get_feature_names())
dtm_train

 

test 셋 변환

df = pd.DataFrame(test_cv.toarray(), columns=cv.get_feature_names())

 

728x90
반응형