nypgd's picture
Update README.md
b6fbca4 verified
|
Raw History Blame Contribute Delete
7.39 kB
---
language:
- tr
tags:
- named-entity-recognition
- ner
- turkish
- bert
- deprem
- disaster
- token-classification
- earthquake
license: apache-2.0
base_model: dbmdz/bert-base-turkish-cased
datasets:
- custom
metrics:
- f1
- precision
- recall
model-index:
- name: bert-turkish-deprem-ner
results:
- task:
type: token-classification
name: Named Entity Recognition
metrics:
- type: f1
value: 0.9702
name: F1 (Stacked 17k)
- type: precision
value: 0.9680
name: Precision
- type: recall
value: 0.9724
name: Recall
---
# BERT Türkçe Deprem Tweet NER Modeli
Deprem tweetlerinden kritik bilgileri otomatik olarak çıkarmak için **SFT + Pseudo-Labeling (Stacking Ensemble)** yöntemiyle fine-tune edilmiş NER modeli.
- **Base model:** dbmdz/bert-base-turkish-cased
- **Eğitim:** 500 altın standart → LLM pseudo-labeling → 17.000 Stacked veri seti
- **Veri seti:** 6 Şubat 2023 Türkiye-Suriye depremi tweet'leri
- **Dil:** Türkçe
## Desteklenen Etiketler
| Etiket | Açıklama | Örnek |
|--------|----------|-------|
| `LOC` | Konum / Adres | Hatay Antakya Armutlu Sokak |
| `PER` | Kişi adı | Murat Filazoğlu |
| `PHONE` | Telefon numarası | 0539 218 3976 |
| `NEED` | İhtiyaç / Talep | battaniye, jeneratör |
| `ORG` | Kurum / Organizasyon | AFAD, Kızılay |
| `LINK` | URL bağlantısı | https://t.co/... |
## ⚠️ Önemli Not: Ön-İşleme (Tokenization)
Bu model eğitilirken metinler standart BERT tokenizer'ı ile değil, özel olarak **NLTK TweetTokenizer** kullanılarak kelimelere ayrılmıştır. Bu sayede `@kullanici_adi`, `https://...` gibi ifadeler ve telefon numaraları parçalanmadan tek bir bütün olarak ele alınır.
Hugging Face'in standart `pipeline` fonksiyonu metni agresif bir şekilde parçaladığı için URL'lerde ve kurumsal etiketlerde bölünmeler yaşatabilir. **Tam ve doğru performans almak için aşağıdaki özel çıkarım (inference) kodunu kullanmanız tavsiye edilir.**
## Kullanım
Aşağıdaki kod bloğu, modelin eğitildiği formata uygun olarak metni işler, etiketleri birleştirir ve güven skorlarıyla (score) birlikte döndürür:
```python
import torch
import nltk
from nltk.tokenize import TweetTokenizer
from transformers import AutoTokenizer, AutoModelForTokenClassification
# 1. NLTK TweetTokenizer'ı başlat (Link ve etiketleri korumak için gerekli)
nltk.download('punkt', quiet=True)
tknzr = TweetTokenizer(preserve_case=True, strip_handles=False, reduce_len=False)
# 2. Modeli ve Tokenizer'ı Hugging Face'den yükle
repo_id = "nypgd/bert-turkish-deprem-ner"
tokenizer = AutoTokenizer.from_pretrained(repo_id)
model = AutoModelForTokenClassification.from_pretrained(repo_id)
model.eval()
id2label = model.config.id2label
# 3. Özel Tahmin Fonksiyonu
def extract_entities(text):
original_tokens = tknzr.tokenize(text)
if not original_tokens: return []
inputs = tokenizer(original_tokens, is_split_into_words=True, return_tensors="pt", truncation=True)
with torch.no_grad():
logits = model(**inputs).logits
predictions = torch.argmax(logits, dim=2)[0]
word_ids = inputs.word_ids()
token_tags = []
token_logit_idx = []
prev_word_idx = None
for sub_pos, (pred_id, word_idx) in enumerate(zip(predictions, word_ids)):
if word_idx is None:
continue
if word_idx != prev_word_idx:
token_tags.append(id2label[pred_id.item()])
token_logit_idx.append(sub_pos)
prev_word_idx = word_idx
# Entity Birleştirme (Noktalama işaretlerini atlama mantığıyla)
SKIP_TOKENS = {',', '-', ':', '.', '/', '(', ')'}
entities = []
current_ent = None
for i, (token, tag) in enumerate(zip(original_tokens, token_tags)):
if tag == 'O' and current_ent and token in SKIP_TOKENS:
continue
if tag == 'O':
if current_ent: entities.append(current_ent)
current_ent = None
continue
ent_type = tag[2:]
score_val = round(torch.softmax(logits[0, token_logit_idx[i]], dim=-1).max().item(), 4)
if tag.startswith('B-'):
if current_ent: entities.append(current_ent)
current_ent = {"entity_group": ent_type, "word": token, "score": score_val, "start": i, "end": i + 1}
elif tag.startswith('I-') and current_ent and current_ent["entity_group"] == ent_type:
current_ent["word"] += " " + token
current_ent["end"] = i + 1
current_ent["score"] = round(min(current_ent["score"], score_val), 4)
else:
if current_ent: entities.append(current_ent)
current_ent = {"entity_group": ent_type, "word": token, "score": score_val, "start": i, "end": i + 1}
if current_ent: entities.append(current_ent)
return entities
# 4. Test Edelim
text = """
@AFADTurkiye ve Ahbap ekipleri, Gaziantep İslahiye Yeni Mahalle Karanfil Sokak No:5 adresinde 7 kişi enkaz altında mahsur kaldı.
Acil ısıtıcı, çadır ve çocuk maması gerekiyor. Saha sorumlusu Ayşe Yurt iletişim: 0533 123 45 67.
Konum ve detaylı bilgi için: https://t.co/yardimadresi
"""
results = extract_entities(text)
for ent in results:
etiket = f"[{ent['entity_group']}]"
print(f"{etiket:<9} {ent['word']} (score: {ent['score']:.4f})")
print("[")
for i, ent in enumerate(results):
virgul = "," if i < len(results) - 1 else ""
print(f" {ent}{virgul}")
print("]")
# Formatlı Çıktı
───────────────────────────────────────────────────────────────────────────────────
[ORG] @AFADTurkiye (score: 0.9999)
[ORG] Ahbap (score: 0.9996)
[LOC] Gaziantep İslahiye Yeni Mahalle Karanfil Sokak No 5 (score: 0.9999)
[NEED] ısıtıcı (score: 0.9999)
[NEED] çadır (score: 0.9999)
[NEED] çocuk maması (score: 0.9997)
[PER] Ayşe Yurt (score: 0.9993)
[PHONE] 0533 123 45 67 (score: 0.9998)
[LINK] https://t.co/yardimadresi (score: 0.9999)
───────────────────────────────────────────────────────────────────────────────────
# Ham Çıktı (Tek satırlık liste formatı)
[
{'entity_group': 'ORG', 'word': '@AFADTurkiye', 'score': 0.9999, 'start': 0, 'end': 1},
{'entity_group': 'ORG', 'word': 'Ahbap', 'score': 0.9996, 'start': 2, 'end': 3},
{'entity_group': 'LOC', 'word': 'Gaziantep İslahiye Yeni Mahalle Karanfil Sokak No 5', 'score': 0.9999, 'start': 5, 'end': 14},
{'entity_group': 'NEED', 'word': 'ısıtıcı', 'score': 0.9999, 'start': 23, 'end': 24},
{'entity_group': 'NEED', 'word': 'çadır', 'score': 0.9999, 'start': 25, 'end': 26},
{'entity_group': 'NEED', 'word': 'çocuk maması', 'score': 0.9997, 'start': 27, 'end': 29},
{'entity_group': 'PER', 'word': 'Ayşe Yurt', 'score': 0.9993, 'start': 33, 'end': 35},
{'entity_group': 'PHONE', 'word': '0533 123 45 67', 'score': 0.9998, 'start': 37, 'end': 41},
{'entity_group': 'LINK', 'word': '[https://t.co/yardimadresi](https://t.co/yardimadresi)', 'score': 0.9999, 'start': 48, 'end': 49}
]