이번에 인사이드아웃 2가 새로 개봉되었다. 그래서 오늘 포스팅은 감정에 대해서 얘기해보려고 한다. NLP Task 중 하나인 감정분석.
컴퓨터가 인간의 언어, 자연어를 이해하기 시작하면서 필요로 되는 능력 중 하나는 감정분석이다. 제품 혹은 서비스에 대한 리뷰, 피드백 등이 수백만 가지 이상의 데이터일텐데 이를 하나하나 확인하고 조사하는 것은 매우 비효율적이며 할 수 있는 일인지조차 모르겠다. 여기서 감정분석은 사용자의 의견, 리뷰, 피드백 등에서 인간의 감정을 파악해 기업이나 개발자가 소비자의 반응을 빠르고 정확하게 이해하고 서비스나 제품을 개선할 수 있도록 돕는다. 이러한 시장 동향 파악, 비즈니스 의사결정 과정에서 중요한 역할을 한다.
감정분석 Task에 적합한 언어 모델
많은 언어 모델이 감정분석 Task에 적합하지만 이번 포스팅에서는 BERT에 대해 간략히 설명만 하고 넘어가려고 한다.
BERT 모델은 Deep Bidirectional Model로 양방향 학습이 가능해 문장의 깊은 의미를 탐구, 이해할 수 있다는 점이 장점이자 특징이다. 이러한 모델 특성때문에 생성 Task(텍스트 요약, 기계 번역 등)에는 적합하지 않을 수 있다. 하지만 감정분석 Task에는 그만큼 유리하게 적용될 수 있다.
위 그림은 BERT 논문 리뷰에서 소개한 BERT 모델의 Fine-tuning 부분 이미지이다. 1번 그림처럼 마지막에 CLS Token을 배출하는데 이를 가지고 우리는 감정분석 Task에 적용할 수 있다. 필자가 이해한대로라면 긍정 / 부정 / 중립 등으로 간략하게 나누는 작업은 감성분석이라 부르고 슬픔 / 기쁨 / 우울함 등 여러 감정까지 잡아내는 것이 감정분석이다.
응용 분야
1) SNS 감정 분석
SNS에서의 감정 분석은 기업이 소비자의 감정과 태도를 실시간으로 모니터링하여 브랜드 인식과 제품 개발에 직접적으로 반영할 수 있게 한다. 예를 들어, 특정 제품 또는 캠페인에 대한 고객의 반응을 분석하여 마케팅 전략을 조정하고, 소비자 선호도에 맞춘 제품을 제공할 수 있다. 또한, 소셜 미디어 상에서의 감정 추세를 분석함으로써, 경쟁사 대비 강점과 약점을 파악하고 시장 내 위치를 강화할 수 있다. 이러한 분석은 특히 급변하는 소비자 트렌드와 공공의 관심사가 중요한 소셜 미디어 플랫폼에서 매우 유용할 수 있다.
2) 고객 서비스 개선을 위한 감정 분석
고객 서비스 분야에서 감정 분석은 고객의 피드백과 문의사항에서 감정을 식별하고 이를 바탕으로 서비스 개선을 도모한다. 예를 들어, 고객 서비스 대화 기록을 분석하여 고객의 불만 사항을 자동으로 식별하고, 그 원인을 분석하여 더 효과적인 해결책을 제시할 수 있다. 이는 고객 만족도를 높이고, 잠재적인 문제를 미리 식별하여 대응할 수 있는 능력을 향상시키고 고객 지원 팀의 대응 전략을 최적화하여, 감정적으로 민감한 고객의 요구에 더 잘 대응할 수 있는 시스템을 구축할 수 있다.
3) 금융 분야에서의 감정 분석 활용
금융 서비스 분야에서 감정 분석은 시장 분석, 투자자 감정 추적, 그리고 리스크 관리에 중요한 역할을 한다. 투자자들의 소셜 미디어 포스트나 뉴스 기사에서 감정을 분석하여 시장의 감정적 변동을 예측하고, 이를 통해 시장 동향을 이해할 수 있다. 예를 들어, 대중의 감정이 긍정적일 때 시장에 투자를 확대하고, 부정적인 감정이 우세할 때는 보수적인 투자 전략을 취할 수 있다. 이런 분석은 투자 결정 과정에서 중요한 참고 자료가 되며, 금융 위기를 예방하는 데에도 기여할 수 있다.
간단한 코드 실습
코드 실습이 없으면 너무 경영 블로그 같아 보이는 건 병인가보다. 하지만 필자는 이러한 병에 걸렸기 때문에 간단하게라도 코드 실습을 담아보려고 한다. 보통 감정 분석을 네이버 영화 리뷰 혹은 네이버 쇼핑 리뷰 등 데이터를 수집한 후 많이 진행한다. 필자는 정말 간단한 text 예시만으로 코드를 작성하였다.
import torch
from torch.utils.data import Dataset, DataLoader
from transformers import BertTokenizer, BertForSequenceClassification, AdamW
class SentimentDataset(Dataset):
def __init__(self, texts, labels, tokenizer):
self.encodings = tokenizer(texts, truncation=True, padding=True, max_length=128)
self.labels = labels
def __getitem__(self, idx):
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
item['labels'] = torch.tensor(self.labels[idx])
return item
def __len__(self):
return len(self.labels)
# 데이터 및 레이블
texts = ["I love this product!", "I hate this product!", "It's okay, not great but not bad."]
labels = [1, 0, 2] # 1: 긍정, 0: 부정, 2: 중립
# 토크나이저 및 데이터셋 초기화
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
dataset = SentimentDataset(texts, labels, tokenizer)
# 데이터 로더 설정
loader = DataLoader(dataset, batch_size=2, shuffle=True)
# 모델 로드 및 미세 조정 설정
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=3)
model.train()
# 옵티마이저 및 손실 함수 설정
optimizer = AdamW(model.parameters(), lr=1e-5)
# 학습
for epoch in range(3): # 에폭 수는 필요에 따라 조정 가능
for batch in loader:
optimizer.zero_grad()
input_ids = batch['input_ids']
attention_mask = batch['attention_mask']
labels = batch['labels']
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
loss = outputs.loss
loss.backward()
optimizer.step()
print(f"Epoch {epoch}, Loss: {loss.item()}")
# 평가 모드 전환
model.eval()
# 예측
with torch.no_grad():
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
outputs = model(**inputs)
predictions = torch.argmax(outputs.logits, dim=-1)
print(predictions) # 수정된 모델의 예측 출력
'NLP' 카테고리의 다른 글
[NLP] Transformer의 함수 model.generate() 파라미터 (3) | 2024.11.25 |
---|---|
[NLP] LLM Prompt Engineering (4) | 2024.11.19 |
[NLP] Korean LLM Leaderboard (3) | 2024.10.16 |
[NLP] Survey of Chatbot, Persona (7) | 2024.09.04 |
[NLP] Similarity, 문서 유사도 측정 (0) | 2024.07.06 |
[NLP] Text Data Preprocessing (0) | 2024.07.02 |
[NLP] 정규 표현식, Regular Expression (0) | 2024.07.01 |
[NLP] API를 활용한 Web Crawling (0) | 2024.06.29 |