본문 바로가기
코딩/Machine Learning

13. 텍스트 분석(Text Analytics)_1

by 세자책봉 2021. 1. 10.
728x90

권철민 저, '파이썬 머신러닝 완벽 가이드', 2019.02.28

내 맘대로 요약 공부 중(문제시 비공개 및 삭제)

최초 작성일 2021.1.10

 

- NLP(National Language Processing): 인간의 언어를 이해하고 해석하는데 중점(기계 번역, 챗봇 등)

- TA(Text Analytics): 비정형 텍스트에서 의미 있는 정보를 추출하는데 중점(결국, NLP를 포함하는 상위 개념)

                         : 머신러닝, 통계 등을 활용해 모델을 만들고 비즈니스 인텔리전스 등 예측 분석을 수행

  • 텍스트 분류(Text Classification): Text Categorization, 문서가 특정 분류 또는 카테고리에 있는 것을 예측하는 기법
  • 감성 분석(Sentiment Analysis): Text에 나타나는 감정/판단 등의 주관적인 요소를 분석하는 기법
  • 텍스트 요약(Text Summarization): Text에 중요한 주제나 중심 사상을 추출하는 기법(Topic Modeling)
  • 텍스트 군집화(Text Clusterting)와 유사도 측정: 비슷한 유형의 문서에 대해 군집화를 수행하는 기법
13.1 텍스트 분석 이해

- 머신러닝 알고리즘은 숫자형 피처 기반 데이터를 입력받을 수 있음

- 어떻게 비정형 텍스트 데이터를 숫자형 피처 기반으로 추출하여 의미 있는 값을 부여하는가?

피처 벡터화(Feature Vectorization), 피처 추출(Feature Extraction)
 - 텍스트를 word 기반의 다수의 피처로 추출하고, 이 피처에 단어 빈도수와 같은 숫자 값을 부여하면
   텍스트는 단어의 조합인 벡터 값으로 표현됨
 - 주요 방법: BOW(Bag of Words), Word2Vec

- 텍스트 분석 수행 프로세스

  1. 텍스트 전처리: 텍스트를 피처로 만들기 전 대/소문자 변경, 특수문자 삭제, 단어(word) 토큰화, 의미 없는 단어 삭제 , 어근 추출 등 텍스트 정규화 작업
  2. 피처 벡터화/추출: 가공된 텍스트에서 피처를 추출하고 벡터 값을 할당하는 작업, BOW와 Word2Vec이 있음
  3. ML 모델 수립/학습/평가: 피처 벡터화된 데이터 세트에 ML 모델을 적용

- 파이썬 기반의 NLP, 텍스트 분석 패키지

  • NLTK(National Language Toolkit for Python): 파이썬의 가장 대표적인 NLP 패키지, 수행 속도가 느려 실제 대량의 데이터 기반에서는 제대로 활용되지 못함
  • Gensim: 토픽 모델링 분야의 대표적인 패키지, SpaCy와 가장 많이 사용되는 NLP 패키지
  • SpaCy: 수행성능이 가장 좋은 최신의 NLP 패키지, 가장 많이 쓰임
13.2 텍스트 전처리(텍스트 정규화)

- 텍스트 정규화 작업

  • 클렌징(Cleansing)
  • 토큰화(Tokenization)
  • 필터링/스톱 워드 제거/철자 수정
  • Stemming/Lemmatization

- 클렌징(Cleansing)

  • 텍스트 분석에 방해되는 불필요한 문자, 기호 등을 사전에 제거하는 작업(HTML, XML 태그, 특정기호 등)

- 텍스트 토큰화(Tokenization)

  • 문서에서 문장을 분리하는 문장 토큰화, 문장에서 단어를 토큰으로 분리하는 단어 토큰화
  • 문장 토큰화(Sentence Tokenization)

문장으로 구성된 List를 반환

  • 단어 토큰화(Word Tokenization): 공백, 콤마(,), 마침표(.), 개행 문자 등으로 단어를 분리

단어의 순서가 중요하지 않을 경우, 단어 토큰화만 수행해도 충분하다

  • 문장 토큰화 & 단어 토큰화 결합 사용

3가지 문장으로 추출 후 문장 별 단어 토큰화 수행

  • 문장을 단어 토큰화 할 경우 문맥적인 의미는 무시되기 마련인데 이를 보정해주는 것 = n-gram
  • n-gram: 연속된 n개의 단어를 하나의 토큰화 단위로 분리하여 문맥적인 의미를 포함시킴

- 스톱 워드(Stop Word) 제거

  • 분석에 큰 의미가 없는 단어 제거
  • NLTK의 stopwords 목록을 사용, nltk.download('stopwords')

영어의 stopwords 개수는 179개
is, this 등 stopwords가 제거됨

- Stemming/Lemmatization

  • 문법적 혹은 의미적으로 변화하는 단어의 원형을 찾는 것(과거형, 현재형, 미래형, 3인칭 단수 등)
  • 성능: Lemmatization > Stemming, 수행 시간: Lemmatization > Stemming
  • NLTK Stemmer: Porter, Lancaster, Snowball Stemmer / NLTK Lemmatization: WordNetLemmatizer
  • Stemmer(Lancaster)

work를 제외하고 나머지는 원형을 제대로 파악하지 못함(amuse, happy, fancy)

  • Lemmatization(WordNetLemmatizer), 품사를 입력해줘야 함(동사:'v', 형용사:'a')

Stemming 보다 성능이 좋지만, 수행시간이 느리다는 단점

13.3 BOW(Bag of Words)

- 모든 단어(Words)를 문맥이나 순서를 무시하고 일괄적으로 단어에 대해 빈도 값을 부여해 피처 값을 추출하는 모델

- 모든 단어를 봉투(Bag) 안에 넣은 뒤 흔들어서 섞는다는 의미로 BOW 모델이라고 함

- BOW 단점

  • 문맥 의미(Sementic Context) 반영 부족: 단어의 순서를 고려하지 않으므로 문맥적 의미가 무시됨                                                                            (보완을 위한 n-gram 기법이 있긴 있음)
  • 희소 행렬 문제(희소성, 희소행렬): 희소 행렬 형태의 데이터 세트가 만들어지기 쉬움. 즉 매우 많은 문서는 서로 다른 단어로 구성되기 때문에 단어의 빈도가 나타나지 않는 경우가 훨씬 더 많은데, 이로 인해 대부분의 데이터는 0으로 채워지게 됨. 대규모의 행렬에서 대부분의 값이 0인 행렬을 희소 행렬(Sparse Matrix)이라고 하며 이는 ML 알고리즘의 수행 시간과 예측 성능을 떨어뜨린다.(희소 행렬 반대 → 밀집 행렬(Dense Matrix))

- BOW 피처 벡터화

  • 모든 문서의 모든 단어를 칼럼 형태를 나열하고, 각 문서에서 해당 단어의 횟수 혹은 정규화된 빈도를 값으로 부여하는 데이터 세트 모델로 변경하는 것
  • M개의 텍스트 문서, 문서 별 N개의 단어 → M×N개의 단어 피처로 이루어진 행렬을 구성
  • 대표적인 BOW 피처 벡터화: Count 벡터화, TF-IDF(Term Frequency - Inverse Document Frequency) 벡터화
  • Count 벡터화: 개별 문서에서 해당 단어가 나타나는 횟수가 많을수록 중요한 단어로 인식
  • TF-IDF 벡터화: 개별 문서에서 자주 나타나는 단어에 높은 가중치를 주되, 전체 문서에서 자주 나타나는 단어에                          대해서는 페널티를 부여

문서의 개수가 많은 경우, TF-IDF 방식이 성능이 좋음

 

- 사이킷런의 Count 및 TF-IDF 벡터화 구현(CountVectorizer, TfidfVectorizer)

  • CountVectorizer 클래스(텍스트 전처리 및 피처 벡터화 함께 수행, fit_transform())
파라미터 명 설 명
max_df 전체 문서에 너무 높은 빈도수를 갖는 단어 피처를 제외하기 위한 파라미터
max_df = 100, 빈도수가 100개 이하의 단어만 피처로 추출
max_df = 0.95, 빈도수가 95% 이하의 단어만 피처로 추출
min_df 전체 문서에 너무 낮은 빈도수를 갖는 단어 피처를 제외하기 위한 파라미터
min_df = 2, 빈도수가 2개 이하의 단어는 피처 제외
min_df = 0.02, 빈도수가 2% 이하의 단어는 피처 제외
max_features 추출하는 피처의 개수 제한
max_features=2000, 가장 높은 빈도를 갖는 단어 순으로 2000개를 추출
stop_words 'english', 영어의 stopwords로 지정된 단어는 추출에서 제외
n_gram_range BOW 모델의 단어 순서를 보완하는 n_gram 범위 설정
(1,1)은 토큰화된 단어를 1개씩 피처로 추출, (1,2)는 토큰화된 단어를 1개씩, 2개씩 묶어서 피처로 추출
analyzer 피처 추출을 수행할 단위 설정, Default='word'
character의 특정 범위를 피처로 만들수도 있음
token_pattern 토큰화를 수행하는 정규 표현식 패턴 지정, Default = '\b\w\w+\b'
공백 또는 개행 문자 등으로 구분된 단어 분리자(\b) 사이의 2문자 이상의 단어를 토큰으로 분리
analyzer = 'word'로 설정했을 때만 변경 가능(거의 대부분 바꿀일 없음)
tokenizer 토큰화를 별도의 커스텀 함수를 사용할 때 적용
일반적으로, CountTokenizer 클래스에서 어근 변환 시 별도 함수를 적용시킴
  • CountVectorizer, TfidfVectorizer를 이용한 피처 벡터화 흐름

- BOW 벡터화를 위한 희소 행렬

  • 피처 칼럼을 만들 때 대규모 행렬이 생성되고, 이 대규모 행렬의 대부분을 0이 차지하는 행렬 → 희소 행렬
  • 희소 행렬은 불필요한 0 때문에 연산에 많은 시간이 소요됨
  • 희소 행렬을 적은 메모리 공간을 차지할 수 있도록 변환해야 함(COO형식, CSR 형식)

- 희소 행렬(COO형식- Coordinate)

  • 0이 아닌 데이터만 별도의 데이터 배열(Array)에 저장하고, 그 데이터가 가리키는 행렬의 위치를 별도 배열에 저장하는 방식
  • [[3,0,2],[0,1,0]]에서 0이 아닌 데이터는 [3,2,1], 0이 아닌 데이터가 있는 위치는 (row,col) (0, 0), (0, 2), (1,1)
  • 행 위치 배열 [0,0,1], 열 위치 배열 [0,2,1]
  • 파이썬에서는 희소 행렬 변환을 위해 Scipy의 sparse 패키지 활용

- 희소 행렬(CSR형식 - Compressed Sparse Row)

  • COO 형식의 반복적인 위치 데이터 사용 문제를 해결
  • 행 위치 배열은 특성상 0부터 순차적으로 증가하는 값으로 이루어짐
  • 행 위치 배열 [0,0,1,1,1,1,1,2,2,3,4,4,5]은 0이 2번, 1이 5번, 2가 2번, 4가 2번 반복되고 있음
  • 행 위치 배열의 숫자가 변하는 위치만 다시 별도의 배열로 변환하는 방식
  • [0,0,1,1,1,1,1,2,2,3,4,4,5] → [0,2,7,9,10,12] CSR변환 후 최종 데이터 총 개수 배열 추가 [0,2,7,9,10,12,13]
  • Scipy의 csr_matrix 패키지 활용

실제로는 위처럼 사용하면 된다

13.4 텍스트 분류 실습 - 뉴스그룹 분류

- sklearn의 fetch_20newsgroups() API 활용

- 텍스트 정규화

  • 데이터 불러오기

데이터 확인
Target 클래스 값은 0~19, 20개
데이터에 포함되어있는 내용 확인

  • 헤더와 푸터 정보는 제외하고 기사 내용만으로 분류 시행
  • remove 파라미터를 사용하여 header, footer 제거
  • fetch_20newsgroups()는 subst 파라미터를 이용해 학습 데이터와 테스트 데이터를 분리해 내려받을 수 있음

사용법을 알아야한다..

- 피처 벡터화 변환 및 머신러닝 모델 학습/예측/평가

  • CountVectorizer로 학습 데이터의 텍스트를 피처 벡터화. 테스트 데이터는 학습 데이터로 fit()이 수행된 CountVectorizer 객체로 변환해야 함(학습 시 설정된 피처 개수와 테스트 데이터를 변환할 피처 개수 동일해짐)
  • 테스트 데이터의 피처 벡터화는 학습 데이터에 사용된 CountVectorizer 객체 cnt_vect.transform() 이용

11314개의 문서에서 101631개의 피처 생성
CountVectorizer 결과 정확도 0.617

  • TD-IDF 수행

.fit() 메서드 사용시 y_train을 넣고 안넣고는 차이가 없다 TD-FID 결과 정확도 0.678

  • Stop_words='english', ngram_range=(1,2), max_df=300

성능향상 정확도 0.690

  • GridSearchCV 하이퍼 파라미터 튜닝

성능향상 정확도 0.704

- 사이킷런 파이프라인(Pipeline)과 GridSearchCV 결합

  • 머신러닝에서 Pipeline: 데이터의 가공, 변환 등의 전처리와 알고리즘 적용을 물 흐르듯 한 번에 처리하는 것을 의미
  • 수행 시간을 절약할 수 있다는 장점

한번에 처리할 수 있다는 장점

  • GridSearchCV 결합
  • 주의사항: GridSearchCV의 param_grid의 입력값의 Key값이 객체 변수 명 + 하이퍼 파라미터 명

성능이 크게 향상되지는 않았다

 

반응형

'코딩 > Machine Learning' 카테고리의 다른 글

15. 추천 시스템(Recommendations)  (0) 2021.01.13
14. 텍스트 분석(Text Analytics)_2  (0) 2021.01.11
12. 군집화(Clustering)  (2) 2021.01.09
11. 차원 축소(Dimension Reduction)  (0) 2021.01.03
10. 회귀(Regression)_3  (0) 2021.01.02

댓글