본문 바로가기
IT 도서/파이썬 머신러닝

8. 텍스트 분석

by 이민우 2021. 2. 11.
728x90
반응형

book.naver.com/bookdb/book_detail.nhn?bid=16238302

 

파이썬 머신러닝 완벽 가이드

자세한 이론 설명과 파이썬 실습을 통해 머신러닝을 완벽하게 배울 수 있습니다!《파이썬 머신러닝 완벽 가이드》는 이론 위주의 머신러닝 책에서 탈피해 다양한 실전 예제를 직접 구현해 보면

book.naver.com

*해당 글은 학습을 목적으로 위의 도서 내용 중 일부 내용만을 요약하여 작성한 포스팅입니다.

 상세한 내용 및 전체 내용 확인을 원하신다면 도서 구매를 추천드립니다.

 

 

텍스트 분석 (텍스트 마이닝)

NLP와 텍스트 분석의 차이

  • NLP는 머신이 인간의 언어를 이해하고 해석하는 데 중점을 둔다.
  • 텍스트 분석은 비정형 텍스트에서 의미있는 정보를 추출하는 것에 중점을 둔다.

*엄밀히 따지면 다른 개념이지만, 머신러닝이 보편화되며 NLP와 텍스트 마이닝을 구분하는 것이 의미가 없어졌다.

 

 

텍스트 분석의 종류

  1. 텍스트 분류 : 문서가 특정 분류 또는 카테고리에 속하는 것을 예측하는 기법
  2. 감성 분석 : 텍스트에서 나타나는 주관적인 요소를 분석하는 기법
  3. 텍스트 요약 : 텍스트 내의 중요한 주제나 중심 사상을 추출하는 기법
  4. 텍스트 군집화와 유사도 측정 : 비슷한 유형의 문서에 대해 군집화를 수행하는 기법

 

 


 

텍스트 분석

  • 비정형 데이터인 텍스트를 분석하는 것
  • 순서는 다음과 같이 진행된다.
  1. 텍스트 전처리 (클렌징, 대소문자 변경, 특수문자 삭제, 토큰화, 스톱웨드 제거 등)
  2. 피처 벡터화 및 추출 : 텍스트 데이터를 숫자형 피처 데이터로 변환하는 것. (BOW, Word2Vec 등)
  3. ML 모델 수립 및 학습, 예측, 평가

 

 

NLTK

  • 파이썬 기반의 텍스트 분석 패키지
  • 방대한 데이터 셋과 서브 모듈, 다양한 데이터 셋을 지원해 오래전부터 파이썬의 대표 NLP 패키지였다.
  • 하지만 수행 성능과 정확도, 신기술, 엔터프라이즈한 기능 지원 등의 측면에서 많이 부족한 부분이 있다.
  • 이런 점을 보완하기 위해 Gensim, SpaCy가 출시되어 실제 업무에서 활용되고 있다.

*사이킷런은 NLP를 위한 라이브러리를 가지고 있지 않아 더 다양한 텍스트 분석을 위해

 NLTK, Gensim, SpaCy와 같은 NLP 전용 패키지와 함께 결합해야 한다.

*단, 일정 수준으로는 가공하고 피처로 처리할 수 있지만 충분하지는 않다.

*Gensim : 토픽 모델링 분야(텍스트 요약)에서 두각을 나타낸다. Word2Vec 지원

*SpaCy : 뛰어난 수행 성능을 가지고 있다.

 

 


텍스트 정규화

  • 텍스트를 입력 데이터로 사용하기 위해 클렌징, 정제, 토큰화, 어근화 등 다양한 텍스트 데이터의 사전 작업을 수행하는 것

 

 

클렌징

  • 텍스트 분석에 방해가 되는 불필요한 문자, 기호 등을 제거하는 작업
  • HTML, XML의 태그나 특정 기호도 포함된다.

 

 

텍스트 토큰화

  • 문서에서 문장을 분리하거나, 문장에서 단어를 토큰으로 분리하는 작업
  • 문장 토큰화 : 문서를 마침표, 개행문자 등을 기준으로 분리하는 작업.
  • nltk.sent_tokenize(text=데이터)로 쉽게 처리할 수 있다.
  • 단어 토큰화 : 문장을 공백, 콤마, 마침표 등을 기준으로 분리하는 작업
  • nltk.word_tokenize(데이터)로 쉽게 할 수 있다.

 

 

스톱 워드 제거

  • 스톱 워드분석에 큰 의미가 없는 단어를 지칭한다.
  • 영어에서는 is, the, a, will 등의 필수 문법 요소가 해당된다.
  • 제거해야 하는 이유는, 이러한 것들은 빈번하게 나타나 중요하지 않음에도 중요한 단어로 인식될 수 있기 때문이다.
  • nltk.corups.stopwords.words('english')로 스톱 워드 목록을 불러올 수 있다.
  • 이후 제거는 단어 토큰화된 리스트에서 직접 삭제 알고리즘을 만들어서 사용해야 한다.

 

 

Stemming과 Lemmatization

  • 많은 언어가 문법적인 요소에 따라 단어가 다양하게 변화한다.
  • 영어의 경우 과거/현재, 3인칭 단수 여부, 진행형 등이 이에 해당된다.
  • StemmingLemmatization문법적 또는 의미적으로 변화하는 단어의 원형을 찾아내는 작업이다.
  • Stemming은 원형 단어로 변환 시 일반적인 방법을 적용하거나 더 단순화된 방법을 적용해서 원래 단어에서 일부 철자가 훼손된 어근 단어를 추출하는 경향이 있다.
  • 이에 반해 Lemmatization은 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안해 정확한 철자로 된 어근 단어를 찾아준다.
  • 즉, Lemmatization이 Stemming보다 정교하며 의미론적 기반에서 단어의 원형을 찾지만, 변환에 더 오랜 시간이 소요된다.

 

 

NLTK에서의 Stemming

  • nltk.stem.LancasterStemmer
  • 형용사의 비교형, 최상급형의 변환에 대해 정확하지 못하다.

 

 

NLTK에서의 Lemmatization (어근 추출)

  • nltk.stem.WordNetLemmatizer
  • 파라미터로 단어와 품사를 입력해야 한다. (동사는 'v', 형용사는 'a')

 

 


BOW (Bag Of Words)

  • 문서가 가지는 모든 단어를 문맥이나 순서를 무시한다.
  • 모든 단어를 일괄적으로 단어에 대해 빈도 값을 부여해 특징 값을 추출하는 모델.
  • 쉽고 빠르게 구축할 수 있다.
  • 또한 단순히 단어의 발생 횟수에 기반함에도 불구하고 문서의 특징을 잘 나타낸다.
  • 그래서 여러 분야에서 활용도가 높다.
  • 하지만 문맥 의미를 반영하지 못해 문맥적인 해석을 처리하지 못한다.
  • 또한 머신러닝 알고리즘의 수행 시간과 예측 성능을 떨어뜨리는 희소 행렬을 만들어내기 쉽다.

*희소 행렬 : 대부분의 값들이 0으로 채워진 행렬

 

 

BOW에 피처 벡터화

  • 피처 벡터화 : 텍스트를 특정 의미를 가지는 숫자형 벡터 값으로 변환하는 것.
  • BOW 모델에서의 피처 벡터화는 모든 문서에서 모든 단어를 칼럽 형태로 나열하고 각 문서에서 해당 단어의 횟수나 정규화된 빈도를 값으로 부여하는 데이터 세트를 모델로 변경하는 것.
  • m개의 문서에 들은 모든 단어 수의 총합이 n개이면 m*n개의 행렬이 출력된다.

 

 

Bow의 피처 벡터화 방식

1) 카운트 기반의 벡터화

  • 단어 피처에 값을 부여할 때 각 문서에서 해당 단어가 나타내는 횟수를 센 것.
  • 카운트 값이 높을수록 중요한 단어로 인식된다.
  • 하지만 언어의 특성상 문장에서 자주 사용되는 단어에 높은 값을 부여하게 된다.

 

 

2) TF-IDF

  • 카운트 기반의 벡터화가 중요하지 않은 단어에 높은 값을 부여해 중요한 단어로 인식하는 문제를 해결한 모델
  • 개별 문서에서 자주 나타나는 단어에 높은 가중치를 주되, 모든 문서에서 전반적으로 자주 나타나는 단어에 대해서는 패널티를 부여한다.
  • 개별 문서에서 자주 나타나는 단어는 해당 문서를 특정짓는 중요한 단어일 수 있지만, 해당 단어가 다른 문서에서도 빈번하게 나타나면 언어 특성상 범용적으로 자주 사용되는 단어일 확률이 높기 때문.
  • 문서마다 텍스트가 길고 문서의 개수가 많은 경우 카운트 방식보다 TF-IDF 방식이 낫다.

 

 

사이킷런의 Count

  • sklearn.feature_extraction.text.CountVectorizer(*, input='content', encoding='utf-8', decode_error='strict', strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, stop_words=None, token_pattern='(?u)\b\w\w+\b', ngram_range=(1, 1), analyzer='word', max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class 'numpy.int64'>)

*max_df : 전체 문서에 걸쳐 max_df 이상의 빈도수를 가지는 단어 피처 제외.

*min_df : 전체 문서에 걸쳐 min_df 이하의 빈도수를 가지는 단어 피처 제외

*max_features : 추출하는 피처의 개수 제한. 가장 높은 빈도의 단어를 max_features개만 추출

*stop_words : 해당 언어의 스톱 워드를 불러와 추출에서 제외

*n_gram_range : 단어 순서를 보장하기 위한 n_gram 범위 설정

*analyzer : 피처 추출을 수행한 단위 지정

*token_pattern : 정규 표현식 패턴 지정

*tokenizer : 토큰화를 별도의 커스텀 함수로 이용시 적용

 

 

사이킷런의 TF-IDF

  • sklearn.feature_extraction.text.TfidfVectorizer(*, input='content', encoding='utf-8', decode_error='strict', strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, analyzer='word', stop_words=None, token_pattern='(?u)\b\w\w+\b', ngram_range=(1, 1), max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class 'numpy.float64'>, norm='l2', use_idf=True, smooth_idf=True, sublinear_tf=False)
  • 주요 파라미터는 CountVectorizer와 같다.
  • 리턴 값은 CSR 형태로 추출된다.

 

 

BOW 벡터화를 위한 희소 행렬

  • 희소 행렬은 연산 시 데이터 액세스에 시간을 많이 사용하게 하고, 메모리 공간을 너무 많이 차지한다.
  • 그래서 변환해야 하는데, 대표적인 변환 형식은 COO와 CSR이 있다.

 

 

COO 형식

  • 0이 아닌 데이터만 별도의 데이터 배열에 저장하고, 그 데이터가 가리키는 행과 열의 위치를 별도의 배열로 저장한다.
  • [[3, 0, 1], [0, 2, 0]] => [3, 1, 2], [0, 0, 1], [0, 2, 1] #값, 행 위치, 열 위치
  • scipy.sparsecoo_matrix((data, (row_pos, col_pos)) 를 사용해 행렬로 전환이 가능하다.

 

 

CSR 형식

  • COO 행렬은 행과 열의 위치를 나타내기 위해 반복적인 위치 데이터를 사용했다.
  • 이로 인해 큰 희소 행렬을 저장하고 계산하는 능력이 떨어졌는데, 이 점을 극복했다.
  • 순차적인 같은 값이 반복적으로 나타날 때, 고유한 값의 시작 위치만 표기한다.
  • 마지막에는 총 항목 개수를 기입한다.
  • [[3, 0, 1], [0, 2, 0]] => [3, 1, 2], [0, 2, 3], [0, 1, 2, 3]
  • 행위치 [0,0,1,1,1,1,1,2,2,3,4,4,5] => [0, 2, 7, 9, 10, 12, 13]
  • scipy.sparsecsr_matrix((data, (row_pos, col_pes)) 를 사용해 행렬로 전환이 가능하다.

 

 

 


감성 분석

  • 문서의 주관적인 감성/의견/감정/기분 등을 파악하기 위한 방법
  • 소셜 미디어, 여론조사, 온라인 리뷰, 피드백 등 다양한 분야에서 활용된다.
  • 문서 내 텍스트가 나타내는 여러 가지 주관적인 단어와 문맥을 기반으로 감성 수치를 계산하는 방법
  • 감성 지수는 긍정 감성 지수와 부정 감성 지수로 구성되며, 이 지수를 합산태 긍정 혹은 부정 감성을 결정
  • 감성 분석은 지도 학습과 비지도 학습으로 나뉜다.

*지도 학습은 일반적인 텍스트 기반의 분류와 거의 동일

*비지도 학습은 Lexico이라는 일종의 감성 어휘 사전을 이용.

 

 

비지도 학습 기반 감성 분석

  • Lexicon을 기반으로 한다.
  • Lexicon은 일반적으로 어휘집을 의미하지만, 주로 감성만을 분석하기 위해 지원하는 감성 어휘 사전이다.
  • 렉시콘은 긍정 감성 또는 부정 감성의 정도를 의미하는 수치를 가지고 있으며, 이를 감성 지수라고 한다.
  • 감성 지수는 단어의 위치, 주변 단어, 문맥, POS (Part of speech) 등을 참고해 결정된다.
  • NLTK에서도 감성 사전인 WordNet이 존재하지만, 예측 성능이 뛰어나지 못하다. 그래서 실제 업무는 NLTK가 아닌, NLTK를 포함한 감성 사전을 이용한다.

 

 

NLTK을 포함한 감성 사전

1) SentiWordNet

  • NLTK 패키지의 WordNet과 유사한 감성 단어 전용의 워드넷.
  • 긍정 감성 지수, 부정 감성 지수, 객관성 지수를 할당한다.
  • 객관성 지수는 개념적으로 단어의 감성과 관계없이 얼마나 객관적인지를 수치로 나타낸다.
  • 전혀 감성적이지 않은 단어의 객관성 지수는 1이다.
  • SentiWordNet을 이용하기 위해샤는 WordNet을 이용해 문서를 단어로 토큰화한 뒤 어근 추출과 품사 태깅을 적용해야 한다.
  • nltk.corpus.sentiwordnet

 

2) VADER

  • 주로 소셜 미디어의 텍스트에 대한 감성 분석을 제공하기 위한 패키지
  • 뛰어난 감성 분석 결과를 제공하며, 비교적 빠른 수행 시간을 보장한다.
  • nltk.sentiment.vader.SetimentIntensityAnalyzer

 

3) Pattern

  • 예측 성능 측면에서 가장 주목받는 패키지.
  • 하지만 파이썬 2.X에서만 동작한다.

 

 


 

토픽 모델링 (문서 요약)

  • 문서 집합에 숨어있는 주제를 찾아내는 것
  • 머신러닝 기반의 토픽 모델링은 숨어있는 중요 주제를 효과적으로 찾아낼 수 있다.
  • 토픽 모델은 숨겨진 주제를 효과적으로 표현 가능한 중심 단어를 함축적으로 추출한다.
  • 토픽 모델링에는 LSA와 LSD 기법이 자주 활용된다.

 

 

사이킷 런에서의 LDA(Latent Dirchlet Allocation)

  • sklearn.decomposition.LatentDirichletAllocation
  • Count 기반의 벡터화를 사용한다.

*n_components : 결과값 클래스

*LDA는 반환값으로 객체를 생성하는데, components_ 속성값을 가지고 있다.

*components_ 속성은 개별 토픽별로 각 word 피처가 얼마나 많이 그 토픽에 할당됐는지에 대한 수치를 가지고 있다.

 

 


문서 군집화

  • 비슷한 텍스트 구성의 문서를 군집화한다.
  • 텍스트 분류와 유사한데, 텍스트 분류 기반의 문서 분류는 사전에 결정 카테고리 값을 가진 학습 데이터를 활용한다. 
  • 그에 비해 문서 군집화는 비지도 학습 기반이다.
  • 별도의 클래스와 함수가 존재하는 것은 아니고, 전처리하여 토큰화된 문서들을 기존의 KMeans 와 같은 군집화 알고리즘으로 군집한다.

 

 


문서 유사도 (코사인 유사도)

  • 문서와 문서간 유사도는 일반적으로 코사인 유사도를 사용한다.
  • 코사인 유사도는 벡터의 유사도를 비교할 때 벡터의 크기보다 벡터의 상호 방향성의 유사성을 중시한다.
  • 즉 코사인 유사도는 두 벡터 사이의 사잇각을 구해 얼마나 유사한지 수치로 적용한 것이다.

 

 

왜 코사인 유사도인가?

  • 문서를 피처 벡터로 변환하면 희소 행렬이 되기 쉽다.
  • 희소 행렬 기반에서 문서와 문서 벡터간의 크기에 기반한 유사도 (유클리드 거리 기반)는 정확도가 떨어지기 쉽다.
  • 그래서 크기보다 상호 방향성의 유사성에 기반한 코사인 유사도로 확인한다.

 

 

사이킷 런의 코사인 유사도

  • sklearn.metrics.pairwise.cosine_similarity
  • 희소 행렬, 밀집 행렬 모두 가능하며, 행렬이나 배열 또한 가능하다.
  • 별도의 변환 작업 없이 그냥 바로 넣어도 된다.

*입력 파라미터는 문서 두 개인데, 문서의 배열을 두 개 넣어도 된다.

*배열로 넣을 경우 서로 비교해서 비교도를 행렬로 반환.

 

 

 


한글 텍스트 처리

 

한글 텍스트 처리가 어려운 이유

1) 띄어쓰기의 문제

  • 띄어쓰기가 잘못 사용되면 의미가 왜곡되기 쉽다.
  • 참고로 한글의 띄어쓰기는 고등교육을 받은 사람들도 종종 틀릴 정도로 어렵다.

2) 조사의 문제

  • 조사의 경우의 수가 너무 많아 어근 추출 시 제거하기가 까다롭다.

 

 

파이썬에서의 한글 NLP

  • KoNLPy를 사용한다.
  • KoNLPy는 대표적인 한글 형태소 패키지이다.
  • 말뭉치를 어근 단위로 쪼개 각 형태소에 품사 태깅을 부착하는 형태소 분석 작업을 지원한다.
  • C/C++/JAVA로 만들어진 한글 형태소에 파이썬 래퍼를 기반으로 재작성한 패키지이다.
  • 꼬꼬마, 한나눔, Komoran, Mecab, Twitter 같은 형태소 분석 모듈을 사용할 수 있다.

*형태소 : 단어로서 의미를 가지는 최소 단위

*Mecab의 경우에는 윈도우에서 사용이 불가능함을 주의.

 


실습코드 : https://github.com/123okk2/MachineLearning_practice/tree/main/8.%20%ED%85%8D%EC%8A%A4%ED%8A%B8%20%EB%B6%84%EC%84%9D

728x90
반응형

'IT 도서 > 파이썬 머신러닝' 카테고리의 다른 글

9. 추천 시스템  (0) 2021.02.15
7. 군집화  (0) 2021.02.10
6. 차원 축소  (0) 2021.02.09
5. 회귀  (0) 2021.02.08
4. 분류  (0) 2021.02.08