textqualtox / utils /sentiment_analyzer.py
sarizeybekk
Remove venv from Git tracking and add to .gitignore
bd97f47
Raw History Blame Contribute Delete
6.02 kB
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import numpy as np
import logging
logger = logging.getLogger(__name__)
class SentimentAnalyzer:
"""
Türkçe metinler için duygu analizi yapan sınıf.
Pozitif, negatif ve nötr duygu skorları üreterek metnin duygusal tonunu analiz eder.
"""
def __init__(self, model=None, tokenizer=None):
"""
Duygu analizi modülünü başlatır.
Args:
model: Duygu analizi modeli (isteğe bağlı)
tokenizer: Model için tokenizer (isteğe bağlı)
"""
self.model = model
self.tokenizer = tokenizer
self.device = "cuda" if torch.cuda.is_available() else "cpu"
self.model_info = {"name": "Bilinmeyen Model", "language": "unknown"}
if model is None or tokenizer is None:
logger.info("Duygu analizi için varsayılan model yükleniyor...")
self.load_default_model()
def load_default_model(self):
"""Varsayılan duygu analizi modelini yükler"""
try:
# Türkçe duygu analizi modeli
model_name = "savasy/bert-base-turkish-sentiment"
logger.info(f"Türkçe duygu analizi modeli yükleniyor: {model_name}")
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModelForSequenceClassification.from_pretrained(model_name)
self.model.to(self.device)
self.model_info = {
"name": model_name,
"description": "Türkçe duygu analizi modeli",
"language": "tr"
}
logger.info("Duygu analizi modeli başarıyla yüklendi")
return True
except Exception as e:
logger.error(f"Duygu analizi modeli yüklenemedi: {str(e)}")
# Yedek model dene
try:
backup_model = "dbmdz/bert-base-turkish-cased"
logger.info(f"Yedek Türkçe model deneniyor: {backup_model}")
self.tokenizer = AutoTokenizer.from_pretrained(backup_model)
self.model = AutoModelForSequenceClassification.from_pretrained(backup_model)
self.model.to(self.device)
self.model_info = {
"name": backup_model,
"description": "Genel amaçlı Türkçe BERT modeli",
"language": "tr"
}
logger.info("Yedek model başarıyla yüklendi")
return True
except Exception as e2:
logger.error(f"Yedek model yüklenemedi: {str(e2)}")
raise e2
def analyze_sentiment(self, text):
"""
Metindeki duygu tonunu analiz eder.
Args:
text: Analiz edilecek metin
Returns:
dict: {
'positive': float, # Pozitif duygu skoru (0-1)
'neutral': float, # Nötr duygu skoru (0-1)
'negative': float, # Negatif duygu skoru (0-1)
'dominant': str # Baskın duygu (positive, neutral, negative)
'score': float # -1 (çok negatif) ile 1 (çok pozitif) arasında genel skor
}
"""
if not text or len(text.strip()) == 0:
return {
'positive': 0.0,
'neutral': 1.0,
'negative': 0.0,
'dominant': 'neutral',
'score': 0.0
}
try:
# Metni tokenize et
inputs = self.tokenizer(text, return_tensors="pt", truncation=True, max_length=512)
inputs = {key: val.to(self.device) for key, val in inputs.items()}
# Tahmin yap
with torch.no_grad():
outputs = self.model(**inputs)
# Sonuçları işle
logits = outputs.logits
probabilities = torch.softmax(logits, dim=1).cpu().numpy()[0]
# Model çıktısının formatına göre işlem yap
if len(probabilities) >= 3:
# 3 sınıflı model (negatif, nötr, pozitif)
result = {
'negative': float(probabilities[0]),
'neutral': float(probabilities[1]),
'positive': float(probabilities[2])
}
else:
# 2 sınıflı model (negatif, pozitif)
result = {
'negative': float(probabilities[0]),
'neutral': 0.0,
'positive': float(probabilities[1])
}
# Baskın duyguyu belirle
dominant_sentiment = max(result, key=result.get)
result['dominant'] = dominant_sentiment
# -1 ile 1 arasında genel bir skor hesapla
# -1: çok negatif, 0: nötr, 1: çok pozitif
weighted_score = result['positive'] - result['negative']
result['score'] = float(weighted_score)
return result
except Exception as e:
logger.error(f"Duygu analizi sırasında hata: {str(e)}")
# Hata durumunda nötr sonuç döndür
return {
'positive': 0.0,
'neutral': 1.0,
'negative': 0.0,
'dominant': 'neutral',
'score': 0.0
}
def batch_analyze(self, texts, batch_size=8):
"""
Bir metin listesi için toplu duygu analizi yapar.
Args:
texts: Analiz edilecek metin listesi
batch_size: İşlenecek grup boyutu
Returns:
list: Her metin için duygu analizi sonuçları
"""
results = []
for i in range(0, len(texts), batch_size):
batch_texts = texts[i:i + batch_size]
batch_results = [self.analyze_sentiment(text) for text in batch_texts]
results.extend(batch_results)
return results