Spaces:
Sleeping
Sleeping
| import numpy as np | |
| from transformers import pipeline | |
| import torch | |
| import logging | |
| import re | |
| from sklearn.feature_extraction.text import CountVectorizer | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| class QualityScorer: | |
| def __init__(self, quality_pipeline=None): | |
| """ | |
| Metin kalitesi değerlendirme sınıfını başlatır. | |
| Args: | |
| quality_pipeline: Metin özetleme pipeline'ı | |
| """ | |
| self.pipeline = quality_pipeline | |
| self.device = "cuda" if torch.cuda.is_available() else "cpu" | |
| # Temel kalite ölçütleri için yardımcı araçlar | |
| self.vectorizer = CountVectorizer(max_features=5000) | |
| # Türkçeye özgü doldurma (filler) kelimeleri | |
| self.turkish_filler_words = [ | |
| 'yani', 'işte', 'şey', 'falan', 'filan', 'hani', 'mesela', 'aslında', | |
| 'ya', 'ki', 'de', 'da', 'çok', 'ama', 'fakat', 'lakin', 'ancak', | |
| 'gerçekten', 'kesinlikle', 'tabii', 'tabi', 'şimdi', 'sonra', 'önce' | |
| ] | |
| def score_text(self, text): | |
| """ | |
| Metin için kalite skoru hesaplar. | |
| Args: | |
| text: Değerlendirilecek metin | |
| Returns: | |
| float: 0 ile 1 arasında kalite skoru (1 = yüksek kalite) | |
| """ | |
| if not text or len(text.strip()) == 0: | |
| return 0.0, {} | |
| # Metni temizle | |
| text = text.strip() | |
| # Çeşitli metin özelliklerini değerlendirelim | |
| features = {} | |
| # 1. Uzunluk puanı - Çok kısa veya çok uzun metinler düşük puan alır | |
| length = len(text.split()) | |
| if length < 3: | |
| features['length_score'] = 0.1 | |
| elif length < 5: | |
| features['length_score'] = 0.2 | |
| elif length < 10: | |
| features['length_score'] = 0.4 | |
| elif length < 20: | |
| features['length_score'] = 0.6 | |
| elif length < 100: | |
| features['length_score'] = 0.8 | |
| elif length < 500: | |
| features['length_score'] = 1.0 | |
| elif length < 1000: | |
| features['length_score'] = 0.8 | |
| else: | |
| features['length_score'] = 0.6 | |
| # 2. Gramer ve yazım denetimi (Türkçe için uyarlanmış) | |
| # Türkçede noktalama işaretleri ve büyük harf kullanımı | |
| sentences = re.split(r'[.!?]+', text) | |
| sentences = [s.strip() for s in sentences if s.strip()] | |
| if not sentences: | |
| features['grammar_score'] = 0.0 | |
| else: | |
| # Cümlelerin büyük harfle başlayıp başlamadığını kontrol et | |
| correct_caps = sum(1 for s in sentences if s and s[0].isupper()) | |
| caps_ratio = correct_caps / len(sentences) if sentences else 0 | |
| # Noktalama işaretlerinin varlığını kontrol et | |
| punct_count = len(re.findall(r'[.!?,;:]', text)) | |
| expected_punct = max(1, len(sentences) - 1) # Beklenen minimum noktalama | |
| punct_ratio = min(1.0, punct_count / expected_punct) if expected_punct > 0 else 0 | |
| # Türkçe'ye özgü yaygın yazım hatalarını kontrol et | |
| common_errors = [ | |
| ('de da', 'de/da ayrı yazılmalı'), | |
| ('ki', 'ki bağlacı ayrı yazılmalı'), | |
| ('misin', 'soru eki ayrı yazılmalı'), | |
| ('geldimi', 'soru eki ayrı yazılmalı'), | |
| ('bişey', 'bir şey ayrı yazılmalı'), | |
| ('herşey', 'her şey ayrı yazılmalı'), | |
| ('hiçbirşey', 'hiçbir şey ayrı yazılmalı') | |
| ] | |
| error_count = sum(1 for error, _ in common_errors if error in text.lower()) | |
| error_ratio = 1.0 - min(1.0, error_count / (len(text.split()) / 10 + 1)) | |
| # Gramer puanını hesapla | |
| features['grammar_score'] = (caps_ratio * 0.4 + punct_ratio * 0.3 + error_ratio * 0.3) | |
| # 3. Kelime çeşitliliği (Türkçe için uyarlanmış) | |
| words = re.findall(r'\b\w+\b', text.lower()) | |
| unique_words = set(words) | |
| if not words: | |
| features['diversity_score'] = 0.0 | |
| else: | |
| # Türkçe metinler için çeşitlilik oranını ayarla | |
| diversity_ratio = len(unique_words) / len(words) | |
| # Türkçe'nin çekimli yapısı nedeniyle daha yüksek bir baz çeşitlilik beklenir | |
| features['diversity_score'] = min(1.0, diversity_ratio * 1.2) | |
| # 4. Özetlenebilirlik puanı - eğer pipeline varsa | |
| if self.pipeline and len(text.split()) > 20: | |
| try: | |
| # Pipeline özetleme mi yoksa çeviri mi ona göre işle | |
| if hasattr(self.pipeline, 'task') and self.pipeline.task == 'translation': | |
| # Çeviri pipeline'ı, bu durumda çevirinin kalitesine bakma | |
| translated = self.pipeline(text, max_length=100)[0]['translation_text'] | |
| features['summary_score'] = 0.7 # Varsayılan olarak iyi bir puan | |
| else: | |
| # Özetleme pipeline'ı | |
| max_length = min(128, max(30, len(text.split()) // 4)) | |
| summary = self.pipeline(text, max_length=max_length, min_length=10, do_sample=False)[0][ | |
| 'generated_text'] | |
| # Özet ve orijinal metin arasındaki benzerliğe bakarak puan ver | |
| summary_len = len(summary.split()) | |
| orig_len = len(text.split()) | |
| compression_ratio = summary_len / orig_len if orig_len > 0 else 0 | |
| if compression_ratio > 0.8 or compression_ratio < 0.05: | |
| features['summary_score'] = 0.3 | |
| elif compression_ratio > 0.6 or compression_ratio < 0.1: | |
| features['summary_score'] = 0.6 | |
| else: | |
| features['summary_score'] = 0.9 | |
| except Exception as e: | |
| logging.warning(f"Error during summarization: {str(e)}") | |
| features['summary_score'] = 0.5 | |
| else: | |
| features['summary_score'] = 0.5 | |
| # 5. Türkçe doldurma kelimeleri (filler words) | |
| filler_count = sum(1 for word in words if word.lower() in self.turkish_filler_words) | |
| if not words: | |
| features['filler_score'] = 1.0 | |
| else: | |
| filler_ratio = filler_count / len(words) | |
| # Türkçede bazı doldurma kelimeleri doğal olabilir, bu yüzden daha toleranslı davran | |
| features['filler_score'] = 1.0 - min(1.0, filler_ratio * 3) | |
| # Puanları birleştir - farklı puanları ağırlıklandırarak | |
| weights = { | |
| 'length_score': 0.15, | |
| 'grammar_score': 0.3, # Türkçe için gramere daha fazla ağırlık | |
| 'diversity_score': 0.25, | |
| 'summary_score': 0.2, | |
| 'filler_score': 0.1 | |
| } | |
| final_score = sum(features[key] * weights[key] for key in weights.keys()) | |
| # Puanı 0-1 aralığına normalize et | |
| final_score = max(0.0, min(1.0, final_score)) | |
| return final_score, features | |
| def batch_score(self, texts, batch_size=8): | |
| """ | |
| Bir metin listesi için toplu kalite skoru hesaplar. | |
| Args: | |
| texts: Değerlendirilecek metin listesi | |
| batch_size: İşlenecek grup boyutu | |
| Returns: | |
| list: Kalite skorları listesi | |
| """ | |
| results = [] | |
| feature_results = [] | |
| for i in range(0, len(texts), batch_size): | |
| batch_texts = texts[i:i + batch_size] | |
| batch_results = [] | |
| batch_features = [] | |
| for text in batch_texts: | |
| score, features = self.score_text(text) | |
| batch_results.append(score) | |
| batch_features.append(features) | |
| results.extend(batch_results) | |
| feature_results.extend(batch_features) | |
| return results, feature_results |