ML.NET kullanarak çoklu dil sınıflandırma

Herkese yeniden merhaba,

Bu yazımda Microsoft’un makine öğrenmesi kütüphanesi olan ML.NET’i kullanarak dil sınıflandırma yapacağım. Örnek vermek gerekirse, dökümanları, yazıları vb. şeylerin dillerini tespit edebileceğiz. İşe kendi eğitim ve test verilerimizi oluşturarak başlayacağım.

Veri kümesinin hazırlanması

Veri kümemizi oluşturmak için Wikipedia sayfalarını kullandım. Bu blog yazısı için python üzerinde bir script dosyası hazırladım. Python üzerinde bulunan wikipedia kütüphanesi ile istenilen sayfaların içeriğini çekerek bunları test ve eğitim kümesi olarak ayırıyorum. Ben bu makale için üç dil seçtim; Türkçe, İngilizce ve İspanyolca. Bu her üç dil için neredeyse aynı oranda başlık seçmeye çalıştım. Bu script dosyası ile önceden belirlemiş olduğum sayfaların içeriklerini alıp python nltk (natural language toolkit) kütüphanesini kullanarak cümlelere bölüyorum. Ve ardından oranında test/eğitim verilerimi ayırıyorum. Eğer veri kümesini genişletmek istersek script dosyamıza yeni makaleler ekleyebiliriz. Örneğin;

Ardından komutu ile çalıştırdığımızda train.txt ve test.txt dosyasımızı oluşturacak. Oluşan dosyaların formatı aşağıdaki gibidir

Ayıraçı karakteri olarak belirledim.

Modelin hazırlanması

Sıra modelimizi hazırlayamaya geldi. Ben bu makaleyi ML.NET 0.5.0 versiyonu ile hazırlamaya başlamıştım ancak 0.6.0 versiyonunda eski API’ların hepsi Legacy namespace’inin altına taşınarak yeni yapıya geçince, ben de bu yeni halinin oturmasını bekledim ve sonunda 0.9.0 versiyonu ile birlikte kodumu yeniden düzenleyerek makaleme devam edebildim.

Pipeline ve Model

Hazırlamış olduğumuz verileri ML.NET API tarafından tanıtmamız gerekiyor. ML.NET temel olarak bir ana sınıf ile ilerliyor o da sınıfı, bu sınıf ile birlikte verilerimizi tanımlıyoruz.

methodu ile birlikte girilen verilerin şemasını belirliyoruz. Read methodu ile bu şema dosyalarının yollarını birbirine bağlıyoruz. Ayrıca belirtmek isterim ki, buraya kadar hiç bir dosya yükleme işlemi yapılmadı.

Sıra da pipeline dediğimiz, bir dizi işlemi ardı ardına yapmakta olan veri yapısını oluşturacağız. Burada yapının güzelliğinden bahsetmek istiyorum, verilmiş olan verilerin teker teker sonuç kısmına kadar hangi işlemlerden geçeceğini alttaki kod parçacığında belirtiyoruz.

  1. Öncelikle, “Label” değişkeni string kabul edilmemekte bu yüzden onu ML.NET içerisinde bulunan KeyType tipine çeviriyoruz. MapValueToKey(“Label”)
  2. Daha sonra verilen cümlelerdeki özel karakterleri/büyük küçük harfleri kaldırıyoruz (normalize) ediyoruz. NormalizeText(“Sentence”, “NormalizedSentence”). Burada yakalanması gereken nokta, normalize edilmiş veri artık “NormalizedSentence” olarak adlandırılması.
  3. Burada ML.NET’in bir özelliği olan FeaturizeText methodunu kullanacağız. Verilen text değerini n-gramlara ayırmakta, örneğin 2-gram için “merhaba” kelimesini “me”, “er”, “rh”, “ha”, “ab”, “ba”. Şeklinde ayırıp bir dizi oluşturmaktadır. Burada dikkat edilmesi gereken nokta pipeline üzerinde ML algoritması verilmeden önce “Features” alanının oluşması lazım. O yüzden bu methottan çıkan değere “Features” ismini veriyoruz.
  4. Sıra ML algoritmasını seçmekte, ben Naive Bayes algoritması ile devam edeceğim.
  5. En son olarak da yaptığımız tüm bu iş hattından çıkan KeyType tipindeki sonucumuzu “Label” da ki değerlere geri çeviriyoruz.

Şimdi bu pipeline’a ilk aşamada oluşturmuş olduğumuz IDataView arayüzümüzü verip modelimizi oluşturacağız. (Şimdi dosyaları okumaya başladık !)

Artık bu model sınıfımız ile birlikte tahminlerimizi gerçekleştirebiliriz. Öncelikle tahmin mekanizması için 2 adet sınıfa ihtiyacımız var, biri yukarıda tanıtmış olduğumuz pipeline’a eş değer olan sınıf (Label ve Sentence). Diğeri ise sonuç sınıfımız. Bunları tanımlayarak başlıyoruz.

Tek bir cümle ile modelimizi test edelim. Blizzard’ın ünlü kart oyunu Heartstone’un ispanyolca kısmından aldığım bir cümleyi test etmek için kullanacağım.

Veee sonuç beklediğimiz gibi çıkıyor !

Modelimiz ne kadar başarılı oldu ?

Sıra modelimizi değerlendirme sürecine geldi. Veri kümesinin hazırlanması kısmında gerçek verinin 1/4'ünü bu aşama için ayırmıştık.

İlk satırda modelimiz ile test verimizi ilişkilendiriyoruz, ikinci satırda ise bu ilişkilendirdiğimiz modeli değerlendirmeye alıyoruz.

Görüldüğü üzere doğruluk değerimiz yüksek çıktı ama bu aklımıza başka bir sorunu getirebilir. Modelimiz overfit mi oldu ? bu yüzden veriyi ve modeli daha detaylı inceleyip ona göre bakmamız gerekecek ama ben daha kolaya kaçacağım ve makaleyi de uzun tutmamak adına twitter üzerinde modelimizi test edeceğim.

Bunun için Netflix’in Türkiye (netflixturkiye), Amerika (netflix) ve İspanya (NetflixES) twitter hesaplarının son 400 tweetini test edeceğim. Reply tweetlerini exclude ediyorum.

Not: İçerisinde sadece link, resim ve ya mention içeren tweetleri doğru tahmin edemiyor haliyle.

Örnek kodumuz bu şekilde siz isterseniz farklı tweet hesaplarında deneyebilirsiniz. (twittersettings.json dosyası oluşturup API authentication bilgilerini girmeniz gerekmektedir.)

Sonuçlar istediğimiz türde çıkıyor, büyük bir oranda doğru tahmin edilmiş. tweet.txt dosyasından benim makaleyi yazarken ki sonuçlarıma bakabiliriz. Dosyayı incelediğimizde en çok fark İngilizce olanda var, bakıldığında ispanyolca tweetler atıldığını görebiliyoruz. Ayrıca bir kaç kelimeyi de tanıyamadığını gözlemleyebiliyoruz. Bunun için eğitim havuzumuzu genişletmemizde fayda var.

Sonuç

Bu yöntem ile metinleri belirli özniteliklere göre sınıflandırabilirsiniz. Son olarak bu makaledeki kaynak koda aşağıdan ulaşabilirsiniz.

Kaynaklar

http://www.diva-portal.org/smash/get/diva2:839705/FULLTEXT01.pdf

ITU. CE. LCWaikiki www.alimozdemir.com

ITU. CE. LCWaikiki www.alimozdemir.com