File size: 4,266 Bytes
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
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 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)
        all_terms.extend([w.strip().lower() for w in candidates if is_valid_aspect(w)])

    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 burada görünecek..."
            )
    
    # 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()