Veri Olarak Metin: Token’lar, Normalleştirme, Zipf

2. Bölüm · Uygulamalı Doğal Dil İşleme

Dr. Batuhan Bardak

Bu dersin sonunda

  • ham metni modele hazır birimlere dönüştürebilir ve her ön işleme kararını savunabilirsiniz
  • Zipf yasasıyla kelime sıklıklarının dağılımını, Heaps yasasıyla derlem büyüdükçe farklı kelime sayısının nasıl arttığını açıklayabilirsiniz
  • bir TF-IDF vektörünü elle türetip scikit-learn ile aynı sayıları elde edebilirsiniz
  • bag-of-words (kelime torbası) temsilinin koruduğu ve kaybettiği bilgileri örneklerle açıklayabilir, hangi görevlerde uygun olduğunu gerekçelendirebilirsiniz
  • Türkçe küçük harf dönüşümü ve eklemeli yapının normalleştirme kararlarını ve sözlük kapsamını nasıl etkilediğini açıklayabilirsiniz

Problem, tek cümlede

Bu bölümde kullanacağımız modeller sayısal girdilerle çalışır. Metni bu modellere verebilmek için karakter dizilerini sayısal bir temsile dönüştürmemiz gerekir.

  • İki temel karar: metni hangi birimlere ayıracağımız (tokenleştirme, tokenization) ve bu birimlerin belge vektöründeki değerleri (ağırlıklandırma, weighting)
  • Bu bölümde seyrek (sparse) temsiller kuracağız: belge vektöründeki bileşenlerin çoğu sıfırdır; 3. bölümde yoğun (dense) vektörlere geçeceğiz
  • Seyrek temsilleri kullanan basit modeller; etiketli örnek sayısının az olduğu, uzun belgelerin konularına göre sınıflandırıldığı veya birebir kelime eşleşmesinin önemli olduğu görevlerde güçlü bir baseline (karşılaştırma modeli) olabilir

Ön işleme, hangi bilginin modele ulaşacağını belirlediği için modelleme sürecinin bir parçasıdır.

Boşluklardan bölmek — ve geriye kalan kararlar

text = "P-101'in pompası arızalandı; sorun salmastrada (yine!). Pompa değiştirildi."
print(text.split())
["P-101'in", 'pompası', 'arızalandı;', 'sorun', 'salmastrada',
 '(yine!).', 'Pompa', 'değiştirildi.']
  • arızalandı;, Pompa ve P-101'in ayrı birimler olarak korunuyor; başka bir metinde arızalandı, pompa veya P-101 geçseydi farklı token’lar sayılacaktı
  • Üç karar: Pompa ile pompa aynı biçime mi dönüştürülsün? Noktalı virgül korunsun mu, çıkarılsın mı? P-101'in içindeki ek korunsun mu?
  • Kelime düzeyinde çalışan bir tokenizer; noktalama işaretleri, kesme işaretleri, URL’ler, sayılar ve kısaltmalar için ayrı kurallar kullanabilir

Normalleştirme kararları, token sınırlarını belirlemekten ayrı işlemlerdir. Yararlı bir ayrımı silip silmediklerini göreve göre değerlendirmek gerekir.

Normalleştirme merdiveni

İşlem Olası yararı Olası kaybı veya maliyeti
Küçük harfe çevirme Pompa = pompa: iki sütun tek sütunda birleşir, sayımları toplanır AŞ (anonim şirket) ile aş (yemek) aynı biçime dönüşür; str.lower() Türkçeye özgü I–ı ve İ–i eşlemelerini uygulamaz
Noktalama işaretlerini çıkarma seçilen işaretleri çıkararak arızalandı; biçimini arızalandı ile eşleştirebilir ayrım gözetmeden silmek P-101 gibi tanımlayıcıları, ondalık gösterimleri ve URL’leri değiştirebilir
Stop word çıkarma listedeki kelimeleri sayımın dışında bırakır: bu bölümün derleminde bütün token’ların %43,9’u listede not bulunuyorsa olumsuzluk bilgisi kaybolabilir
Gövdeleme (stemming) farklı kelime biçimlerini ortak bir çıktıda birleştirebilir: Porter replaced kelimesini replac yapar farklı kelimeleri yanlışlıkla birleştirebilir: university de universe de univers olur
Lemmatizasyon kelimeyi uygun sözlük biçimiyle eşleştirmeyi amaçlar: gidiyorum için gitmek sözlük, kurallar, sözcük türü veya bağlam bilgisi gerektirebilir; belirsiz biçimlerde hata yapabilir

Bu tablo, işlem hattını (pipeline) kendiniz kurduğunuz durumlar içindir. Metni ön eğitimli bir modele verecekseniz, modelin eğitim sırasında kullandığı tokenizer’a ve ön işleme varsayımlarına uymanız gerekir.

Merdiveni okumak

  • Tablo zorunlu bir uygulama sırası değildir; gövdeleme ile lemmatizasyon çoğu durumda birbirinin alternatifidir
  • Her işlem, kaldırdığı ayrımın görev açısından gerekli olmadığı varsayımına dayanır
  • Küçük harfe çevirme bazı konu sınıflandırma görevlerinde yararlı olabilir; adlandırılmış varlık tanımada (named entity recognition, NER) ise büyük harflerden gelen bir ipucunu kaldırır
  • Modelin gerekliliklerini ve verinin özelliklerini dikkate alın

Öneriler bir başlangıç noktasıdır: uygun seçenekleri doğrulama verisinde karşılaştırın ve son değerlendirme için test kümesini ayrı tutun.

Türkçede küçük harf: varsayılan dönüşüm Türkçe değil

"İSTANBUL".lower()                # 'i̇stanbul': başta U+0069 + U+0307; toplam 9 kod noktası
"İSTANBUL".lower() == "istanbul"  # False
"IĞDIR".lower()                   # 'iğdir' — 'ığdır' olmalıydı
  • Python’un str.lower() metodu Unicode’un varsayılan küçük harf eşlemesini uygular; Türkçe için bir yerel ayar parametresi almaz. Türkçede iki ayrı eşleme vardır: I → ı ve İ → i
  • İlk sonuç yalın bir i ile değil, U+0069 + U+0307 ile başlar
  • Hata mesajı üretilmez; ancak aynı kelimenin farklı yazımları eşleşmeyebilir: varsayılan CountVectorizer, İSTANBUL girdisinden stanbul token’ını üretir

Ön işleme düzeltildiğinde sözlüğün ve ona bağlı modellerin de yeniden oluşturulması gerekebilir.

Gövdeleme ile lemmatizasyon aynı işlem değil

Ne yapar Örnekler
Gövdeleme (Porter) çekim veya yapım eklerine yönelik kurallar uygular; sonucun sözlükte bulunan bir kelime olmasını garanti etmez replaced → replac; university ve universe → univers
Lemmatizasyon kelimeyi sözlükteki temel biçimiyle eşleştirmeyi amaçlar: fiiller mastar hâliyle, isimler yalın hâliyle gidiyorum → gitmek; left için bağlam gerekebilir
Snowball Türkçe gövdeleyicisi bu kitapta kullanılan gövdeleyici kitaplarımızdan → kitap; kullanıyorum → kullanıyor; kullandık → kulla
  • Ön eğitimli bir transformer modelinde, modelin tokenizer’ını ve beklediği ön işleme adımlarını kullanın; gövdeleme veya lemmatizasyonu kendiliğinizden eklemeyin
  • Sözcüksel arama veya seyrek sınıflandırmada gövdeleme yararlı olabilir; ancak aracınızın hangi biçimleri birleştirdiğini kontrol edin: Snowball kullanıyorum ile kullandık biçimlerini birleştirmez

Porter 1980

Stop word’ler: türlerin %0,4’ü, token’ların %43,9’u

  • scikit-learn’ün İngilizce stop word listesinde 318 madde bulunur; bu bölümdeki 20 Newsgroups ölçümünde, kullanılan tokenleştirme kuralıyla bunların 311’i derlemde görülür
  • Bunlar 78.649 farklı token türünün yaklaşık %0,4’ünü, derlemdeki bütün token’ların ise %43,9’unu oluşturur: token’ların neredeyse yarısı sayımın dışında kalır
  • Bu oran, metnin bayt büyüklüğünün veya seyrek matrisin belleğinin aynı oranda azalacağı anlamına gelmez
  • not gibi görev açısından önemli bir kelime çıkarılırsa, anlamı ayırt etmek için gereken bilgi kaybolabilir

Stop word çıkarırken bilgi kaybını değerlendirin. Çıkarmanın yararlı olup olmadığı göreve bağlıdır.

Kelime düzeyinin sınırı

  • Bu bölümün geri kalanında token, normalleştirilmiş bir kelime biçimidir; kelime torbası ve TF-IDF için bu birim yeterlidir
  • Sözlük sabitlendikten sonra gelen bir metinde, sözlükte bulunmayan kelime biçimleriyle karşılaşabilirsiniz: kelime düzeyinde bir temsil bu biçimlere sütun ayıramaz ve onları sayımın dışında bırakır
  • Türkçe gibi eklemeli bir dilde aynı gövdenin çok sayıda çekimli biçimi olduğu için bu durum daha sık yaşanır
  • Bugünün dil modelleri bu sınırı kelimeden küçük birimlerle aşar: sözlüğe kelimeleri değil, veriden öğrenilen kelime parçalarını (alt kelimeleri) koyar ve yeni bir kelimeyi bu parçalarla yazar

Alt kelime yöntemlerini, onları kullanan ön eğitimli modellerle birlikte 8. bölümde ele alacağız. Şimdilik kelimelerle devam ediyoruz.

Zipf ve Heaps: iki ayrı soru

  1. Bir derlemde en sık kelimelerle nadir kelimelerin frekansları nasıl dağılır? Zipf yasası
  2. Derleme daha fazla metin ekledikçe farklı kelime sayısı nasıl büyür? Heaps yasası
  • Zipf yasası belirli bir derlemdeki sıklıkların nasıl dağıldığını, Heaps yasası derlem büyüdükçe farklı kelime biçimlerinin sayısının nasıl değiştiğini betimler
  • Aralarında belirli varsayımlar altında bağlantı kurulabilir

İkisi de gözleme dayanan yaklaşık ilişkilerdir; tokenleştirmenin nasıl yapılacağını tek başlarına belirlemezler.

Lü, Zhang ve Zhou 2010

20 Newsgroups: 2,29 milyon token, 78.649 tür

tokens: 2288401  distinct types: 78649
top     10 types -> 20.99% of all tokens
top    100 types -> 46.99% of all tokens
top   1000 types -> 71.04% of all tokens
top  10000 types -> 92.50% of all tokens

types appearing exactly once: 38571  (49.0% of the vocabulary,
                                      1.69% of all tokens)
  • Tür (type), bölme işleminin ürettiği her farklı karakter dizisidir; token ise bu dizinin metindeki her bir geçişidir: pompa yüz kez geçiyorsa bu, bir tür ve yüz token demektir
  • Türlerin yaklaşık %49’u yalnızca bir kez görülüyor; en sık on tür ise token’ların yaklaşık beşte birini oluşturuyor

Zipf yasası: yaklaşık bir kuvvet ilişkisi

\[f(r) \propto r^{-\alpha}\]

  • \(r\) türün sıklık sıralamasındaki konumu, \(f(r)\) geçiş sayısı; iki ekseni de logaritmik olan bir grafikte ilişki yaklaşık bir doğru olarak görünür
  • the’nin 106.425 geçişini ölçek alıp \(\alpha = 1\) seçersek onuncu sıra için yaklaşık 10.600 geçiş bekleriz. Gözlenen değer 26.985: bunun yaklaşık iki buçuk katı
  • Zipf–Mandelbrot biçimi, \(f(r) \propto (r + b)^{-\alpha}\), dağılımın başındaki biçime daha fazla esneklik tanır
sıra geçiş sayısı
1 106.425
2 62.043
10 26.985
97 3.027
1.113 221
10.352 13
77.121 1

Doğruyu veriden kestirilmiş bir model olarak değil, dağılımın biçimini özetleyen bir referans olarak alın.

Sözlük tasarımı için üç pratik nokta

  1. Sabit bir kelime sözlüğü yeni girdileri eksiksiz kapsamayabilir. Konusu ve kaynağı sınırlanmamış metinlerde yeni adlarla, parça numaralarıyla, yazım biçimleriyle ve bileşik kelimelerle karşılaşılır
  2. Seyrek türler için güvenilir istatistik öğrenmek zordur; yine de nadir bir terim değerli olabilir. Bu derlemde CountVectorizer’ın varsayılan ayarlarıyla min_df=2, 101.631 sütunun 62.208’ini (%61) siler; silinen sütunlar token geçişlerinin yalnızca %3,4’ünü taşır. İngilizce stop word listesi ise 309 sütun siler, ama bu sütunlar geçişlerin %43’ünü taşır
  3. Bir terimin sıklığı, görev açısından ne kadar yararlı olduğunu tek başına belirlemez. Çok sayıda belgede bulunan terimler, belgeleri birbirinden ayırmada daha az işe yarayabilir; az belgede geçmek de tek başına anlam veya yararlılık güvencesi değildir

Sayılar bu derleme ve bu eşiğe aittir; filtrenin başarıyı nasıl etkilediği ayrıca ölçülmelidir.

Heaps yasası: sözlük büyümeye devam eder

|V| ~ 16.5 * N^0.580
new types in the first 100,000 tokens: 13497
new types in tokens 2,180,001-2,280,000: 1814

\[|V(N)| \approx K N^{\beta}\]

  • \(K\) ve \(\beta\), derleme ve ön işleme kararlarına bağlıdır: burada \(K \approx 16{,}5\) ve \(\beta \approx 0{,}58\); Reuters-RCV1 derlemi için bildirilen değerler \(K \approx 44\) ve \(\beta \approx 0{,}49\)
  • İlk 100.000 token 13.497 tür getirirken, ölçtüğümüz son 100.000 token yalnızca 1.814 yeni tür getiriyor. Yeni türler gelmeye devam ediyor, ama giderek daha seyrek.

Heaps yasası, bu büyümeyi belirli bir aralıkta yaklaşık olarak modelleyen ampirik bir düzenliliktir; kanıtlanmış bir teorem değildir.

Heaps 1978 · Manning, Raghavan ve Schütze 2008

Her zaman ilk 50 listenize bakın

Bu sayımda en sık ikinci token 'ax: 62.043 kez geçiyor ve to, a ve of’un önünde. Bu, doğal dilde kullanılan bir kelime değil.

  • Geçişlerin tamamı 11.314 belgenin 13’ünde toplanıyor; bunların 12’si, roman.bmp adlı bir dosyayı on dört parça hâlinde taşıyan gönderilerin 3–14. parçaları; satırlar >'AX>'AX>'AX biçiminde
  • Tek bir belge, yani 12. parça, 62.043 geçişin 11.147’sini karşılıyor
  • Toplam geçiş sayısına göre ikinci sırada; buna karşılık belgelerin yalnızca %0,1’inde bulunuyor: derlem toplamındaki sıklık ile belgeler arasındaki yaygınlık farklı şeylerdir
  • TF-IDF doğal dil dışındaki içeriği kendiliğinden tanımaz: az belgede görülen bir gürültü dizisi yüksek IDF alabilir

En sık token’ların listesine bakmak, ağırlıklandırmadan önce veri ve ön işleme sorunlarını fark etmenin basit bir yoludur.

Birbirinden ayrılacak üç sayım

  1. bir terimin belirli bir belgedeki geçiş sayısı
  2. bütün derlemdeki toplam geçiş sayısı
  3. terimi içeren belge sayısı
  • 'ax örneğinde derlem toplamı yüksek, terimi içeren belge sayısı ise düşüktür
  • Token’ın biçimi bir ön işleme kararına bağlıdır: scikit-learn’ün varsayılan token_pattern ayarı aynı belgelerden ax token’ını üretir; ax bu ayarla da 62.387 geçişle the’dan sonra ikinci sıradadır

TF-IDF, her belgedeki terim sıklığını (TF), terimin kaç belgede bulunduğundan hesaplanan IDF ağırlığıyla birleştirir.

Karakter dizisinden vektöre: altı adım

corpus = [
    "pompa yine arızalandı",              # d1
    "pompa yine değiştirildi",            # d2
    "vana yine arızalandı",               # d3
    "salmastra yine kaçırdı ve onarıldı", # d4
]
  1. Dizin: arızalandı→0, pompa→4, yine→8
  2. One-hot: pompa = [0 0 0 0 1 0 0 0 0]
  3. Topla = sayımlar: [1 0 0 0 1 0 0 0 1]
  1. TF-IDF ağırlıkları: [1,51 0 … 1,51 … 1,00]
  2. L2 normalleştir: [0,64 0 … 0,64 … 0,42]
  3. Karşılaştır: cos(d1, d3) = 0,528

Gösterilen her sayı, kodun d1 = "pompa yine arızalandı" için fiilen ürettiği sayı.

1. adım · sözlük sadece bir dizindir

from sklearn.feature_extraction.text import CountVectorizer

cv = CountVectorizer()
X = cv.fit_transform(corpus)
print(cv.get_feature_names_out())
['arızalandı' 'değiştirildi' 'kaçırdı' 'onarıldı' 'pompa' 'salmastra'
 'vana' 've' 'yine']
  • Sütun numarası terimin sözlükteki adresidir; kendi başına anlamsal yakınlık belirtmez
  • Dokuz terim var, yani buradan sonraki her vektör \(\mathbb{R}^9\) uzayında yer alıyor
  • Sütunları hangi sırayla numaralandırdığımız, eğitimde ve kullanımda aynı eşlemeyi koruduğumuz sürece sonucu değiştirmez

2. adım · one-hot: vektör olarak kelime

index of 'pompa': 4
one-hot: [0 0 0 0 1 0 0 0 0]
pompa : [0 0 0 0 1 0 0 0 0]
vana  : [0 0 0 0 0 0 1 0 0]
        ------------------- konum konum çarp
        [0 0 0 0 0 0 0 0 0]  -> toplam = 0
  • Farklı kelimelerin one-hot vektörleri birbirine diktir: bu kodlamada pompa, vana’ya tam olarak salmastra’ya olduğu kadar benzerdir
  • Vektör kelimenin hangi sütunda tutulduğunu söyler; neye benzediği hakkında bir şey söylemez

One-hot burada kelime anlamını temsil etmenin nihai yolu değil, bir ara yapıdır. Öğrenilen yoğun vektörler, yani embedding’ler 3. bölümün konusu.

3. adım · belge, one-hot’larının toplamıdır

d1 tokens: ['pompa', 'yine', 'arızalandı']
d1 vector: [1 0 0 0 1 0 0 0 1]
  • Bir belgedeki her token’ın one-hot vektörünü toplayın: bir sayım vektörü. Kelime torbası budur: token’ların çoklu kümesi, sıra atılmış hâlde
  • Dört belge için de yapın: belge-terim matrisi
  • Standart gösterimde satırlar belge, sütunlar terimdir: burada 4 belge × 9 terim. Sağda devriğini gösteriyoruz
                d1  d2  d3  d4
arızalandı       1   0   1   0
değiştirildi     0   1   0   0
kaçırdı          0   0   0   1
onarıldı         0   0   0   1
pompa            1   1   0   0
salmastra        0   0   0   1
vana             0   0   1   0
ve               0   0   0   1
yine             1   1   1   1

4. adım · her kelime aynı ağırlığı hak eder mi?

  • yine dört belgenin hepsinde geçiyor: her karşılaştırmaya katkı veriyor ama hiçbir şeyi ayırt etmiyor. vana bir kez geçiyor ve d3’ü ayırt eden tek şey o. Ham sayımlar ikisine aynı muameleyi yapar

Bir terime yüksek ağırlık vermek için iki şey isteriz:

  1. Bu belgede sık geçsin. Bunu ölçen çarpan TF’dir
  2. Bütün belgelerde sıradan biçimde geçmesin. Bunu ölçen çarpan IDF’dir
  • Terim frekansı, zaten elimizdeki ham sayımdır: scikit-learn bu sayımı belge uzunluğuna bölmez

TF-IDF, bu iki sorunun cevaplarının çarpımıdır. “TF-IDF” tek başına bir şartname değildir: bir sayıyı raporlarken hangi varyantı kullandığınızı yazın.

Neden df’nin tersi — ve neden logaritma

  • Belge frekansı (document frequency, df), \(\mathrm{df}(t)\), kelimenin en az bir kez geçtiği belge sayısıdır. Ağırlığın df arttıkça düşmesini istiyoruz, o hâlde tersini alıyoruz
  • Ham tersleme, yani \(1/\mathrm{df}\), çok geniş bir aralık verir: bin belgelik bir koleksiyonda tek belgede geçen bir terim 1, her belgede geçen bir terim 0,001 alır
  • Logaritma bu aralığı sıkıştırır: \(\log(n/\mathrm{df})\) aynı koleksiyonda \(\ln 1000 \approx 6{,}9\) ile 0 arasında kalır ve belge frekansını her ikiye katlamak aynı miktarı (\(\ln 2 \approx 0{,}69\)) götürür

\[\mathrm{idf}(t) = \ln\!\left(\frac{n}{\mathrm{df}(t)}\right)\]

İkinci gerekçe bilgi kuramından gelir: belgelerin eşit olasılıkla seçildiği bir modelde \(\log(n/\mathrm{df})\), seçilen belgenin terimi içermesi olayının öz bilgisidir.

Spärck Jones 1972 · Robertson 2004

scikit-learn’ün düzleştirilmiş IDF’si, elle

\[\mathrm{idf}(t) = \ln\!\left(\frac{1 + n}{1 + \mathrm{df}(t)}\right) + 1\]

  • \(1+\) terimleri düzleştirmedir: formül, sanki derlemde her terimi birer kez içeren fazladan bir belge varmış gibi davranır
  • Sondaki \(+1\), her belgede geçen bir terimin IDF değerini 0 yerine 1 yapar: terim sıfırlanmaz

\[\mathrm{idf}(\texttt{pompa}) = \ln\!\left(\frac{1+4}{1+2}\right) + 1 = 0{,}511 + 1 = 1{,}511 \qquad \mathrm{idf}(\texttt{yine}) = \ln\!\left(\frac{1+4}{1+4}\right) + 1 = 1\]

Bu, scikit-learn’ün birebir formülüdür; başka kütüphaneler ayrıntıda farklılaşır ve “sayılarım neden tutmuyor” sorusunun sık rastlanan kaynaklarından biri budur.

IDF: dört belgede ve gerçek derlemde

                df     idf
arızalandı       2  1.5108
değiştirildi     1  1.9163
kaçırdı          1  1.9163
onarıldı         1  1.9163
pompa            2  1.5108
salmastra        1  1.9163
vana             1  1.9163
ve               1  1.9163
yine             4  1.0000
the            df=  9477  df/N= 0.838  idf= 1.18
is             df=  7034  df/N= 0.622  idf= 1.48
car            df=   394  df/N= 0.035  idf= 4.35
encryption     df=   169  df/N= 0.015  idf= 5.20
gravitational  df=     8  df/N= 0.001  idf= 8.14
  • Solda: yine dört belgenin hepsinde geçiyor ve tam olarak 1,0 tabanına oturuyor; tek bir belgeye özgü her kelime 1,9163 alıyor
  • Sağda: gerçek derlemde yayılım çok daha geniş
  • Önce elle hesaplandı, sonra kütüphaneyle karşılaştırıldı: en büyük mutlak fark 0,0

Ağırlık, kelimenin kaç belgede geçtiğinin monoton azalan bir fonksiyonudur. Terimin içerik kelimesi olup olmadığını değil, belgeler arasındaki yaygınlığını gösterir.

5. adım · çarp, sonra normalleştir

counts        : [1 0 0 0 1 0 0 0 1]
times idf     : [1.5108 0.     0.     0.     1.5108 0.     0.     0.     1.    ]
l2 norm       : 2.3591
normalized    : [0.6404 0.     0.     0.     0.6404 0.     0.     0.     0.4239]
sklearn row d1: [0.6404 0.     0.     0.     0.6404 0.     0.     0.     0.4239]

\[\lVert v \rVert_2 = \sqrt{1{,}5108^2 + 1{,}5108^2 + 1{,}0000^2} \approx 2{,}3591 \qquad \frac{1{,}5108}{2{,}3591} = 0{,}6404 \qquad \frac{1{,}0000}{2{,}3591} = 0{,}4239\]

  • d1, pompa yine arızalandı: üç konum sıfırdan farklı, her birinin sayımı 1 ve her biri kendi IDF’siyle çarpılıyor
  • Elle kurduğumuz hesapla TfidfVectorizer sonucu, gösterilen dört ondalık basamakta uyuşuyor

Vektörü kendi uzunluğuna, \(\lVert v \rVert_2\)’ye bölmek L2 normalleştirmedir.

L2 normalleştirmesi neyi değiştirir

Benzer terimleri benzer oranlarda kullanan, biri 20, diğeri 2.000 kelimelik iki belgeyi, yalnızca biri uzun diye neden birbirinden uzak görmek isteyelim?

  • L2 normalleştirmesi, sıfır olmayan vektörün normunu 1’e getirirken bileşenlerin birbirine oranını korur: sıfır olmayan her belge vektörü birim küre üzerine taşınır
  • Bu adım olmadan iç çarpıma ya da Öklid uzaklığına dayanan her karşılaştırma — doğrusal bir sınıflandırıcının puanı dâhil — kısmen bir vektör büyüklüğü karşılaştırmasına dönüşür
  • Hiçbir etkin terimi kalmayan belge sıfır vektörü verir; onunla hesaplanan kosinüs \(0/0\), yani tanımsızdır. scikit-learn 0 kosinüs döndürür; bu bir uzlaşımdır: bu satırları sayın ve ayrı işleyin
  • Ham TF, düzleştirilmiş IDF ve L2 bileşimi scikit-learn’ün varsayılanıdır; başka araçlarda formül ve normalleştirme tercihleri değişebilir

Karşılaştırmada yalnızca yön, yani ağırlıklı terim bileşimi kalır. Sınıflandırma başarısına etkisini ise doğrulama verisiyle ölçeriz.

Salton ve Buckley 1988

6. adım · kosinüs uzunluğu değil yönü karşılaştırır

\[\cos(a, b) = \frac{a \cdot b}{\lVert a \rVert \, \lVert b \rVert} = \sum_{i} a_i b_i \quad \text{(ikisi de zaten birim uzunluktaysa)}\]

\[\cos(\text{d1}, \text{d3}) = \underbrace{0{,}6404 \times 0{,}5729}_{\texttt{arızalandı}} + \underbrace{0{,}4239 \times 0{,}3792}_{\texttt{yine}} = 0{,}3669 + 0{,}1607 = 0{,}528\]

  • Buradaki sıfır olmayan ve negatif bileşen içermeyen vektörlerde 1 aynı yönü, 0 ise ortak pozitif ağırlıklı terim bulunmadığını gösterir
  • Benzerliğin %70’ini arızalandı, %30’unu yine sağlıyor; üstelik iki kelime de her iki belgede tam olarak birer kez geçiyor. Ham sayımlarda ikisi eşit katkı verirdi

Ortak kelimelerden hangisinin kanıt sayılacağına ağırlıklandırma karar verir.

Aynı dört belge, iki ağırlıklandırma

       d1     d2     d3     d4          <- TF-IDF
d1  1.000  0.528  0.528  0.107
d2  0.528  1.000  0.144  0.096
d3  0.528  0.144  1.000  0.096
d4  0.107  0.096  0.096  1.000

       d1     d2     d3     d4          <- raw counts
d1  1.000  0.667  0.667  0.258
d2  0.667  1.000  0.333  0.258
d3  0.667  0.333  1.000  0.258
d4  0.258  0.258  0.258  1.000
  • Ham sayımda d1 ile d4’ün kosinüsü 0,26; oysa paylaştıkları tek kelime yine. TF-IDF, ortak yine teriminin göreli katkısını azaltarak bu puanı 0,11’e indiriyor

Kosinüs, iki vektör arasındaki açının kosinüsüdür. Anlamsal benzerliğin kalibre edilmiş bir yüzdesi değildir; oysa onu “%26 benzer” diye raporlamak bunu ima eder.

Neden kosinüs, neden Öklid uzaklığı değil?

İki kelime üzerinde ham sayım vektörü olarak çift Ham sayımlarda Öklid uzaklığı L2 normalleştirmesinden sonra
A (2, 1) ile B (20, 10) 20,12 — uzakta, ama B, A’nın tam 10 katı aynı nokta
A (2, 1) ile C (1, 4) 3,16 — en yakını, ama C’nin terim oranları farklı 49,4°’lik bir açı: \(\cos = 0{,}651\), uzaklık 0,836
  • Ham sayımlarla Öklid uzaklığı A’yı C’ye, B’ye olduğundan altı kattan fazla yakın bulur
  • L2 normalleştirmesinden sonra bütün vektörler birim küre üzerindedir ve orada iki ölçüt monoton biçimde ilişkilidir: \(\lVert a - b \rVert^2 = 2 - 2\cos(a,b)\)
  • Sıfır olmayan vektörler L2 ile normalleştirilmişse, tam en yakın komşu aramasında iki ölçüt aynı sıralamayı verir; sayısal eşiklerin ise dönüştürülmesi gerekir

Kosinüs yalnızca yöne bakar: terimlerin birbirine oranını karşılaştırır, toplam miktarını değil. Klasik metin işleme hatlarının karşılaştırmadan önce normalleştirmesinin sebebi bu.

Kelime torbasının yapamadıkları · kelime sırası

pair = ["pompa arızalandı ve vana sağlam",
        "vana arızalandı ve pompa sağlam"]
vocabulary: ['arızalandı','pompa','sağlam','vana','ve']
row 1: [1 1 1 1 1]
row 2: [1 1 1 1 1]
vectors identical: True
cosine similarity: 1.0
  • Kelime sırasını temsil edemez. “Kötü temsil eder” değil; hiç temsil edemez
  • Hangi ekipmanın arızalandığı konusunda birbirinin tam tersini söyleyen iki rapor, uzayda aynı noktadır

Temsil aşamasında atılan bilgi, daha güçlü bir sınıflandırıcıyla geri getirilemez.

n-gram’lar bilginin bir kısmını geri kazandırır

bigram vocabulary: ['arızalandı ve','pompa arızalandı','pompa sağlam',
                    'vana arızalandı','vana sağlam','ve pompa','ve vana']
cosine similarity: 0.25
vocabulary size: unigrams 5 -> bigrams 7
  • Tek kelime yerine komşu kelime çiftleri kullanınca iki rapor ayırt edilebiliyor
  • Maliyeti: aşağıdaki deneyde ikili n-gram (bigram) eklemek öznitelik sayısını 32.318’den 249.522’ye, yani 7,7 katına çıkardı ve doğruluk (accuracy) düştü
  • Dil tanıma, spam süzme ya da kısa metin sınıflandırma gibi işlerde n-gram’lar tek başlarına yeterli olabilir

Bağlam uzunluğu arttıkça öznitelik uzayı hızla büyür; uzun menzilli ve bağlama duyarlı ilişkiler için daha genel temsillere ihtiyaç duyarsınız.

Kelime torbasının yapamadıkları · olumsuzlama ve anlam

"sızıntı tespit edilmiş değil"  vs  "sızıntı tespit edilmiş"
vocabulary: ['değil', 'edilmiş', 'sızıntı', 'tespit']
raw counts  ->  cosine 0.866
TF-IDF      ->  cosine 0.777
  • değil de diğerleri gibi bir özniteliktir; kelime torbasının geri getiremediği şey neyin olumsuzlandığıdır
  • Stop word listenizde değil varsa — ki bazı hazır Türkçe listelerde bulunur — iki vektör birebir aynı hâle gelir (kosinüs 1)
  • Eş anlamlılığı ve çok anlamlılığı doğrudan kodlamaz: pompa arızalandı ile pompa bozuldu, pompa dışında hiçbir şey paylaşmaz

Olumsuzluğun kararı değiştirdiği görevlerde stop word listesini ayrıca denetlemek gerekir.

Bütün bunların hâlâ bir önemi var mı?

Dört haber grubu, 2.327 eğitim belgesi, 1.550 test belgesi, lojistik regresyon; hiperparametre araması yapılmadı.

raw counts               accuracy 0.767   features   32318
counts + stop words      accuracy 0.795   features   32014
tf-idf                   accuracy 0.831   features   32318
tf-idf + stop words      accuracy 0.853   features   32014
tf-idf + bigrams         accuracy 0.819   features  249522
tf-idf + sublinear tf    accuracy 0.843   features   32318

Bu tablo bir mekanizma gösterimi ve bir baseline karşılaştırmasıdır. Küçük farkları evrensel bir üstünlük olarak okumayın.

Altı satırdan dört çıkarım

  1. TF-IDF, ham sayımlara göre 6,4 doğruluk puanı kazandırıyor; ek eğitim belgesi toplamadan ve hiperparametre araması yapmadan
  2. Stop word atmak burada faydalı (+2,2 puan); duygu analizinde veya olumsuzluk tespitinde, liste görev için önemli kelimeleri çıkarıyorsa aynı adım zarar verebilir
  3. İkili n-gram’lar eklenince doğruluk düştü; öznitelik sayısı ise 7,7 katına çıktı. Daha çok öznitelik, daha yüksek doğruluk garantisi vermez
  4. sublinear_tf aynı yönü işaret ediyor (0,843’e karşı 0,831): ham sayımı \(1 + \log(\text{tf})\) ile değiştirir; IDF için kurduğumuz aralık sıkıştırma argümanının terim frekansı tarafına uygulanmış hâli

scikit-learn’ün kendi belgelendirmesi stop_words='english' ayarını sorunlu olarak niteliyor. Stop word’ler sonucunuz için önemliyse listeyi kendiniz yazın ve ekrana basın.

Bu sayılar ne kadar belirsiz?

  • 1.550 test belgesinde 0,83 civarındaki tek bir doğruluğun %95 aralığı kabaca ±1,9 puandır (binom yaklaşımı)
  • Altı model birebir aynı test belgelerini görüyor: uygun araç, McNemar gibi eşleştirilmiş bir testtir
Karşılaştırma Yalnızca ilki doğru Yalnızca ikincisi doğru p
TF-IDF ile ham sayım 119 20 2,4 × 10⁻¹⁸
TF-IDF + stop word ile TF-IDF 86 52 0,0048
TF-IDF + bigram ile TF-IDF 17 35 0,018
TF-IDF + sublinear tf ile TF-IDF 29 11 0,0064

Dört karşılaştırma yapıldığı için Bonferroni düzeltmesiyle eşik 0,05/4 = 0,0125 olur. TF-IDF, stop word ve sublinear_tf farkları bu eşiğin altında kalıyor; bigram farkı kalmıyor.

McNemar 1947

Dört dersin ikisi görev değişince tersine dönebiliyor

  • Buradaki her sayı uzun belgeler üzerinde İngilizce konu sınıflandırmasından geliyor
  • Türkçe ürün yorumlarında — kısa belgeler, konu değil duygu — 4. bölümün ilk tablosu ikisinde de ters yönü gösteriyor: sabit etiket bütçesinde en büyük kazancı ikili n-gram’lar veriyor, düz sayım da TF-IDF’i geçiyor
  • Ama ikinci sonuç IDF’ten gelmiyor: o bölümün ablasyonuna göre asıl kaybı L2 normalleştirmesi getiriyor, IDF puanı geri kazandırıyor
  • Sonuç ayarlanmamış bir C’ye bağlıydı ve eşit ayar bütçesinde tersine dönüyor

Aktarılabilir olan ders sıralama değil, yöntem.

Okunabilir ve küçük

rec.autos            car, cars, engine, ford, oil, dealer, drive, price
sci.med              msg, doctor, disease, medical, pain, patients, treatment
sci.space            space, nasa, orbit, moon, launch, earth, spacecraft
talk.politics.guns   gun, guns, weapons, fbi, law, government, firearms
shape: (2327, 32318)
stored non-zeros: 234281
density: 0.312%
dense float64 would need :    601.6 MB
sparse csr actually needs:      2.8 MB
ratio: 213x
  • Her sınıf için en yüksek katsayılı terimler; yüksek katsayıyı tek başına nedensel açıklama saymayız
  • Matrisin %99,7’si sıfır: 601,6 MB yerine 2,8 MB. Bu, yalnızca seyrek matrisin saklama maliyetidir

Kelime torbası: güçlü ve zayıf yanları

Kelime torbası neden ayakta kaldı Neden yeterli değil
Küçük bir seyrek matris. Bu örnekte 2.327 belgenin matrisi 2,8 MB. GPU gerekmez Kelime sırası yok. pompa arızalandı, vana sağlam ile vana arızalandı, pompa sağlam aynı vektör
Okunabilir. Model kendi özniteliklerini adlandırır — gun, orbit, doctor Eş anlamlılık yok. araba ile otomobil, araba ile muz kadar ilgisizdir
Güçlü baseline. Burada 0,853; önce 3. bölümde ortalaması alınmış embedding’leri yendi, sonra 4. bölümde Türkçe veride tekrar yendi Çok anlamlılık yok. yüz için tek sütun var; surat mı, sayı mı, fiil mi, fark etmez
Kendi verinizin ötesinde eğitim verisi gerekmez. Ön eğitimli hiçbir şey, indirilen hiçbir şey, tedarikçi yok Sözlük dışı terimler yeni belgelerde görülebilir
Sabit hatla tekrarlanabilir. Aynı girdi aynı çıktıyı verir Olumsuzlamanın kapsamı yok. Torbanın geri getiremediği şey neyin olumsuzlandığıdır

Tablonun iki sütunu aynı temsilin güçlü yanlarını ve sınırlılıklarını gösteriyor. Hangi tarafın ağır bastığı, görevin gereksinimlerine bağlıdır.

Bunlar gerçekte nerede çalışıyor

Nerede Bu bölümdeki fikrin uygulamadaki hâli
Uber’de talep yönlendirme 2018’de anlatılan COTA: metni temizle, token’lara ayır, stop word’leri at, lemmatizasyon uygula, TF-IDF hesapla, LSA ile boyut indir; bu vektörlerden hesaplanan kosinüs benzerliği random forest tabanlı bir eşleşme modeline gider
Arama sıralaması Lucene — dolayısıyla Elasticsearch ve OpenSearch — belgeleri varsayılan olarak BM25 ile puanlar
Google’ın metin sınıflandırma rehberi karşılaştırdığı kodlamalar arasında en doğru sonucu TF-IDF n-gram’larının verdiğini bildiriyor
Melez erişim (hybrid retrieval) yoğun embedding aramasıyla seyrek BM25 araması birleştirilir: seyrek yarı birebir eşleşmeleri yakalar
İstenmeyen içerik ve kötüye kullanım filtreleme ilk hat filtresi olarak seyrek öznitelikler; feature hashing terimleri sabit sayıda sütuna eşler
Yakın kopya tespiti simhash parmak izleri; shingle kümeleri üzerinde MinHash — shingle, sabit uzunlukta bir kelime penceresidir

Metin sınıflandırma ve sözcüksel erişim gibi uygun görevlerde, TF-IDF tabanlı bir karşılaştırma modelini değerlendirmeye dâhil edin.

BM25 tek formülde

\[\mathrm{BM25}(q, d) = \sum_{t \in q} \mathrm{idf}(t) \cdot \frac{c(t,d)\,(k_1 + 1)}{c(t,d) + k_1\!\left(1 - b + b\,\frac{|d|}{\mathrm{avgdl}}\right)}\]

  • \(\mathrm{idf}\) çarpanı bizimkiyle aynı fikir (BM25 olasılıksal bir varyant kullanıyor)
  • Kesir, ham terim frekansının yerine doyuma giden bir frekans koyuyor: diğer değişkenler sabitken, \(c(t,d)\) büyüdükçe \(k_1 + 1\) sınırına yaklaşır
  • \(b \in [0,1]\), belge uzunluğunu yok saymak (\(b = 0\)) ile terim frekansını belge uzunluğunun derlem ortalamasına oranına bölmek (\(b = 1\)) arasında kademeli bir ayar sağlıyor
  • Lucene 9.12.1’in BM25Similarity sınıfında varsayılanlar \(k_1 = 1{,}2\) ve \(b = 0{,}75\) değerleridir

L2 normalleştirmesinin ele aldığı aynı derdi — uzun belgeler sırf uzunluklarıyla kazanmasın — başka bir formülle ve açma-kapama anahtarı yerine ayar düğmesiyle çözüyor; ikisi aynı işlem değil.

Robertson ve Zaragoza 2009

Sezgi kontrolü 1 / 6

TF-IDF matrisinizin 200.000 sütunu ve 5.000 satırı var. Endişelenmeli misiniz?

  • Bellek için değil: seyrek bir matriste gerçek bellek maliyeti büyük ölçüde sıfırdan farklı eleman sayısına bağlıdır, satır × sütun çarpımına değil
  • Asıl endişe istatistiksel: 5.000 gözleme karşı 200.000 öznitelik. Bu bir p ≫ n problemidir
  • Alışıldık çözümler güçlü düzenlileştirme (L2 ya da L1) ve min_df ile öznitelik sayısını azaltmaktır
  • Dört kategorili derlemde min_df=5, sözlüğü 32.318’den 6.281’e indiriyor — sütunların %81’i gidiyor. Silinen sütunlar token kullanımlarının %11,6’sını taşıyor

Sezgi kontrolü 2 / 6

IDF eğitim kümesinde mi yoksa bütün veride mi hesaplanmalı?

  • Denetimli sınıflandırma değerlendirmesinde sözlük ve IDF yalnızca eğitim bölümünden öğrenilir; doğrulama ve test verisine değiştirilmeden uygulanır
  • IDF veriden kestirilen bir parametredir; onu eğitim + test üzerinde hesaplamak test dağılımına dair bilgiyi özniteliklerinize sızdırır
  • scikit-learn’de: eğitimde fit_transform, testte transform. fit_transform’u iki kez çağırmak gerçek ve yaygın bir hatadır
  • Üretimde IDF vektörü, modelle birlikte sürümleyip yayına aldığınız bir bileşendir; her yeni batch (veri partisi) için yeniden hesaplanan bir şey değil

Sezgi kontrolü 3 / 6

Bir kelime her belgede geçiyor. TF-IDF ağırlığı nedir?

  • scikit-learn’ün düzleştirilmiş formülünde \(\mathrm{df} = n\) olunca IDF çarpanı \(\ln\frac{1+n}{1+n} + 1 = 1\) olur; normalleştirmeden önceki TF-IDF değeri terimin TF değeridir
  • Ders kitabının düzleştirilmemiş \(\log(n/\mathrm{df})\) formülünde tam olarak 0 olurdu ve terim vektörden düşerdi
  • smooth_idf=False seçildiğinde de scikit-learn dışarıdaki \(+1\) terimini korur: IDF bu ayarda da 1 olur; sonuç ders kitabı formülüyle aynı değildir

Sezgi kontrolü 4 / 6

Belge vektörlerini neden normalleştiriyoruz da öznitelik sütunlarını normalleştirmiyoruz?

  • İki normalleştirme farklı sorulara cevap verir: satır bazında L2 normalleştirmesi, sıfır olmayan belge vektörlerini birim norma getirir; karşılaştırma ağırlıklı terimlerin oranlarına dayanır
  • Sütunlardan sıfır olmayan ortalamalarını çıkarıp sonucu açıkça saklamak, mevcut sıfırları sıfırdan farklı değerlere dönüştürür: 2,8 MB’lık bu matris, yoğun bir float64 dizide yaklaşık 601,6 MB gerektirir
  • Bütün sütun ölçeklemeleri böyle değildir: StandardScaler(with_mean=False) seyrek yapıyı koruyabilir
  • Seyreklik, hangi işlemlerin uygulanabilir olduğunu belirleyen bir kısıttır

Sezgi kontrolü 5 / 6

Arama motorunuz “P-101” parça numarası için hiçbir şey döndürmüyor. Neden?

default    : ['101', '102', 'devre', 'dışı', 'pompası']
custom     : ['devre', 'dışı', 'p-101', 'p-102', 'pompası']
  • scikit-learn’ün varsayılan token_pattern kalıbı en az iki kelime karakteri ister ve tireyi aşmaz: P-101 sessizce 101’e döndü
  • Hiç sonuç gelmemesi, sorgu ile dizin arasındaki çözümleyici uyumsuzluğundan veya başka filtrelerden de kaynaklanabilir
  • Bunu önleyen alışkanlık: herhangi bir vektörleştiriciyi eğittikten sonra get_feature_names_out() çıktısını yazdırın ve okuyun

Sezgi kontrolü 6 / 6

2026’da kelime torbası ne zaman doğru seçimdir?

Aşağıdaki koşullardan birkaçının bir arada bulunması kelime torbası baseline’ını özellikle çekici kılar:

  • sınıf başına çok az etiketli örneğiniz var
  • sözlüğünüz alana özgü ve birebir eşleşme önemli: parça numaraları, gen adları, hukuki atıflar
  • her tahmini, üzerinizde yetkisi olan birine açıklamak zorundasınız
  • GPU’nuz yok ya da katı bir gecikme bütçeniz var
  • belgeleriniz kısa ve incelikli değil, uzun ve konusal

Tartışma için mülakat soruları

Bölümün mülakat sorularından beşi. Bölüm, soruları neyi sınadıklarına göre gruplar.

  1. TF-IDF’i hiç görmemiş birine anlatın. Sonra IDF teriminin neden logaritma kullandığını açıklayın
  2. Ham terim sayımları TF-IDF’ten ne zaman daha iyi olur?
  3. İkili n-gram eklediniz ve doğruluk düştü. Ne oldu?
  4. Stop word’leri atmak bir duygu analizi modeline neden bazen zarar verir?
  5. Gövdeleme mi lemmatizasyon mu — ve bugün ikisinden birini kullanır mıydınız?

Açıkça dile getirilmesi gereken kural: ön işleme göreve göre seçilmelidir; varsayılan diye uygulanmamalıdır.

Mülakat sorusu 1 / 2

Belge-terim matrisiniz 10⁶ × 10⁵. Bu matrisi nasıl saklar, onunla nasıl çalışırsınız?

  • Bir milyon belge, yüz bin kelimelik bir sözlük, yani \(10^{11}\) hücre: 8 baytlık float64 olarak yalnızca matrisin veri alanı 800 GB eder
  • Metin matrislerinde sıfırdan farklı hücre oranı tipik olarak %0,1 ile %1 arasındadır. Sıkıştırılmış seyrek satır (compressed sparse row, CSR) biçimi üç liste tutar: sıfırdan farklı değerler, her değerin sütunu ve her satırın nereden başladığı
  • %0,1 yoğunlukta bu \(10^8\) değer demek; kayıt başına 12 bayttan yaklaşık 1,2 GB: kabaca 670× kazanç
  • Seyreklik bir depolama numarası değil, hangi işlemleri yapabileceğinizi belirleyen bir kısıttır

Mülakat sorusu 2 / 2

Çevrimdışı iyi, üretimde kötü çalışan bir metin sınıflandırıcı eğittiniz. Hata ayıklama sürecinizi anlatın.

  1. Training/serving skew (eğitim/servis kayması): birebir aynı ön işleme hattı her iki yerde de mi çalışıyor — eğitilmiş TfidfVectorizer, sözlüğü ve IDF vektörü dâhil?
  2. Sözlük kayması: yeni ürün adları ve yeni hata kodları hiçbir sütuna düşmez; model onları hiç görmez
  3. Etiket dağılımında kayma
  4. Çevrimdışı değerlendirmede sızıntı; örneğin vektörleştiriciyi eğitim/test ayrımından önce eğitmek
  5. Ve ancak bundan sonra model

Daha derine inmek için

Amacınız Başlangıç kaynakları
Otuz dakikam var 3Blue1Brown videosu, scikit-learn metin öznitelikleri sayfası
TF-IDF ve bilgi erişimi tarafını derinleştirmek istiyorum Manning ve arkadaşlarının IR kitabı (idf ve BM25 sayfaları), scikit-learn belgeleri
Akademik referans istiyorum Jurafsky & Martin, özgün makaleler (Zipf, Heaps)
  • Bölümdeki liste uzun; hepsini okumanız gerekmiyor: önce ne istediğinize karar verin
  • Bağlantıların hepsi bölüm sayfasında

Akılda kalması gerekenler

  1. Tokenleştirme, metnin modele hangi birimlerle sunulacağına dair bir tasarım kararıdır
  2. Normalleştirme kuralları bazı yazım veya kodlama ayrımlarını birleştirebilir; hangilerinin korunacağı göreve ve kullanılacak modelin beklediği girdiye bağlıdır
  3. Kelime düzeyinde sabit bir sözlük, yeni metinlerdeki bütün kelime biçimlerini kapsayamaz; bugünün dil modelleri bu sınırı kelimeden küçük, veriden öğrenilen birimlerle aşar (Bölüm 8)
  4. Zipf, kelime frekansları ile sıraları arasındaki; Heaps ise işlenen metin miktarı ile gözlenen farklı terim sayısı arasındaki yaklaşık ampirik ilişkiyi betimler
  5. Kelime torbası bir belgeyi hangi terimlerin kaç kez geçtiğiyle temsil eder ve kelime sırasını kaybeder
  6. TF-IDF, diğer koşullar aynıyken, belgede sık geçen ve derlemin az sayıda belgesinde bulunan terime daha yüksek ağırlık verir
  7. Kosinüs benzerliği belge uzunluğunu değil vektörlerin yönünü karşılaştırır; L2 normalleştirmesi bu geometriyi kullanışlı kılar
  8. Kelime torbası hızlı, seyrek ve okunabilir bir karşılaştırma modelidir (baseline); ama sıra, olumsuzlama kapsamı ve anlamsal benzerlik gibi bilgileri doğrudan temsil edemez

Laboratuvar ve alıştırmalar

  • Bölümde altı alıştırma var: Temel, Uygulama veya İleri etiketli
  • 1. alıştırma: kendi alanınızdan on belge üzerinde bir CountVectorizer eğitin, get_feature_names_out() çıktısını yazdırın ve en az iki yanlış token bulun
  • 2. alıştırma: d3’ün TF-IDF vektörünü kâğıt kalemle hesaplayın, sonra TfidfVectorizer ile doğrulayın
  • 3. alıştırma: sınıflandırma tablosunu yeniden üretin, sonra bir satır ekleyin: min_df=5 ile TF-IDF

Bölüm: Veri Olarak Metin. Laboratuvar, notebooks deposundaki bölüm notebook’unu izliyor: tr/chapters/02-metin-veri/02-metin-veri.ipynb.