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 클래스를 리스트 형태로 반환
- 문서를 문장 단위로 분해
- 다시 문장을 단어 단위로 토큰화하고 품사 태깅
- 품사 태깅된 단어 기반으로 synset 객체와 senti_synset 객체를 생성
- senti_synset 객체에서 긍정 감성/ 부정 감성 지수를 구하고 이를 모두 합산해 특정 임계치 값 이상일 때 긍정 감성으로, 그렇지 않을 때는 부정 감성으로 결정
VADER를 이용한 감성 분석
- VADER : 소셜 미디어의 감성 분석 용도로 만들어진 룰 기반의 Lexicon
- Polarity_scores() : 감정 점수를 구한 뒤, 해당 감성 점수가 특정 임계값 이상이면 긍정, 또는 부정으로 판단
- vader_polarity() : 텍스트와 임곗값을 파라미터로 가지고 polarity_scores() 메서드를 호출해 감성 결과를 반환
- 비지도학습은 지도학습 기반의 예측 성능에 비해 낮은 수준이지만, 결정 클래스 값이 없는 경우에 사용
06 토픽 모델링 - 20 뉴스그룹
토픽 모델링
- 문서 집합에 숨어 있는 주제를 찾아내는 것
- 숨겨진 주제를 효과적으로 표현할 수 있는 중심 단어를 함축적으로 추출
- LSA (Latent Semantic Analysis) : 문서와 단어의 잠재적인 의미를 발견하려는 방법. 특이값 분해라는 기법을 활용하여 문서-단어 행렬을 분해하고 다시 조합하여 문서의 잠재적인 주제를 찾아 냄
- LDA (Latent Dircihlet Allocation) : 각 문서에서 토픽의 분포와 각 토픽 내에서 단어의 분포를 추정하는 확률적 생성 모델. 각 문서가 여러 토픽들의 혼합으로 구성되어 있으며, 각 토픽은 확률 분포에 따라 단어를 생성한다는 가정하에 작동
07 문서 군집화 소개와 실습
문서 군집화 : 비슷한 텍스트 구성의 문서를 군집화하는 것, 비지도학습 기반
Opinion Review 데이터 세트를 이용한 문서 군집화
- Data Import
- TF-IDF 시행 : TfidfVectorizer에 Lemmatization 기능 추가를 위해 tokenizer에 커스텀 어근변환 함수 LemNormalize() 함수 생성
- k-means clustering : 5개, 3개 등 파라미터를 바꾸며 군집화가 어떻게 되었는지 확인
- 군집별 핵심 단어 추출하기
군집별 핵심 단어 추출하기
- 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 : 파이썬의 대표적인 한글 형태소 패키지