Spaces:
Sleeping
Sleeping
| import re | |
| from collections import Counter | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| class LanguageDetector: | |
| """ | |
| Metin dilini algılayan sınıf. | |
| İstatistiksel yöntemlerle metinlerin dilini tespit eder. | |
| """ | |
| def __init__(self): | |
| """Dil algılama sınıfını başlatır""" | |
| # Dil tanıma için tipik karakter ve kelime varlıkları | |
| self.language_profiles = { | |
| 'tr': { | |
| 'chars': 'abcçdefgğhıijklmnoöprsştuüvyz', | |
| 'unique_chars': 'çğıöşü', | |
| 'common_words': [ | |
| 've', 'bir', 'bu', 'da', 'de', 'için', 'ile', 'ben', 'sen', 'o', | |
| 'biz', 'siz', 'ama', 'ki', 'ya', 'çok', 'daha', 'en', 'ne', 'kadar', | |
| 'var', 'yok', 'mı', 'mi', 'mu', 'mü', 'gibi', 'olarak', 'çünkü', | |
| 'sonra', 'önce', 'nasıl', 'neden', 'evet', 'hayır', 'ise', 'veya' | |
| ] | |
| }, | |
| 'en': { | |
| 'chars': 'abcdefghijklmnopqrstuvwxyz', | |
| 'unique_chars': 'qwxz', | |
| 'common_words': [ | |
| 'the', 'and', 'a', 'to', 'of', 'in', 'is', 'you', 'that', 'it', | |
| 'he', 'was', 'for', 'on', 'are', 'as', 'with', 'his', 'they', | |
| 'at', 'be', 'this', 'have', 'from', 'or', 'one', 'had', 'by', | |
| 'but', 'not', 'what', 'all', 'were', 'we', 'when', 'your', 'can', | |
| 'there', 'if', 'more', 'an', 'who' | |
| ] | |
| }, | |
| 'de': { | |
| 'chars': 'abcdefghijklmnopqrstuvwxyzäöüß', | |
| 'unique_chars': 'äöüß', | |
| 'common_words': [ | |
| 'der', 'die', 'das', 'und', 'in', 'zu', 'den', 'mit', 'auf', 'für', | |
| 'ist', 'im', 'dem', 'nicht', 'ein', 'eine', 'als', 'auch', 'es', | |
| 'von', 'sich', 'oder', 'so', 'zum', 'bei', 'eines', 'nur', 'am', | |
| 'werden', 'noch', 'wie', 'einer', 'aber', 'aus', 'wenn', 'doch' | |
| ] | |
| }, | |
| 'fr': { | |
| 'chars': 'abcdefghijklmnopqrstuvwxyzàâçéèêëîïôùûü', | |
| 'unique_chars': 'àâçéèêëîïôùûü', | |
| 'common_words': [ | |
| 'le', 'la', 'les', 'de', 'des', 'un', 'une', 'et', 'est', 'en', | |
| 'du', 'dans', 'qui', 'que', 'pour', 'pas', 'sur', 'ce', 'vous', | |
| 'avec', 'au', 'il', 'je', 'sont', 'mais', 'nous', 'si', 'plus', | |
| 'leur', 'par', 'ont', 'ou', 'comme', 'elle', 'tout', 'même' | |
| ] | |
| }, | |
| 'es': { | |
| 'chars': 'abcdefghijklmnopqrstuvwxyzáéíóúüñ', | |
| 'unique_chars': 'áéíóúüñ', | |
| 'common_words': [ | |
| 'el', 'la', 'los', 'las', 'de', 'del', 'un', 'una', 'unos', 'unas', | |
| 'y', 'e', 'o', 'u', 'que', 'en', 'a', 'con', 'por', 'para', 'es', | |
| 'son', 'al', 'lo', 'su', 'sus', 'se', 'mi', 'me', 'te', 'nos', | |
| 'como', 'pero', 'más', 'este', 'esta', 'esto' | |
| ] | |
| } | |
| } | |
| # Desteklenen diller | |
| self.supported_languages = { | |
| 'tr': 'Türkçe', | |
| 'en': 'İngilizce', | |
| 'de': 'Almanca', | |
| 'fr': 'Fransızca', | |
| 'es': 'İspanyolca', | |
| 'unknown': 'Bilinmeyen' | |
| } | |
| logger.info("Dil algılama modülü başlatıldı") | |
| def _clean_text(self, text): | |
| """ | |
| Metni temizler | |
| Args: | |
| text: Temizlenecek metin | |
| Returns: | |
| str: Temizlenmiş metin | |
| """ | |
| if not text: | |
| return "" | |
| # Küçük harfe çevir | |
| text = text.lower() | |
| # Sayıları ve özel karakterleri kaldır (dil karakterleri hariç) | |
| text = re.sub(r'[0-9]', '', text) | |
| text = re.sub(r'[^\w\s\u00C0-\u00FF\u0100-\u017F\u0400-\u04FF]', '', text) | |
| return text | |
| def _get_words(self, text): | |
| """ | |
| Metinden kelimeleri çıkarır | |
| Args: | |
| text: Kelimesi çıkarılacak metin | |
| Returns: | |
| list: Kelimeler listesi | |
| """ | |
| words = re.findall(r'\b\w+\b', text.lower()) | |
| return words | |
| def _calculate_character_score(self, text, language): | |
| """ | |
| Metindeki karakterlerin dile uygunluğunu hesaplar | |
| Args: | |
| text: Değerlendirilecek metin | |
| language: Dil kodu | |
| Returns: | |
| float: Karakter skoru (0-1 arası) | |
| """ | |
| if not text: | |
| return 0.0 | |
| profile = self.language_profiles.get(language, {}) | |
| chars = profile.get('chars', '') | |
| unique_chars = profile.get('unique_chars', '') | |
| # Metin içindeki karakterleri say | |
| char_count = Counter(text.lower()) | |
| # Dildeki karakterlerin metinde bulunma oranı | |
| total_chars = sum(char_count.values()) | |
| if total_chars == 0: | |
| return 0.0 | |
| matched_chars = sum(char_count.get(char, 0) for char in chars) | |
| char_ratio = matched_chars / total_chars | |
| # Dile özgü karakterlerin varlığını kontrol et | |
| unique_char_present = any(char in text.lower() for char in unique_chars) | |
| unique_bonus = 0.2 if unique_char_present else 0.0 | |
| return min(1.0, char_ratio + unique_bonus) | |
| def _calculate_word_score(self, words, language): | |
| """ | |
| Kelimelerin dile uygunluğunu hesaplar | |
| Args: | |
| words: Değerlendirilecek kelimeler listesi | |
| language: Dil kodu | |
| Returns: | |
| float: Kelime skoru (0-1 arası) | |
| """ | |
| if not words: | |
| return 0.0 | |
| common_words = self.language_profiles.get(language, {}).get('common_words', []) | |
| # Yaygın kelimelerin metinde bulunma sayısı | |
| matched_words = sum(1 for word in words if word in common_words) | |
| # Yaygın kelime oranı | |
| word_ratio = matched_words / min(len(words), 100) # En fazla 100 kelime değerlendir | |
| return word_ratio | |
| def detect_language(self, text): | |
| """ | |
| Metnin dilini tespit eder | |
| Args: | |
| text: Dili tespit edilecek metin | |
| Returns: | |
| dict: { | |
| 'language_code': dil kodu (tr, en, vb), | |
| 'language_name': dil adı, | |
| 'confidence': güven skoru (0-1 arası), | |
| 'scores': dil bazında skorlar | |
| } | |
| """ | |
| if not text or len(text.strip()) < 5: | |
| return { | |
| 'language_code': 'unknown', | |
| 'language_name': self.supported_languages.get('unknown'), | |
| 'confidence': 0.0, | |
| 'scores': {} | |
| } | |
| try: | |
| clean_text = self._clean_text(text) | |
| words = self._get_words(clean_text) | |
| scores = {} | |
| # Her dil için skor hesapla | |
| for lang_code in self.language_profiles.keys(): | |
| char_score = self._calculate_character_score(clean_text, lang_code) | |
| word_score = self._calculate_word_score(words, lang_code) | |
| # Ağırlıklı toplam (karakter:0.4, kelime:0.6) | |
| total_score = (char_score * 0.4) + (word_score * 0.6) | |
| scores[lang_code] = total_score | |
| # En yüksek skorlu dili bul | |
| if not scores: | |
| detected_lang = 'unknown' | |
| confidence = 0.0 | |
| else: | |
| detected_lang = max(scores, key=scores.get) | |
| confidence = scores[detected_lang] | |
| # Eğer güven skoru çok düşükse "bilinmeyen" olarak işaretle | |
| if confidence < 0.15: | |
| detected_lang = 'unknown' | |
| confidence = 0.0 | |
| return { | |
| 'language_code': detected_lang, | |
| 'language_name': self.supported_languages.get(detected_lang, self.supported_languages.get('unknown')), | |
| 'confidence': confidence, | |
| 'scores': scores | |
| } | |
| except Exception as e: | |
| logger.error(f"Dil algılama hatası: {str(e)}") | |
| return { | |
| 'language_code': 'unknown', | |
| 'language_name': self.supported_languages.get('unknown'), | |
| 'confidence': 0.0, | |
| 'scores': {} | |
| } | |
| def detect_languages_batch(self, texts): | |
| """ | |
| Birden çok metnin dilini tespit eder | |
| Args: | |
| texts: Dilleri tespit edilecek metinler listesi | |
| Returns: | |
| list: Her metin için dil tespiti sonuçları | |
| """ | |
| results = [] | |
| for text in texts: | |
| result = self.detect_language(text) | |
| results.append(result) | |
| return results |