Update app.py
Browse files
app.py
CHANGED
|
@@ -11,7 +11,7 @@ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
|
|
| 11 |
|
| 12 |
HF_MODEL_ID = "LiProject/BERT-Turkish-Lemmatization-V3"
|
| 13 |
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
| 14 |
-
CONFIDENCE_THRESHOLD = 0.85 # Güven skoru eşiği
|
| 15 |
|
| 16 |
try:
|
| 17 |
tok = AutoTokenizer.from_pretrained(HF_MODEL_ID, use_fast=True)
|
|
@@ -25,20 +25,20 @@ except Exception as e:
|
|
| 25 |
# 2. Arka Plan İşlemleri
|
| 26 |
# =========================================================================
|
| 27 |
|
| 28 |
-
def get_lemma_for_word(word: str):
|
| 29 |
"""
|
| 30 |
Tek kelimeyi temizler, modelden geçirir.
|
| 31 |
-
|
| 32 |
"""
|
| 33 |
clean_word = word.strip(".,!?();:\"'’")
|
| 34 |
|
| 35 |
if not clean_word:
|
| 36 |
-
return word
|
| 37 |
|
| 38 |
# Eğer kelime sadece sayı veya sayı+ek ise direkt döndür
|
| 39 |
num_match = re.match(r"^(\d+(?:[.,]\d+)?)(?:['’.]?[a-zA-ZğüşıöçĞÜŞİÖÇ]*)$", clean_word)
|
| 40 |
if num_match:
|
| 41 |
-
return num_match.group(1)
|
| 42 |
|
| 43 |
inputs = tok(clean_word, return_tensors="pt", truncation=True, max_length=128).to(DEVICE)
|
| 44 |
|
|
@@ -58,21 +58,16 @@ def get_lemma_for_word(word: str):
|
|
| 58 |
)
|
| 59 |
|
| 60 |
# Tüm dizinin (kelimenin) ortak olasılığını hesapla
|
| 61 |
-
# Log-olasılıkların toplamının üstel fonksiyonu (e^x) dizi olasılığını verir
|
| 62 |
seq_log_prob = transition_scores[0].sum().item()
|
| 63 |
confidence_score = torch.exp(torch.tensor(seq_log_prob)).item()
|
| 64 |
|
| 65 |
lemma = tok.decode(sequences[0], skip_special_tokens=True).strip()
|
| 66 |
|
| 67 |
-
#
|
| 68 |
-
if not lemma:
|
| 69 |
-
return clean_word
|
| 70 |
-
|
| 71 |
-
# Eşik değeri kontrolü (0.85 altındaysa orijinali bırak)
|
| 72 |
-
if confidence_score < CONFIDENCE_THRESHOLD:
|
| 73 |
-
return clean_word, confidence_score
|
| 74 |
|
| 75 |
-
return lemma
|
| 76 |
|
| 77 |
|
| 78 |
@torch.inference_mode()
|
|
@@ -81,17 +76,16 @@ def lemmatize_rows(multiline_text: str):
|
|
| 81 |
sentences = [s.strip() for s in multiline_text.splitlines() if s.strip()]
|
| 82 |
|
| 83 |
if not sentences:
|
| 84 |
-
return pd.DataFrame(columns=["Full_Sentence", "Word", "Lemma"
|
| 85 |
|
| 86 |
for sent in sentences:
|
| 87 |
words = sent.split()
|
| 88 |
for w in words:
|
| 89 |
-
l
|
| 90 |
rows.append({
|
| 91 |
"Full_Sentence": sent,
|
| 92 |
"Word": w,
|
| 93 |
-
"Lemma": l
|
| 94 |
-
"Confidence": round(conf, 4) # Skoru 4 ondalık basamağa yuvarla
|
| 95 |
})
|
| 96 |
|
| 97 |
return pd.DataFrame(rows)
|
|
@@ -110,8 +104,7 @@ def add_sentence_separators(df: pd.DataFrame, char: str = "-", repeat: int = 10)
|
|
| 110 |
rows.append({
|
| 111 |
"Full_Sentence": sep,
|
| 112 |
"Word": sep,
|
| 113 |
-
"Lemma": sep
|
| 114 |
-
"Confidence": "" # Ayırıcı satır için boş bırak
|
| 115 |
})
|
| 116 |
rows.append(r.to_dict())
|
| 117 |
prev = r["Full_Sentence"]
|
|
@@ -212,8 +205,8 @@ with gr.Blocks(title="Türkçe Lemmatizer") as demo:
|
|
| 212 |
gr.HTML(f"""
|
| 213 |
<div class="info-box">
|
| 214 |
<b>Model:</b> {HF_MODEL_ID}<br>
|
| 215 |
-
<b>
|
| 216 |
-
<
|
| 217 |
</div>
|
| 218 |
""")
|
| 219 |
|
|
@@ -237,7 +230,7 @@ with gr.Blocks(title="Türkçe Lemmatizer") as demo:
|
|
| 237 |
clr = gr.Button("Temizle", variant="secondary")
|
| 238 |
|
| 239 |
out_tbl = gr.Dataframe(
|
| 240 |
-
headers=["Full_Sentence", "Word", "Lemma"
|
| 241 |
label="Sonuç Önizleme",
|
| 242 |
interactive=False,
|
| 243 |
wrap=True,
|
|
|
|
| 11 |
|
| 12 |
HF_MODEL_ID = "LiProject/BERT-Turkish-Lemmatization-V3"
|
| 13 |
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
| 14 |
+
CONFIDENCE_THRESHOLD = 0.85 # Güven skoru eşiği (Arka planda çalışır)
|
| 15 |
|
| 16 |
try:
|
| 17 |
tok = AutoTokenizer.from_pretrained(HF_MODEL_ID, use_fast=True)
|
|
|
|
| 25 |
# 2. Arka Plan İşlemleri
|
| 26 |
# =========================================================================
|
| 27 |
|
| 28 |
+
def get_lemma_for_word(word: str) -> str:
|
| 29 |
"""
|
| 30 |
Tek kelimeyi temizler, modelden geçirir.
|
| 31 |
+
Arka planda güven skoru hesaplanır, 0.85 altındaysa orijinal (temizlenmiş) kelime döndürülür.
|
| 32 |
"""
|
| 33 |
clean_word = word.strip(".,!?();:\"'’")
|
| 34 |
|
| 35 |
if not clean_word:
|
| 36 |
+
return word
|
| 37 |
|
| 38 |
# Eğer kelime sadece sayı veya sayı+ek ise direkt döndür
|
| 39 |
num_match = re.match(r"^(\d+(?:[.,]\d+)?)(?:['’.]?[a-zA-ZğüşıöçĞÜŞİÖÇ]*)$", clean_word)
|
| 40 |
if num_match:
|
| 41 |
+
return num_match.group(1)
|
| 42 |
|
| 43 |
inputs = tok(clean_word, return_tensors="pt", truncation=True, max_length=128).to(DEVICE)
|
| 44 |
|
|
|
|
| 58 |
)
|
| 59 |
|
| 60 |
# Tüm dizinin (kelimenin) ortak olasılığını hesapla
|
|
|
|
| 61 |
seq_log_prob = transition_scores[0].sum().item()
|
| 62 |
confidence_score = torch.exp(torch.tensor(seq_log_prob)).item()
|
| 63 |
|
| 64 |
lemma = tok.decode(sequences[0], skip_special_tokens=True).strip()
|
| 65 |
|
| 66 |
+
# Üretilen kök boşsa veya arka plandaki güven skoru %85'in altındaysa orijinali kullan
|
| 67 |
+
if not lemma or confidence_score < CONFIDENCE_THRESHOLD:
|
| 68 |
+
return clean_word
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
+
return lemma
|
| 71 |
|
| 72 |
|
| 73 |
@torch.inference_mode()
|
|
|
|
| 76 |
sentences = [s.strip() for s in multiline_text.splitlines() if s.strip()]
|
| 77 |
|
| 78 |
if not sentences:
|
| 79 |
+
return pd.DataFrame(columns=["Full_Sentence", "Word", "Lemma"])
|
| 80 |
|
| 81 |
for sent in sentences:
|
| 82 |
words = sent.split()
|
| 83 |
for w in words:
|
| 84 |
+
l = get_lemma_for_word(w)
|
| 85 |
rows.append({
|
| 86 |
"Full_Sentence": sent,
|
| 87 |
"Word": w,
|
| 88 |
+
"Lemma": l
|
|
|
|
| 89 |
})
|
| 90 |
|
| 91 |
return pd.DataFrame(rows)
|
|
|
|
| 104 |
rows.append({
|
| 105 |
"Full_Sentence": sep,
|
| 106 |
"Word": sep,
|
| 107 |
+
"Lemma": sep
|
|
|
|
| 108 |
})
|
| 109 |
rows.append(r.to_dict())
|
| 110 |
prev = r["Full_Sentence"]
|
|
|
|
| 205 |
gr.HTML(f"""
|
| 206 |
<div class="info-box">
|
| 207 |
<b>Model:</b> {HF_MODEL_ID}<br>
|
| 208 |
+
<b>Çalışma mantığı:</b> Metin satır satır, her satır da kelime kelime işlenir.
|
| 209 |
+
<i>(Not: Modelin ürettiği kökün güven skoru 0.85 altındaysa arka planda otomatik olarak iptal edilir ve kelime olduğu gibi bırakılır.)</i>
|
| 210 |
</div>
|
| 211 |
""")
|
| 212 |
|
|
|
|
| 230 |
clr = gr.Button("Temizle", variant="secondary")
|
| 231 |
|
| 232 |
out_tbl = gr.Dataframe(
|
| 233 |
+
headers=["Full_Sentence", "Word", "Lemma"],
|
| 234 |
label="Sonuç Önizleme",
|
| 235 |
interactive=False,
|
| 236 |
wrap=True,
|