Spaces:
Sleeping
Sleeping
File size: 6,015 Bytes
bd97f47 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
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 |