Spaces:
Running
Running
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 |