AIchemist

[10주차] 텍스트 분석 (2)

양윤서_Ewha 2024. 11. 25. 01:27

05 감성 분석

감성 분석(Sentiment Analysis)

  • 주관적인 감성/의견/감정/기분 등을 파악하기 위한 방법
  • 소셜 미디어, 여론조사, 온라인 리뷰, 피드백 등
  • 문서 내 텍스트가 나타내는 주관적 단어와 문맥을 기반으로 감성 수치를 계산하는 방법
  • 긍정 감성 지수 / 부정 감성 지수
지도 학습 비지도 학습
감성 분석 학습을 수행한 뒤 이를 기반으로 다른 데이터의 감성 분석을 예측
일반적인 텍스트 기반의 분류와 거의 동일
Lexicon이라는 감성 어휘 사전 이용
용어와 문맥에 대한 다양한 정보를 가지고 있음

 

지도학습 기반 감성 분석 실습 - IMDB 영화평

데이터의 피처

  • id : 각 데이터의 id
  • sentiment : 영화평의 Sentiment 결과 값. 1은 긍정, 0은 부정. target 데이터이다.
  • review : 영화평의 텍스트

HTML  형식에서 추출한 데이터에는 <br /> 태그가 존재하기 때문에 str 속성을 이용해 제거한다.

숫자와 특수문자도 파이썬의 re 모듈을 이용한 정규 표현식([^a-zA-Z] : 영어 대/소문자가 아닌 모든 문자)을 통해 공백으로 변경한다. 

import re
#<br> html 태그는 replace 함수로 공백으로 변환
review_df['review'] = review_df['review'].str.replace('<br />', ' ')

#re를 이용해 영어 문자열이 아닌 문자는 모두 공백으로 변환
review_df['review'] = review_df['review'].apply(lambda x : re.sub("[^a-zA-Z]", " ", x))

결정 값 클래스인 sentiment 칼럼을 별도 추출해 결정 값 데이터 세트 생성 - 원본 데이터 세트에서 id와 sentiment 칼럼을 삭제해 피처 데이터 세트 생성 - train_test_split() 이용

피처 벡터화와 ML 분류 알고리즘

Count 벡터화 : Classifier는 LogisticRegression을 이용

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, roc_auc_score

# 스톱 워드는 English, filtering, ngram은 (1,2)로 설정해 CountVectorization수행. 
# LogisticRegression의 C는 10으로 설정. 
pipeline = Pipeline([
    ('cnt_vect', CountVectorizer(stop_words='english', ngram_range=(1,2) )),
    ('lr_clf', LogisticRegression(solver='liblinear', C=10))])

# Pipeline 객체를 이용하여 fit(), predict()로 학습/예측 수행. predict_proba()는 roc_auc때문에 수행.  
pipeline.fit(X_train['review'], y_train)
pred = pipeline.predict(X_test['review'])
pred_probs = pipeline.predict_proba(X_test['review'])[:,1]

TF_IDF 벡터화 : CountVectorizer 를 TfidfVectorizer로 변경, 예측 성능이 더 좋음

pipeline = Pipeline([
    ('tfidf_vect', TfidfVectorizer(stop_words='english', ngram_range=(1,2) )),
    ('lr_clf', LogisticRegression(solver='liblinear', C=10))])

 

비지도학습 기반 감성 분석

  • 감성사전 Lexicon을 이용해 감성 지수(Polarity score) 표시
  • NLTK 패키지의 WordNet 모듈 : 문맥상 의미 분석을 제공하는 어휘 사전. Synset이라는 개념을 이용해 개별 단어를 표현. 그 단어가 가지는 문맥 정보를 제공하는 핵심 개념임.

대표적인 감성 사전

SentiWordNet 감성 단어 전용의 WordNet 구현
WordNet의 Synset 별로 3가지 감성 점수를 할당 (긍정/부정/객관적 감정 지수)
VADER 주로 소셜미디어 텍스트에 대한 감성 분석을 제공하기 위한 패키지
Pattern 예측 성능 측면에서 가장 주목받는 패키

 

SentiWordNet을 이용한 감성 분석

  • synsets() : 지정된 단어에 대해 WordNet에 등재된 모든 Synset 객체를 반환 (리스트)
  • Synset은 POS(품사), 정의, 부명체(Lemma) 등으로 시맨틱적인 요소를 표현함
  • 하나의 단어가 가질 수 있는 여러 가지 시맨틱 정보를 개별 클래스로 나타낸 것
  • path_similarity() : 단어 간의 유사도를 나타내는 메서드
  • senti_synsets() : Senti_Synset 클래스를 리스트 형태로 반환
  1. 문서를 문장 단위로 분해
  2. 다시 문장을 단어 단위로 토큰화하고 품사 태깅
  3. 품사 태깅된 단어 기반으로 synset 객체와 senti_synset 객체를 생성
  4. senti_synset 객체에서 긍정 감성/ 부정 감성 지수를 구하고 이를 모두 합산해 특정 임계치 값 이상일 때 긍정 감성으로, 그렇지 않을 때는 부정 감성으로 결정

 

VADER를 이용한 감성 분석

  • VADER : 소셜 미디어의 감성 분석 용도로 만들어진 룰 기반의 Lexicon
  • Polarity_scores() : 감정 점수를 구한 뒤, 해당 감성 점수가 특정 임계값 이상이면 긍정, 또는 부정으로 판단
  • vader_polarity() : 텍스트와 임곗값을 파라미터로 가지고 polarity_scores() 메서드를 호출해 감성 결과를 반환
  • 비지도학습은 지도학습 기반의 예측 성능에 비해 낮은 수준이지만, 결정 클래스 값이 없는 경우에 사용

 

06 토픽 모델링 - 20 뉴스그룹

토픽 모델링

  • 문서 집합에 숨어 있는 주제를 찾아내는 것
  • 숨겨진 주제를 효과적으로 표현할 수 있는 중심 단어를 함축적으로 추출
  • LSA (Latent Semantic Analysis) : 문서와 단어의 잠재적인 의미를 발견하려는 방법. 특이값 분해라는 기법을 활용하여 문서-단어 행렬을 분해하고 다시 조합하여 문서의 잠재적인 주제를 찾아 냄
  • LDA (Latent Dircihlet Allocation) : 각 문서에서 토픽의 분포와 각 토픽 내에서 단어의 분포를 추정하는 확률적 생성 모델. 각 문서가 여러 토픽들의 혼합으로 구성되어 있으며, 각 토픽은 확률 분포에 따라 단어를 생성한다는 가정하에 작동

 

07 문서 군집화 소개와 실습

문서 군집화 : 비슷한 텍스트 구성의 문서를 군집화하는 것, 비지도학습 기반

Opinion Review 데이터 세트를 이용한 문서 군집화

  1. Data Import
  2. TF-IDF 시행 : TfidfVectorizer에 Lemmatization 기능 추가를 위해 tokenizer에 커스텀 어근변환 함수 LemNormalize() 함수 생성
  3. k-means clustering : 5개, 3개 등 파라미터를 바꾸며 군집화가 어떻게 되었는지 확인
  4. 군집별 핵심 단어 추출하기

군집별 핵심 단어 추출하기

  • clusters_centers_ : 각 군집을 구성하는 단어 피처가 군집의 중심을 기준으로 얼마나 가깝게 위치해 있는지 나타냄
  • get_cluster_details() : cluster_centers_ 배열 내에서 가장 값이 큰 데이터의 위치 인덱스를 추출한 뒤, 해당 인덱스를 이용해 핵심 단어 이름과 그때의 상대 위치 값을 추출
  • cluster_details : 개별 군집번호, 핵심 단어, 핵심단어 중심 위치 상댓값, 파일명 속성 값

 

08 문서 유사도

코사인 유사도

  • 벡터와 벡터 간의 유사도를 비교할 때 벡터의 상호 방향성이 얼마나 유사한지에 기반
  • 두 벡터의 내적을 총 벡터 크기의 합으로 나눈 것
  • 희소 행렬 기반에서 문서 벡터 간의 크기에 기반한 유사도 지표는 정확도가 떨어지기 쉬움 > 빈도수에만 기반해서는 공정한 비교를 할 수 없음
  • cos_similarity() : 두 개의 넘파이 배열에 대한 코사인 유사도를 구하는 함수
  • sklearn.metrics.pairwise.cosine_similarity API : 사이킷런이 제공하는 API, 희소 행렬과 밀집 행렬 모두 가능하며 별도의 변환 작업이 필요 없음
import numpy as np

def cos_similarity(v1, v2):
    dot_product = np.dot(v1, v2)
    l2_norm = (np.sqrt(sum(np.square(v1))) * np.sqrt(sum(np.square(v2))))
    similarity = dot_product / l2_norm     
    
    return similarity

 

09 한글 텍스트 처리

한글 NLP 처리의 어려움

  • 띄어쓰기 : 의미가 왜곡되어 전달될 수 있음
  • 다양한 조사 : 경우의 수가 많아서 어근 추출 등의 전처리로 제거하기가 까다로
  • KoNLPy : 파이썬의 대표적인 한글 형태소 패키지