Bu yazımda öğrencilerimin sıklıkla sorduğu metin sınıflandırması (text classification) konusunda basit bir kod yazıp hangi bölümlere bakmaları gerektiği hakkında bilgi vermeye çalışacağım. Benimde fazla kullanmadığım Python Scikit-Learn kütüphanesini kullanacağız. Metin sınıflandırması nedir ile başlayalım.
Metin sınıflandırma metin madenciliğinin konularından biridir. Metin madenciliği metinler üzerinden bilgi çıkarımı yapmayı amaçlar. Metin sınıflandırmada ise sınıflandırma metotları kullanarak bir bilgi çıkarımı yapılır. Sınıflandırma işlemi için bir eğitim verisi gerekir. Bu eğitim verisinden elde edilen model üzerinden yeni gelen metinlerin tahmini yapılabilir. Örneğin, sinema yorumlarını topladık ve olumsuz/olumlu yorumları işaretledik. Bu veri bizim eğitim veri setimiz oluyor.
Veri setinin hazırlanması
Bu örneğimizde 10 cümleyi amazon Türkiye üzerinden topladım ve olumsuz(0)/olumlu(1) olarak bir CSV (comma-separated values – literatürde sıklıkla kullanılır) dosya şeklinde kaydettik. Örnek eğitim verimiz:
1 2 3 4 5 6 7 8 9 10 11 |
Sentence,NegPos Ürünü kargo teslim süresi içerisinde teslim aldım. Aldığım ürün ekranin sağ ve sol iki taratan yukarıdan aşağıya doğru ince ince beyaz noktalar çizgi halinde. Bundan ötürü memnun kalmadım ürünü iade edip değiştirilmesini istiyorum.,0 Elime ulaştığı ilk gün kullanmaya başladım bir kaç saat içinde alet kapandı ve açılmadı. Amazona olan güvenim sarsıldı..,0 İncecik bir ssd disk a3 zarf içerisine konur mu? İlk defa böyle birşey gördüm. Cihaz ezilmiş ve yamulmuş halde geldi.,0 İlanda ürün korea yazıyor gelen ürün cin malı yazıyor ürün hiç çalışmadı yani arızalı çıktı geri iade edeceğim,0 Büyük hevesle almama rağmen ürün bozuk çıktı..iade edilmesine rağmen param hala yatmadı,0 Fiyat performans ve güncel sayılabilecek işletim sistemi ile güzel tablet.,1 Güzel fp ürünü çok memnun kaldım tskler,1 Macbook Pro mid. 2012 bilgisayarım için aldım. Bilgisayarımın açılış ve kullanım hızı oldukça arttı. Ürün gerçekten çok kaliteli. Piyasadaki en iyi fiyatı sunan Amazon.com.tr ye teşekkürler.,1 Windows10 sıfırdan yüklemesi 1dk sürdü pc açılısı 1 sn sürüyor varın hızını siz hesap edin. 250gb yerine 500 gb alınabilir,1 Bilgisayar şuan aldığımdan 5 kat daha hızlı. Ayrıyeten PC den çıkan harddiskiniz için harddisk kutusu alıp takın harici olarak taşıyın. Veya CD rom yerine şuanki harddiskinizi takıp ikisini de kullanabilirsiniz.,1 |
ornek_dataset.txt olarak kodu yazacağımız klasöre kaydettik. Şimdi, sıra bu dosyayı okutup Python tarafına taşımaya geldi. Bu noktada, CSV dosya okutmak için pandas kütüphanesi duymuştum. İlk okumada hata aldım, ancak aşağıdaki kod ile okumayı başardım. (UTF-8 ile ilgili bir hata mesajı verdi)
1 2 |
import pandas as pd data = pd.read_csv("ornek_dataset.txt", engine='python') |
data görüntüsü (print(data)) görüntüsü aşağıdaki gibidir.
1 2 3 4 5 6 7 8 9 10 11 |
Sentence NegPos 0 Ürünü kargo teslim süresi içerisinde teslim al... 0 1 Elime ulaştığı ilk gün kullanmaya başladım bir... 0 2 İncecik bir ssd disk a3 zarf içerisine konur m... 0 3 İlanda ürün korea yazıyor gelen ürün cin malı ... 0 4 Büyük hevesle almama rağmen ürün bozuk çıktı..... 0 5 Fiyat performans ve güncel sayılabilecek işlet... 1 6 Güzel fp ürünü çok memnun kaldım tskler 1 7 Macbook Pro mid. 2012 bilgisayarım için aldım.... 1 8 Windows10 sıfırdan yüklemesi 1dk sürdü pc açıl... 1 9 Bilgisayar şuan aldığımdan 5 kat daha hızlı. A... 1 |
“…” bu metnin devamı var anlamına geliyor. Python’ın sevdiğim bir özelliği, matrisleri de böyle küçültüyor. Şimdiki amacım cümleler ile sonucu birbirinden ayırmak. Bunun için iloc komutu ve “:” operatörü ile gerekli kolonları bir listeye aktarıyorum. iloc tamsayı tabanlı pozisyon üzerinden verileri elde etmek için uygun bir metot, “:” içinde Python Liste konusuna bakabilirsiniz.
1 2 |
sentences_training = [doc for doc in data.iloc[:,0]] classification_training = [doc for doc in data.iloc[:,1]] |
,0 ile cümleleri ve ,1 ile metinleri alıp for döngüsü ile dolaşıp, dönen sonuçlardan bir liste oluşturduk.
Cümleleri vektöre çevirme
Ne yazık ki, cümlelerin bilgisayar için bir anlamı yoktur. Bu verileri sayısal bir değere çevirmeliyiz, anca sayısal veriler üzerine sınıflandırma metotlarını kullanabileceğimizi unutmamalıyız. Vektörümüz: kelimelerden ve bu kelimenin cümlede olup olmadığını gösteren bir sayısal değerden oluşabilir.
1 2 3 4 |
CümleNo Ürünü kargo teslim ... 1 1 1 1 ... 2 0 0 0 ... … |
Ürünü, kargo, teslim gibi kelimeler ilk cümlede var iken diğer cümlede yok. Diğer tüm kelimelerde sistemde olacak. Tahmin edebileceğiniz şekilde büyük bir matrisimiz oldu. Bu matris sınıflama metotlarında artık kullanılabilir. Ancak günümüzde 1 ve 0 yerine tf, tf-idf gibi daha fazla anlam içeren sayısal değerler kullanılıyor. Scikit kütüphanesi TfidfVectorizer sayesinde bu işlemi çok kolay şekilde yapıyoruz. (tf-dif için bu blog yazıma bakabilirsiniz. Diğer taraftan internette birçok bilgi var. )
1 2 |
from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer(analyzer='word', lowercase = True) |
TfidfVectorizer sınıfından bir nesne oluşturuyoruz. (Diğer metinden vektör oluşturma yöntemleri için tıklayın.) TfidfVectorizer sınıfının birçok parametresi var. Biz kelimeler üzerinde çalıştığımız için analyzer=’word’ ve tüm harfleri lowercase = True ile küçük harfe çevirdik. Bu metni işleme aşamasında birçok ek işlem yapılabilir. Örneğin kelimelerin köklerini bulma (stemming), bazı kelimeleri matristen çıkarma (stopwords) gibi temel işlemler kullanılabilir. Burada bir uyarım olacak, “bu ürünü beğendim” ve “bu ürünü beğenmedim” iki cümlemiz olsun. Türkçe stemming uygularsanırsa, beğen kökü her iki kelime içinde (beğendim / beğenmedim) kullanılmış olur. “beğenmedim” kelimesi içindeki “me” nin anlamını kaybedeceğinizi unutmayın. Şimdi, vektörümüzü elimizdeki matrise uygun hale getiriyoruz.
1 |
sen_train_vector = vectorizer.fit_transform(sentences_training) |
Burada, fit_transform fonksiyonu ile tüm cümlelerdeki kelimeleri içeren ve tf-idf değerlerini içeren büyük bir dizi oluştu. Oluşan diziyi matrise dönüştürmek için toarray() fonksiyonu kullanılır.
1 |
print(sen_train_vector.toarray()) |
Çıktının bir kısmı:
1 2 3 4 5 6 7 |
[[0. 0. 0. ... 0.28463598 0. 0. ] [0. 0. 0. ... 0. 0. 0. ] [0. 0. 0. ... 0. 0. 0. ] ... [0. 0.19627544 0. ... 0. 0. 0. ] [0.23283969 0. 0.23283969 ... 0. 0. 0. ] [0. 0. 0. ... 0. 0.18841794 0.18841794]] |
Şimdi elimizde sınıflama metotları için uygun bir veri oluştu. Ben bu bölümde bilinen bir sınıflama metodunu kullanmaya karar verdim: Naive Bayes.
Naive Bayes sınıflama metodu ile model oluşturma
1 2 3 |
from sklearn.naive_bayes import GaussianNB clf = GaussianNB() model = clf.fit(X=sen_train_vector.toarray(), y=classification_training) |
GaussianNB sınıfından bir nesne oluşturup yukarıdaki verileri ve verilerin çıktısı (olumlu-1, olumsuz-0) değerleri içeren classification_training parametrelerini içeren fit fonksiyonu ile modelimizi oluşturduk. Bu modeli kaydedip, ihtiyacımınız olduğunda yukarıdaki işlemlere gerek kalmadan direkt kullanabilirsiniz. Artık modelimiz hazır. Yeni gelen cümleyi bu modele göre değerlendireceğiz.
Tahmin yapalım
Şimdi bir örnek cümle gönderip soralım, bakalım sistem ne diyecek:
1 2 3 4 |
sen_test_vector = vectorizer.transform(['bu kadar kötü bir ürün görmedim']) #print(sen_test_vector.toarray()) y_pred = model.predict(sen_test_vector.toarray()) print(y_pred) |
Buradaki ekran çıktısı “0” yani cümle “olumsuz”muş. Bir de olumlu cümle yazalım.
1 2 3 |
sen_test_vector = vectorizer.transform(['iyi bir ürünmüş.']) y_pred = model.predict(sen_test_vector.toarray()) print(y_pred) |
Sonuç “1”…
Basit bir model oluşturduk ve onun üzerinden tahmin yapabiliyoruz. Ancak 10 cümle ile eğitildiğimizi unutmayalım. 10 cümle içinde geçen kelimeleri kullandığımız için sistemimiz güzel cevaplar verdi ama bilinmeyen kelimeler ve zor cümleleri her zaman işimizi zorlaştırılır. Ayrıca, Türkçe yazarken İngilizce kelimeleri kullanmakta işin diğer bir zorluğudur. Hocam, “ben bir kelime havuzu yaparım ve gelen cümlede olup olmamasına bakarak sınıflama metotlarını kullanmadan bu işi çözebilirim” diyebilirsiniz. Ama unutmayın, unuttuğunuz her kelime size olumsuzluk olarak döner, ayrıca kelimelere ağırlık vermeniz zor bir süreçtir. Sınıflama metotları aslında bu sorunlar için bir çözüm sunuyor. Ama az bir eğitim verisi ile de iyi sonuçlara ulaşmanın zor olduğunu unutmayın. Konuya bir merhaba dedik, gerisi sizden…
Bol kodlu günler…
Tüm kodlar, jpyter