Tokenizasyon Nedir?
Token kelimesini oldukça sık duymuşsunuzdur. Her ne kadar ülkemizde daha çok kripto paraları akla getirsede biz NLP ve ML problemlerinde ki kullanımlarına değineceğiz. Temelde tokenizasyon, bir cümlenin yapısını anlamak için parçalara ayırmaya işlemidir. Tıpkı doktorların bir organı anlamak için tek tek hücreleri incelemesi gibi, NLP geliştiricileride metnin yapısını ve anlamını parçalara ayırıp anlamak için tokenizasyondan yararlanır. Detaylı anlatıma başlamadan önce klasik tanımlara bir göz atalım.
Doğal Dil İşleme (NLP) ve makine öğrenimi alanında tokenizasyon, bir metin dizisini token olarak bilinen daha küçük parçalara dönüştürme sürecini ifade eder. Bu jetonlar karakter kadar küçük veya kelimeler kadar uzun olabilir.
Diğer bir tanımla Tokenizasyon, bir metin öbeğinin daha küçük parçalara bölünmesidir. İster paragrafı cümlelere bölün, ister cümleyi kelimelere, ister kelimeyi karakterlere bölün.
Başka bir ifadeyle de Tokenizasyon, metin dizisinin (veri) yapı birimi olarak düşünülebilir.
Bir çocuğa okumayı öğretmeye çalıştığınızı hayal edin. Doğrudan karmaşık paragraflara dalmak yerine, bunları tek tek harflerle, sonra hecelerle ve son olarak da tüm kelimelerle tanıtarak başlarsınız. Benzer şekilde tokenizasyon, geniş metin parçalarını makineler için daha sindirilebilir ve anlaşılır parçalara böler.
Peki bunu neden yapıyoruz? Tokenleştirme aşamasına neden ihtiyaç duyuyoruz?
Bunu yapıyoruz çünkü tokenler metinlerin temel yapı taşlarını oluştururlar. Problemlerin çözümünde kullandığımız köklerin alınması, köklerden türetme işlemleri ve istenmeyen kelimelerin çıkarılması gibi bütün önişleme adımları token seviyesinde gerçekleştirilir.
Ve tabi ki sinir ağları. Doğal dil işleme problemleri için bir sinir ağı, bir belgeyi anlamak için tokenleri kullanır. Tabi ki makineler direk bu metin verilerini işleyemezler. Bunların bir sinir ağı tarafından işlenebilmesi için sayısal değerlere döndürülmesi, kimliklendirilmesi gerekir.
Tokenleştirme Yöntemleri
Buraya kadar geldiğinize göre Tokenizasyon işleminin orijinal metni karakterlere, kelimelere, cümlelere bölmeye yardımcı olan bir algoritma olduğunu artık biliyorsunuz.
Tokenleştirme yöntemleri, metne ve problemin gereksinimlerine göre değişiklik gösterebilir. Bu yöntemler, metni tek tek kelimelere bölmekten, bunları karakterlere ve hatta daha küçük birimlere ayırmaya kadar değişebilir. Peki şimdi bunlara bir gözatalım.
Kelime tokenizasyonu (Word Tokenization)
Bu yöntemde metin tek tek kelimelere bölünür (Yukarıda ki resimde olduğu gibi). Çok yaygın bir yaklaşımdır ve özellikle İngilizce gibi kelime sınırlarının net olduğu diller için oldukça etkilidir. Ya Türkçe?
En sık kullanılan ayırma ayracı “boşluk”tur. Duruma göre metin boşluk ve noktalama işaretleri gibi birden fazla ayraç kullanılarak da bölünebilir. Bunu belirleyen sizin projenizin isterleridir.
Kelime tabanlı tokenizasyon, özel RegEx veya Python’un split() yöntemi kullanılarak kolayca yapılabilir. Bunun dışında Python’da tokenizasyonu kolayca gerçekleştirmenize yardımcı olabilecek NLTK, SpaCy, Keras, Gensim gibi birçok kütüphane vardır. Bunlar içinde NLTK oldukça kullanışlı ve esnektir. Bunun dışında yeni çıkan daha kompleks yöntemler (WordPiece ve BPE gibi) ise daha karmaşık bir yapıya sahiptir. Bunlara ileride ayrı ayrı detaylıca değineceğiz.
Hadi bir de örnek verelim ve bu yöntemi tamamlayalım.
Metin : “Ben örnek bir metnim :)”
Tokens: [ “Ben”, “örnek”, “bir”, “metnim”, “:)” ]
Karakter Tokenizasyonu (Character Tokenization)
Bu algoritmada metin tek tek ayrı karakterlere ayrılmıştır. Bu yöntem, sözcük sınırlarının bulunmadığı diller veya yazım düzeltme gibi ayrıntılı analiz gerektiren görevler için faydalıdır. Kelime dağarcığının boyutu oldukça küçüktür.
Örneğin Türkçe’de 29 farklı karakter (harf, rakam, özel karakterler hariç) kullanılırken, kelime hazinesinde 616.767 adet kelime bulunmaktadır. Bu da bize problem çözümünde karakter bazlı tokenizasyon ile kelime bazlı tokenizasyona kıyasla daha az token kullanılacağını göstermektedir.
Karakter tabanlı tokenizasyonun en büyük avantajı bilinmeyen (UNK) kelimelerin olmaması veya çok az olmasıdır. Diğer bir avantaj ise yanlış yazılan kelimelerin Kelime Dağarcığı Dışı (OOV, A Out-Of-Vocabulary) olarak işaretlenerek doğru yazımlarının tespit edilmesi ile bilgi kaybının önüne geçilebilmesidir.
Bu tür tokenizasyon işlemi oldukça basittir ve bellek/zaman maliyetlerini önemli ölçüde azaltabilir. Bununla birlikte bazı handikapları da vardır. Örneğin bir karakter bir kelime gibi (simgesel diller hariç) herhangi bir anlam veya bilgi taşıyamaz. Ayrıca her kelime her karaktere bölündüğü için tokenize edilmiş metin, ham metinden çok daha uzun olacaktır.
Fakat Çin’ce gibi sembolik dillerde karakterler başlı başına kelime gibi anlam ifade eder. Bu tür problemlerin kullanımda oldukça faydalı olacaktır.
Alt Kelime Tokenizasyonu (Subword Tokenizasyon)
Yukarıda bahsettiğimiz iki yöntem arasında denge kuran bu yöntem, metni tek bir karakterden daha büyük ancak bir kelimeden de daha küçük olabilecek birimlere ayırır. Burada ki ana fikir, kelime tabanlı tokenizasyon (büyük kelime dağarcığı boyutu, çok sayıda OOV (kelime dağarcığı dışı kelimeler) tokeni ve eş anlamlı kelimeler) ve karakter tabanlı tokenizasyon (uzun dizi boyutu ve anlamsız tokenler) tarafından karşılaşılan sorunları çözmektir.
Örneğin “çocuklar” kelimesi “çocuk” ve “lar” olarak ikiye ayrılmalıdır. Bu, modelin “çocuklar” kelimesinin biraz farklı anlamlara sahip ancak aynı kök kelimeye sahip “çocuk” kelimesi kullanılarak oluşturulduğunu öğrenmesine yardımcı olacaktır. Bu sayade model gelebilecek çocuk ön ekli farklı kelimelerin aynı anlamları ifade edebileceğini öğrenecektir.
Alt kelime tabanlı tokenizasyon algoritmaları genellikle hangi kelimenin token’ın başlangıcı, hangi kelimenin tamamlayıcısı olduğunu belirtmek için özel bir sembol kullanır. Örneğin, “çocuklar”, “çocuk” ve “##lar” olarak ikiye ayrılabilir; bu, “token”ın kelimenin başlangıcı olduğunu ve “##lar”ın kelimenin tamamlanması olduğunu gösterir. Farklı modeller kelimeleri belirlemek için farklı semboller kullanır. Örnek olarak burada kullandığımız “##” sembolü BERT modeli tarafından ikinci alt kelimeyi belirtmek amacıyla kullanılmaktadır.
En yaygın kullanan modeller:
- BERT ve DistilBERT tarafından kullanılan WordPiece , XLNet
- ALBERT tarafından kullanılan Unigram
- GPT-2 ve RoBERTa tarafından kullanılan Bye-Pair Encoding’dir.
Bu algoritma ile model yeterli kelime dağarcığına sahip olacağı gibi bağlam dışı anlamlı temsilleride rahatlıkla öğrenebilecektir.
Tokenizasyon İşleminin Zorlukları
Doğal dil işleme, yani insan dilinin inceliklerini anlamak oldukça zorlu bir iştir. Kendinizden pay biçin. Farklı kelimeler farklı hareketlerle farklı anlamlara gelebilir; bazen küfür bazen sevgi ifade edebilir. Ayrıca bununla birlikte üstü kapalı ifadeler insan dilindeki belirsizliği zirveye çıkarır. Bu zorlukları genel olarak şu şekilde guruplandırabiliriz:
Belirsizlikler : İnsan dili doğası gereği belirsizdir. “Trafikte araba sürmek tehlikeli olabilir” cümlesini düşünün. Bu cümlenin nasıl tokenize edildiğine ve yorumlandığına bağlı olarak araba sürmenin tehlikeli olduğu veya araç sürmenin trafikte tehlikeli olduğu gibi anlamlar çıkarılabilir.
Açık sınırları olmayan diller : Çince veya Japonca gibi bazı dillerde kelimeler arasında net boşluklar yoktur, bu da tokenizasyonu daha karmaşık bir görev haline getirir. Bir kelimenin nerede bitip diğerinin nerede başladığını belirlemek bu tür dillerde önemli bir zorluk olabilir.
Özel karakterlerin işlenmesi : Bir metin düşünün. Kelimelerin bir araya geldiği bir yığın. İlk bakışta gayet basit gibi görünsede metinler genellikle kelimelerden daha fazlasını içerir. Bu noktada e-posta adreslerinin, URL’lerin veya özel sembollerin simgeleştirilmesi zor olabilir. Örneğin, “ oguzhanyenen@gmail.com “ tek bir token olarak mı ele alınmalı, “.” veya “@” sembolüne göre mi bölünmelidir?
Önceden tanımlanmış kurallar ve düzenli ifadeler, özel karakterlerin ve karmaşık dizelerin işlenmesinde yardımcı olabilir.


