TR-KVKK Classifier
*** !!! STILL under development. Weights are updating regularly !!! ***
Türkçe metinlerde KVKK (Kişisel Verilerin Korunması Kanunu) kapsamındaki kişisel veri kategorilerini tespit eden karakter bazlı Transformer modelidir.
EĞİTİM VE AKADEMİK AMAÇLIDIR
Model arhitecture based on https://arxiv.org/pdf/2010.11929
Model Mimarisi
Karakter düzeyinde çalışan özgün bir Vision Transformer (ViT) uyarlamasıdır (CharViT). Subword tokenization yerine karakter bazlı embedding kullanır; bu sayede TC kimlik numarası, IBAN ve telefon numarası gibi yapısal pattern'ları daha iyi öğrenir.
| Parametre | Değer |
|---|---|
| Mimari | CharViT (Transformer Encoder) |
| Embedding | Karakter bazlı |
embed_dim |
128 |
n_layers |
3 |
n_heads |
4 |
max_len |
512 karakter |
num_classes |
6 |
Kategoriler
| Label | Kategori | Açıklama |
|---|---|---|
| 0 | negatif |
Kişisel veri içermeyen metinler |
| 1 | tc_kimlik |
TC kimlik numarası |
| 2 | saglik |
Sağlık ve tıbbi veriler |
| 3 | finans |
IBAN, banka ve finansal bilgiler |
| 4 | iletisim |
Telefon, e-posta, adres |
| 5 | biyometrik |
Parmak izi, yüz tanıma ve benzeri |
Kullanım
import torch
import json
from safetensors.torch import load_file
# Config ve vocab yükle
with open("config.json") as f:
config = json.load(f)
with open("vocab.json") as f:
char2idx = json.load(f)
# Model tanımı (CharViT sınıfının tanımlı olduğunu varsayar)
model = CharViT(**{k: config[k] for k in
["vocab_size","embed_dim","max_len","n_heads","n_layers","num_classes"]})
model.load_state_dict(load_file("model.safetensors"))
model.eval()
def predict(text: str) -> str:
unk = char2idx["[UNK]"]
ids = [char2idx.get(c, unk) for c in text[:config["max_len"]]]
ids += [0] * (config["max_len"] - len(ids))
with torch.no_grad():
logits = model(torch.tensor([ids]))
return config["label_names"][logits.argmax().item()]
print(predict("Orkun Gedik'e ait IBAN: TR33 0006 1005 1978 6457 8413 26"))
# → "finans"
Demo için https://github.com/orkungedik/tr-kvkk-classifier
Büyük Dokümanlar
Model 512 karakter ile sınırlıdır. Daha uzun metinler için chunk + majority vote kullanın:
from collections import Counter
def predict_document(text: str, overlap: int = 30) -> str:
step = config["max_len"] - overlap
chunks = [text[i:i+config["max_len"]] for i in range(0, len(text), step)]
preds = [predict(c) for c in chunks if c.strip()]
return Counter(preds).most_common(1)[0][0]
Eğitim
| Detay | Değer |
|---|---|
| Split | %80 train / %10 val / %10 test |
| Batch size | 64 |
| Optimizer | AdamW (lr=3e-4, weight_decay=1e-2) |
| Scheduler | CosineAnnealingLR |
Değerlendirme Sonuçları
Test seti üzerinde elde edilen metrikler (n=8.348):
| Kategori | Precision | Recall | F1 | Support |
|---|---|---|---|---|
| negatif | 0.99 | 0.98 | 0.98 | 5.417 |
| tc_kimlik | 0.97 | 0.99 | 0.98 | 526 |
| saglik | 0.91 | 0.93 | 0.92 | 826 |
| finans | 1.00 | 1.00 | 1.00 | 527 |
| iletisim | 0.99 | 1.00 | 1.00 | 526 |
| biyometrik | 0.93 | 0.98 | 0.95 | 526 |
| accuracy | 0.98 | 8.348 | ||
| macro avg | 0.97 | 0.98 | 0.97 | 8.348 |
| weighted avg | 0.98 | 0.98 | 0.98 | 8.348 |
Sınırlılıklar
- Maksimum 512 karakter işleyebilir, daha uzun metinler için chunking gerekir.
- Birden fazla kategori içeren metinlerde yalnızca baskın kategoriyi döndürür (multi-label desteklenmez).
- Model yalnızca Türkçe metinler üzerinde değerlendirilmiştir.
- Downloads last month
- 219