Bu doküman metin madenciliğinde sıkça karıştırılan TF.IDF skorunun mantığının anlaşılması için hazırlanmıştır. TF.IDF skoru bir dokümanda geçen kelime sıklığından ziyade dokümanlardaki sıklıklarını da hesaba katan bir skordur. Örneğin bir külliyatta en fazla geçen kelime ‘ve’, ‘veya’ gibi kavramlar olduğu halde TF.IDF değerine göre bu değerler en az puana sahip olacaktır.

Örnek Külliyat (Corpus)

Bir külliyat birden fazla dokümandan oluşan bir yapıdır.

library(tidytext)
library(readr)
library(dplyr)
df <- read_csv("ornek_metin_1")
df

Adım 1

Dokümanları tidyverse formatına çevirelim. 5 dokümanda 33 kelime çıkıyor ve bunların bazıları tekrar ediyor.

kelime_dokuman_listesi <- df %>% unnest_tokens(word,metin)
kelime_dokuman_listesi

Adım 2

Tekrar eden kelimeleri gruplandırarak. En sık geçen kelimeleri listeleyelim. Burada her bir kelimenin hangi dokümana ait olduğunu bilmek için count fonksiyonumuzda dokuman_no parametresini de unutmuyoruz. Eğer başka parametreler de olacaksa burada eklenebilir.

dokuman_bazinda_kelime_frekans_listesi<-kelime_dokuman_listesi %>% count(dokuman_no,word,sort = TRUE)
dokuman_bazinda_kelime_frekans_listesi

Adım 3

Her dokümanda (ayrı doküman numarası ile işaretlenen) içerisinde geçen toplam kelime sayısını da hesaplayalım. Bunun için dokuman_bazinda_kelime_frekans_listesi üzerinde dokümanları gruplandırdıracağız

dokuman_bazinda_kelime_frekans_listesi %>% group_by(dokuman_no)

Sonra da her bir dokümanda kaç kelime geçiyor görelim

her_dokuman_icin_toplam_kelime_adetleri <- dokuman_bazinda_kelime_frekans_listesi %>% group_by(dokuman_no) %>% summarize(total = sum(n))
her_dokuman_icin_toplam_kelime_adetleri

Adım 4

Şimdi her_dokuman_icin_toplam_kelime_adedi değeri tablomuz ile kelime Adım 2’de hazırladığımız dokuman_bazinda_kelime_frekans_listesi tablomuzu birleştirelim. Bu birleşimde aslında sadece her kelimenin hangi dokümanda geçtiği ve bu kelimenin ilgili dokümandaki tekrar adedi ve o dokümandaki tüm tekrar adedini listeledik. Mesela 3 nolu dokümanda türkiye kelimesi 2 kes geçmiş. Bu dokümanda toplam 7 kelime var.

yeni_kelime_dokuman_listesi <- left_join(dokuman_bazinda_kelime_frekans_listesi,her_dokuman_icin_toplam_kelime_adetleri)
## Joining, by = "dokuman_no"
yeni_kelime_dokuman_listesi

Bunu neden hesaplıyoruz. Şimdi göreceğiz. TF.IDF hesaplaması için buraya kadar gelmek durumundaydık. Şimdi onu yapacağız

Adım 5

Şimdi TF.IDF fonksiyonunu çalıştıarak, hesaplamada dokümanları atfen dokuman_no parametresini, kelime frekansına referans olarak n parametresini veritoruz.

İşte TF.IDF tablomuz:

tf_idf_tablosu <-yeni_kelime_dokuman_listesi %>% bind_tf_idf(word,dokuman_no,n)
tf_idf_tablosu

Şimdi bu neyi anlatıyor açıklayalım. Normalde Adım 2’de dokuman_bazinda_kelime_frekans_listesi içerisinde her doküman içinde her kelime kaç kez geçiyor hesapladık. Bunun yerine aşağıdaki gibi tüm külliyat genelinde en sık geçen kelimeleri listeleseydik. Durum şöyle olacaktır:

İşte külliyat genelinde salt kelime sayım tablomuz

kelime_dokuman_listesi  %>% count(word,sort=TRUE)

Yukarıda sadece tüm külliyat genelinde en çok geçen kelimeleri saydık. Ancak TF.IDF değerleri her bir doküman için ayrı hesaplanmış oldu. Burada sıkça kafa karışıklığı yapan önemli bir hususu vurgulamak gerekir. İkinci tablomuz (Kelime frekans) kelimelerin gruplandırılması ile oluşmuştur ve 21 benzersiz kelime olduğundan satır sayısı 21’dir. Öte yandan İlk tablomuz TF.IDF ise her bir doküman özelinde kelimeler için hesaplanmaktadır. O nedenle ilk tabloda mükerrer kelimeler görülmektedir. Peki neden hesapladık?

Doküman 3’e bakalım. En yüksek TF.IDF değeri bu dokümanda türliye kelimesindedir. Bu şu anlama gelir? Bu külliyat içerisinde ‘türkiye’ kelimesi ile **en ilgili’ doküman 3. dokümandır. Peki neden? Sadece 2 kez Türkiye geçtiği için mi? Hayır! Her bir dokümanda geçen kelimelere oranla şurada geçen formüllere göre yapılan hesaplamada en yüksek skora sahip olduğu için.

Peki nerede kullanılabilir bu değer? Bu değer aslında arama motorlarının aradığınız bir kelime ile en ilgili dokümanı bularken kullandığı algoritmaların temelidir. Herhangi bir metin madenciliği çalışmanızda herhangi bir kavramla en ilgili dokümanı ararken en yüksek TF.IDF değerini aratabilirsiniz. Söz gelimi TF.IDF tablomuzda Suriye ile ilgili dokümanlar 4 ve 5 nolu dokümanlar iken 4 nolu doküman daha yüksek TF.IDF değerine sahip olduğundan bu konudaki en ilgili metin olarak buraya odaklanabiliriz.

Kendi külliyatınızda en önemli kavramları çıkardıktan sonra bunlarla en ilgili örnek dokümnları ortaya çıkarırken bu TF.IDF kullanabilirsiniz.

Meraklısına TF.IDF formülü ve elle hesaplama.

Şimdi ilk külliyatımızı ve tf.idf tablomuzu önümüze koyalım. Daha sonra bir kavrama-doküman ikilisi için tf.idf değerini elle heaplayalım:

df
tf_idf_tablosu

Formüller şöyledir.

Term Frequency (Kelime Sıklığı:)

\[ tf = n/total \] Bunu 4. dokümandaki ‘suriye’ kelimesi için hesaplayacak olursak 4. dokümanda suriye geçme sayısı (n=2), 4. dokümanda toplam kelime sayısı (total=6) o zaman tf = 2/6 = 0.33. Bu arada unutmadan, bazı kaynaklarda total değeri yerine maksimum değeri kullanılıyor. Bu konuyu halen ben de anlamadım. Ancak R’da hazır gelen metin madenciliği kütüphanesine göre hesaplama anlattığım gibidir.

Şimdi gelelim biraz daha zor olan kısma. IDF hesabına. IDF yani (Inverse Document Frequency) ise şöyle hesaplanır. \(i\) kavramın geçtiği doküman sayısı \(n_i\), toplam doküman sayısı \(C\) olmak üzere

\[ idf = log_2(C/n_i) \] Şimdi yine 4. dokümanda bulunan ‘suriye’ kavramı için hesaplamayı yapalım. suriye kavramının geçtiği doküman sayısı 5’tir. Yani 5 dokümanın 5’inde de bu kavram geçmiştir. Tüm dokümanların sayısı da yine 5’tir. Bu durumda

\[ idf = log_2(5/5) = 0 \] Yani 4. dokümandaki suriye kavramı için idf değeri 0 olmaktadır. Son olarak tf. idf değeri tf ve idf değerinin çarpımı olacağından

\[ 0.28 x 0 =0 \] olacaktır. Suriye her dokümanda ortaya çıkan bir kavram olduğundan değeri düşmüştür.

Deney 1

Peki tüm külliyatı tek doküman yapıp analiz etsek sonuç ne olurdu? Bunun için tüm doküman no’ları aynı değeri atayarak deneme yapalım:

deney_1_df <- df
deney_1_df$dokuman_no = 0
deney_1_df
deney_1_kelime_dokuman_listesi <- deney_1_df %>% unnest_tokens(word,metin)
deney_1_dokuman_bazinda_kelime_frekans_listesi<-deney_1_kelime_dokuman_listesi %>% count(dokuman_no,word,sort = TRUE)
deney_1_dokuman_bazinda_kelime_frekans_listesi
deney_1_her_dokuman_icin_toplam_kelime_adetleri <- deney_1_dokuman_bazinda_kelime_frekans_listesi %>% group_by(dokuman_no) %>% summarize(total = sum(n))
deney_1_her_dokuman_icin_toplam_kelime_adetleri
deney_1_yeni_kelime_dokuman_listesi <- left_join(deney_1_dokuman_bazinda_kelime_frekans_listesi,deney_1_her_dokuman_icin_toplam_kelime_adetleri)
## Joining, by = "dokuman_no"
deney_1_yeni_kelime_dokuman_listesi
deney_1_yeni_kelime_dokuman_listesi %>% bind_tf_idf(word,dokuman_no,n)

Böyle bir durumda tf_idfdeğerleri sıfırlanmaktadır.Bunun nedeni idf değeridir. Bu değer, doküman adedinin ilgili kavramın geçtiği doküman adedine bölümünün logaritmasıdır. Doküman adedi=1, bir kavramın görüldüğü doküman sayısı da her zaman 1 olduğundan 1/1=1 logaritması da 0 olmakta ve \(tf.idf\) çarpımı sıfır çıkmaktadır.