Spaces:
Sleeping
Sleeping
| import re | |
| import string | |
| import numpy as np | |
| from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer | |
| from collections import Counter | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| class KeywordExtractor: | |
| """ | |
| Metin içindeki anahtar kelimeleri çıkaran sınıf. | |
| TF-IDF, rakip kelimeler ve diğer metotlarla anahtar kelime çıkarma işlemi yapar. | |
| """ | |
| def __init__(self): | |
| """Anahtar kelime çıkarıcıyı başlatır""" | |
| # Türkçe stopwords (durma kelimeleri) | |
| self.turkish_stopwords = [ | |
| 've', 'veya', 'ile', 'için', 'bu', 'bir', 'ya', 'de', 'da', 'ki', 'ne', 'her', 'çok', | |
| 'daha', 'ama', 'fakat', 'lakin', 'ancak', 'gibi', 'kadar', 'sonra', 'önce', 'göre', | |
| 'nasıl', 'neden', 'şey', 'ben', 'sen', 'o', 'biz', 'siz', 'onlar', 'kendi', 'aynı', | |
| 'ise', 'mi', 'mı', 'mu', 'mü', 'hem', 'değil', 'hiç', 'olarak', 'evet', 'hayır', | |
| 'belki', 'tüm', 'yani', 'hep', 'şu', 'şey', 'tabi', 'tamam', 'bunlar', 'şunlar', | |
| 'böyle', 'öyle', 'şöyle', 'iki', 'üç', 'dört', 'beş', 'altı', 'yedi', 'sekiz', 'dokuz', | |
| 'on', 'yüz', 'bin', 'milyon', 'milyar', 'var', 'yok', 'oldu', 'olur', 'oluyor', 'olacak' | |
| ] | |
| # İngilizce stopwords (durma kelimeleri) | |
| self.english_stopwords = [ | |
| 'the', 'and', 'a', 'to', 'of', 'in', 'for', 'with', 'on', 'at', 'by', 'from', 'about', | |
| 'as', 'into', 'like', 'through', 'after', 'over', 'between', 'out', 'against', 'during', | |
| 'without', 'before', 'under', 'around', 'among', 'is', 'are', 'was', 'were', 'be', 'been', | |
| 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'shall', 'should', | |
| 'may', 'might', 'must', 'can', 'could', 'i', 'you', 'he', 'she', 'it', 'we', 'they', | |
| 'me', 'him', 'her', 'us', 'them', 'who', 'which', 'whose', 'whom', 'this', 'that', 'these', | |
| 'those', 'am', 'is', 'are', 'was', 'were', 'an', 'my', 'your', 'his', 'its', 'our', 'their' | |
| ] | |
| # Tüm stopwords listesini birleştir | |
| self.stopwords = set(self.turkish_stopwords + self.english_stopwords) | |
| # TF-IDF vektörleyici | |
| self.tfidf_vectorizer = TfidfVectorizer( | |
| max_df=0.9, | |
| min_df=2, | |
| max_features=200, | |
| stop_words=self.stopwords, | |
| ngram_range=(1, 2) # Tek kelimeler ve ikili kelime grupları | |
| ) | |
| # Sayısal karakter ve noktalama işaretlerini temizlemek için regex pattern | |
| self.cleanup_pattern = re.compile(f'[{re.escape(string.punctuation)}]|[0-9]') | |
| logger.info("Anahtar kelime çıkarıcı başlatıldı") | |
| def preprocess_text(self, text): | |
| """ | |
| Metni anahtar kelime çıkarma için ön işleme tabi tutar | |
| Args: | |
| text: İşlenecek metin | |
| Returns: | |
| str: Temizlenmiş metin | |
| """ | |
| if not text: | |
| return "" | |
| # Küçük harfe çevir | |
| text = text.lower() | |
| # Noktalama işaretlerini temizle | |
| text = self.cleanup_pattern.sub(' ', text) | |
| # Fazla boşlukları temizle | |
| text = re.sub(r'\s+', ' ', text).strip() | |
| return text | |
| def extract_keywords_tfidf(self, text, num_keywords=5): | |
| """ | |
| TF-IDF kullanarak metinden anahtar kelimeleri çıkarır | |
| Args: | |
| text: Anahtar kelimeleri çıkarılacak metin | |
| num_keywords: Çıkarılacak anahtar kelime sayısı | |
| Returns: | |
| list: [(anahtar_kelime, skor), ...] formatında liste | |
| """ | |
| try: | |
| if not text or len(text.strip()) < 10: | |
| return [] | |
| # Metni ön işle | |
| processed_text = self.preprocess_text(text) | |
| # TF-IDF matrix oluştur | |
| tfidf_matrix = self.tfidf_vectorizer.fit_transform([processed_text]) | |
| # Feature isimleri (kelimeler) | |
| feature_names = self.tfidf_vectorizer.get_feature_names_out() | |
| # Kelimelerin TF-IDF skorlarını hesapla ve sırala | |
| tfidf_scores = zip(feature_names, tfidf_matrix.toarray()[0]) | |
| sorted_scores = sorted(tfidf_scores, key=lambda x: x[1], reverse=True) | |
| # En yüksek skorlu kelimeleri seç | |
| top_keywords = sorted_scores[:num_keywords] | |
| return top_keywords | |
| except Exception as e: | |
| logger.error(f"TF-IDF anahtar kelime çıkarma hatası: {str(e)}") | |
| return [] | |
| def extract_keywords_textrank(self, text, num_keywords=5): | |
| """ | |
| TextRank benzeri bir algoritma ile anahtar kelimeleri çıkarır | |
| Args: | |
| text: Anahtar kelimeleri çıkarılacak metin | |
| num_keywords: Çıkarılacak anahtar kelime sayısı | |
| Returns: | |
| list: [(anahtar_kelime, skor), ...] formatında liste | |
| """ | |
| try: | |
| if not text or len(text.strip()) < 10: | |
| return [] | |
| # Metni ön işle | |
| processed_text = self.preprocess_text(text) | |
| # Kelimeleri ayır | |
| words = processed_text.split() | |
| # Stopwords olmayan kelimeleri filtrele | |
| filtered_words = [word for word in words if word not in self.stopwords and len(word) > 2] | |
| # Kelime frekanslarını hesapla | |
| word_freq = Counter(filtered_words) | |
| # En sık geçen kelimeleri seç | |
| most_common = word_freq.most_common(num_keywords * 2) # Daha fazla al, sonra filtreleyeceğiz | |
| # TF-IDF skorlaması ile benzer bir yaklaşım uygula | |
| # Kelime sıklığının logaritması * kelimenin benzersizliği | |
| scored_words = [] | |
| for word, count in most_common: | |
| # Benzersizlik faktörü: Toplam kelime sayısı / kelimenin sıklığı | |
| uniqueness = len(filtered_words) / (count + 1) | |
| # Skor hesapla | |
| score = np.log(count + 1) * uniqueness | |
| scored_words.append((word, score)) | |
| # Skorlara göre sırala | |
| scored_words.sort(key=lambda x: x[1], reverse=True) | |
| return scored_words[:num_keywords] | |
| except Exception as e: | |
| logger.error(f"TextRank anahtar kelime çıkarma hatası: {str(e)}") | |
| return [] | |
| def extract_bigrams(self, text, num_bigrams=3): | |
| """ | |
| Metinden ikili kelime gruplarını (bigram) çıkarır | |
| Args: | |
| text: Anahtar kelimeleri çıkarılacak metin | |
| num_bigrams: Çıkarılacak bigram sayısı | |
| Returns: | |
| list: [(bigram, skor), ...] formatında liste | |
| """ | |
| try: | |
| if not text or len(text.strip()) < 10: | |
| return [] | |
| # Metni ön işle | |
| processed_text = self.preprocess_text(text) | |
| # Bigram için vektörleyici | |
| bigram_vectorizer = CountVectorizer( | |
| ngram_range=(2, 2), | |
| stop_words=self.stopwords, | |
| max_features=100 | |
| ) | |
| # Bigram matrix oluştur | |
| bigram_matrix = bigram_vectorizer.fit_transform([processed_text]) | |
| # Feature isimleri (bigramlar) | |
| feature_names = bigram_vectorizer.get_feature_names_out() | |
| # Bigramların skorlarını hesapla ve sırala | |
| bigram_scores = zip(feature_names, bigram_matrix.toarray()[0]) | |
| sorted_scores = sorted(bigram_scores, key=lambda x: x[1], reverse=True) | |
| # En yüksek skorlu bigramları seç | |
| top_bigrams = sorted_scores[:num_bigrams] | |
| return top_bigrams | |
| except Exception as e: | |
| logger.error(f"Bigram çıkarma hatası: {str(e)}") | |
| return [] | |
| def extract_keywords(self, text, method='combined', num_keywords=10): | |
| """ | |
| Metinden anahtar kelimeleri çıkarır | |
| Args: | |
| text: Anahtar kelimeleri çıkarılacak metin | |
| method: Kullanılacak metod ('tfidf', 'textrank', 'combined') | |
| num_keywords: Toplam çıkarılacak anahtar kelime sayısı | |
| Returns: | |
| dict: { | |
| 'keywords': [(anahtar_kelime, skor), ...], | |
| 'bigrams': [(bigram, skor), ...], | |
| 'method': kullanılan metod | |
| } | |
| """ | |
| if not text or len(text.strip()) < 10: | |
| return { | |
| 'keywords': [], | |
| 'bigrams': [], | |
| 'method': method | |
| } | |
| try: | |
| keywords = [] | |
| if method == 'tfidf': | |
| keywords = self.extract_keywords_tfidf(text, num_keywords) | |
| elif method == 'textrank': | |
| keywords = self.extract_keywords_textrank(text, num_keywords) | |
| else: # combined | |
| # TF-IDF ve TextRank sonuçlarını birleştir | |
| tfidf_keywords = self.extract_keywords_tfidf(text, num_keywords // 2) | |
| textrank_keywords = self.extract_keywords_textrank(text, num_keywords // 2) | |
| # İki listeyi birleştir | |
| combined = {} | |
| for keyword, score in tfidf_keywords + textrank_keywords: | |
| if keyword in combined: | |
| combined[keyword] = max(combined[keyword], score) | |
| else: | |
| combined[keyword] = score | |
| # En yüksek skorlu kelimeleri seç | |
| keywords = sorted(combined.items(), key=lambda x: x[1], reverse=True)[:num_keywords] | |
| # Bigramları da ekle | |
| bigrams = self.extract_bigrams(text, num_keywords // 3) | |
| return { | |
| 'keywords': keywords, | |
| 'bigrams': bigrams, | |
| 'method': method | |
| } | |
| except Exception as e: | |
| logger.error(f"Anahtar kelime çıkarma hatası: {str(e)}") | |
| return { | |
| 'keywords': [], | |
| 'bigrams': [], | |
| 'method': method | |
| } |