본문 바로가기

Study/Introduction to ML with python - 한빛

[Book] 7. 텍스트 데이터 다루기 - (1)

Book Title : Introduction to Machine Learning with Python

- 파이썬 라이브러리를 활용한 머신러닝 -

지은이 : 안드레아스 뮐러, 세라 가이도

옮긴이 : 박해선

출판사 : 한빛미디어

코드 출처

https://github.com/rickiepark/introduction_to_ml_with_python

 

GitHub - rickiepark/introduction_to_ml_with_python: 도서 "[개정판] 파이썬 라이브러리를 활용한 머신 러닝"의

도서 "[개정판] 파이썬 라이브러리를 활용한 머신 러닝"의 주피터 노트북과 코드입니다. Contribute to rickiepark/introduction_to_ml_with_python development by creating an account on GitHub.

github.com


7. 텍스트 데이터 다루기

  • 텍스트 데이터는 주로 글자가 연결된 문자열로 표현
  • 텍스트 데이터는 수치형 특성과 매우 다르므로 머신러닝 알고리즘에 적용하기 전에 전처리를 해야 함

7.1 문자열 데이터 타입

문자열 데이터 4 종류
  1. 범주형 데이터
  2. 범주에 의미를 연결시킬 수 있는 임의의 문자열
  3. 구조화된 문자열 데이터
  4. 텍스트 데이터

7.2 텍스트 데이터를 BOW로 표현하기

  • 문단, 문장, 서식 같은 입력 텍스트의 구조 대부분을 읽어버리고 각 단어가 이 말뭉치에 있는 텍스트에 얼마나 많이 나타나는지만 헤아림
  • 구조는 상관하지 않고 단어의 출현 횟수만 세는 텍스트를 담는 가방(Bag)
3단계
  1. 토큰화(Tokenization) : 각 문서를 문서에 포함된 단어(토큰)으로 나눔
  2. 어휘 사전 구축 : 모든 문서에 나타난 모든 단어의 어휘를 모으고 번호를 매김
  3. 인코딩 : 어휘 사전의 단어가 문서마다 몇 번이나 나타는지 체크

샘플 데이터에 BoW

bards = ['The fool doth think he is wise,',
         "but the wise man knows himself to be a fool"]

from sklearn.feature_extraction.text import CountVectorizer
vector = CountVectorizer()
vector.fit(bards)

# 어휘 사전 구축
print("어휘 사전 크기", len(vector.vocabulary_))
print("어휘 사전 내용", vector.vocabulary_)

# 어휘 사전 크기 13
# 어휘 사전 내용 {'the': 9, 'fool': 3, 'doth': 2, 'think': 10, 'he': 4, 'is': 6, 'wise': 12, 'but': 1, 
#                'man': 8, 'knows': 7, 'himself': 5, 'to': 11, 'be': 0}

bow = vector.transform(bards)
print("bow", bow.toarray())

# bow [[0 0 1 1 1 0 1 0 0 1 1 0 1]
# [1 1 0 1 0 1 0 1 1 1 0 1 1]]

 

  • BOW 표현은 0이 아닌 값만 저장하는 SciPy 희소 행렬로 저장되어 있어서 실제 내용을 보려면 toarray 메서드를 사용하여 Numpy 형태로 확인
  • 각 단어의출현 횟수는 0 아니면 1
  • 첫 번째 리스트는 “The fool doth think he is wise”를 나타냄

7.4 불용어

  • 의미없는 단어를 제거하는데 2가지 방식이 있는데 언어별 불용어(stop word) 목록을 사용하는 것과 너무 자주 나타나는 단어를 제외하는 것
  • 사이킷런의 feature_extraction.text 모듈 사용
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
print("불용어 개수:", len(ENGLISH_STOP_WORDS))
print("불용어 개수 예시 10개", list(ENGLISH_STOP_WORDS)[:5])

불용어 개수: 318
불용어 개수 예시 10개 ['everything', 'side', 'over', 'since', 'nowhere']

 

  • 불용어를 제외하면 특성의 개수(318) 만큼 줄어들겠지만, 성능이 향상될 수도 있음
  • 사용방법은 stop_words = ‘english’라고 지정하면 내장된 불용어를 사용
vector = CountVectorizer(min_df = 5, stop_words = 'english').fit(X)

 

7.5 td-idf로 데이터 스케일 변경

  • td-idf(term frequency-inverse document frequency, 단어 빈도- 역면서 빈도)
  • 중요하지 않아 보이는 특성을 제외하는 대신, 얼마나 의미 있는 특성인지를 계산해서 스케일을 조정하는 방식
  • td-idf는 말뭉치의 다른 문서보다 특정 문서에 자주 나타나는 단어에 높은 가중치를 주는 방법
  • 예를들어 한단 어가 특정 문서에 자주 나타나고 다른 여러 문서에는 그렇지 않다면, 그 문서의 내용을 아주 잘 설명하는 단어라보 볼 수 있음
  • 사이킷런의 TfidfTransformer는 CountVectorizer가 만든 희소 행렬을 입력받아 변환
from sklearn.feature_extraction.text import TfidVectorizer
from sklearn.pipeline import make_pipeline
pipe = make_pipeline(TfidVectorizer(min_df = 5), LogisticRegression(max_iter =500))
param_grid = {'logisticregression__C' : [0.001, 0.01, 0.1, 1, 10]}

grid = GridSearchCV(pipe, param_grid, cv = 5)
grid.fit(X, y)