File size: 4,824 Bytes
19995b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae19be7
 
 
 
 
 
 
 
 
 
19995b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae19be7
 
 
 
19995b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae19be7
19995b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import torch
import re
from collections import Counter

# LOAD MODEL
MODEL_ID = "Sengil/t5-turkish-aspect-term-extractor"
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_ID).to(DEVICE)
model.eval()

TURKISH_STOPWORDS = {
    "ve", "çok", "ama", "bir", "bu", "daha", "gibi", "ile", "için",
    "de", "da", "ki", "o", "şu", "bu", "sen", "biz", "siz", "onlar"
}

def is_valid_aspect(word):
    word = word.strip().lower()
    return (
        len(word) > 1 and
        word not in TURKISH_STOPWORDS and
        word.isalpha()
    )

def is_aspect_in_text(aspect_term, original_text):
    """Aspect term'in orijinal metinde geçip geçmediğini kontrol eder"""
    # Case-insensitive karşılaştırma
    text_lower = original_text.lower()
    aspect_lower = aspect_term.lower()
    
    # Word boundary ile tam kelime araması
    pattern = r'\b' + re.escape(aspect_lower) + r'\b'
    return bool(re.search(pattern, text_lower, re.IGNORECASE))

def extract_and_rank_aspects(text, max_tokens=64, beams=5):
    inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True).to(DEVICE)

    with torch.no_grad():
        outputs = model.generate(
            input_ids=inputs["input_ids"],
            attention_mask=inputs["attention_mask"],
            max_new_tokens=max_tokens,
            num_beams=beams,
            num_return_sequences=beams,
            early_stopping=True
        )

    all_predictions = [
        tokenizer.decode(output, skip_special_tokens=True)
        for output in outputs
    ]

    all_terms = []
    for pred in all_predictions:
        candidates = re.split(r"[;,–—\-]|(?:\s*,\s*)", pred)
        # Sadece orijinal metinde geçen aspect term'leri ekle
        for candidate in candidates:
            if is_valid_aspect(candidate) and is_aspect_in_text(candidate.strip(), text):
                all_terms.append(candidate.strip().lower())

    ranked = Counter(all_terms).most_common()
    return ranked

def process_text(text):
    if not text.strip():
        return "Lütfen analiz edilecek bir metin girin."
    
    try:
        ranked_aspects = extract_and_rank_aspects(text)
        
        if not ranked_aspects:
            return "Metinde herhangi bir aspect term bulunamadı."
        
        result = "🎯 **Bulunan Aspect Terimler:**\n\n"
        for i, (term, score) in enumerate(ranked_aspects, 1):
            result += f"{i}. **{term.title()}** - Skor: {score}\n"
        
        return result
    except Exception as e:
        return f"Hata oluştu: {str(e)}"

# Gradio Interface
with gr.Blocks(title="🇹🇷 Türkçe Aspect Term Extraction", theme=gr.themes.Soft()) as demo:
    gr.HTML("""
    <div style="text-align: center; margin-bottom: 20px;">
        <h1>🇹🇷 Türkçe Aspect Term Extraction</h1>
        <p>T5 tabanlı model ile Türkçe metinlerden aspect terimleri çıkarın</p>
        <p><i>Model: Sengil/t5-turkish-aspect-term-extractor</i></p>
    </div>
    """)
    
    with gr.Row():
        with gr.Column():
            text_input = gr.Textbox(
                label="📝 Analiz edilecek metin",
                placeholder="Örnek: Artılar: Göl manzarasıyla harika bir atmosfer, Ipoh'un her zaman sıcak olan havası nedeniyle iyi bir klima olan restoran...",
                lines=5,
                max_lines=10
            )
            
            analyze_btn = gr.Button("🔍 Aspect Terimleri Çıkar", variant="primary", size="lg")
        
        with gr.Column():
            output = gr.Markdown(
                label="📊 Sonuçlar",
                value="📊 Sonuçlar"
            )
    
    # Example texts
    gr.HTML("<h3>📋 Örnek Metinler:</h3>")
    
    examples = [
        ["Artılar: Göl manzarasıyla harika bir atmosfer, Ipoh'un her zaman sıcak olan havası nedeniyle iyi bir klima olan restoran, iyi ve hızlı hizmet sunan garsonlar, temassız ödeme kabul eden e-cüzdan, ücretsiz otopark ama sıcak güneş altında açık, yemeklerin tadı güzel."],
        ["Bu otelin konumu mükemmel, personel çok yardımısever. Kahvaltı çeşitliliği iyi ancak oda temizliği yetersiz. WiFi hızı da çok yavaş."],
        ["Ürünün kalitesi harika, kargo hızlı geldi. Fiyat biraz yüksek ama memnunum. Müşteri hizmeti de gayet iyi."]
    ]
    
    gr.Examples(
        examples=examples,
        inputs=[text_input],
        outputs=[output],
        fn=process_text,
        cache_examples=False
    )
    
    analyze_btn.click(
        fn=process_text,
        inputs=[text_input],
        outputs=[output]
    )

if __name__ == "__main__":
    demo.launch()