textqualtox / utils /language_detector.py
sarizeybekk
Remove venv from Git tracking and add to .gitignore
bd97f47
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