Yazan : Şadi Evren ŞEKER

Bu yazının amacı, bir makine öğrenmesi (machine learning) ve veri madenciliği (data mining) aracı olan ve iş zekası (business intelligence) gibi farklı alanlarda kullanımı olan WEKA aracının üzerinde yapılan eğitim modellerinin nasıl kaydedilip, farklı test kümeleri üzerine nasıl uygulandığını anlatmaktır.

WEKA arcını kullanan kişilerin yaşadığı bir durum, WEKA’nın en sık kullanılan ve en kolay ekranı olan Explorer ekranındaki eğitim (train) ve test kümelerinin aynı anda veriliyor olması ve farklı test kümelerinin verilemiyor olmasıdır. Oysaki WEKA’nın en kuvvetli özelliklerinden birisi olan, JAVA ile tam uyum sağlayan yapısı, yazılan kodlarda aynı eğitim modelinin tekrar tekrar eğitilmeden kullanılmasını mümkün kılmaktadır.

Yani modelimizi bir kere eğitip sonra çok farklı testler için kullanabiliriz. Mesela, bir güvenlik firmasının kamera üzerinden yüz tanıma programını yazdığımızı düşünelim. Elimizdeki yüzlerce personelin yüzlerini sisteme tanıtıp modelimizi eğittikten sonra bu eğitilmiş modeli, her yeni gelen kişi için kullanmak gerekir. Aksi halde her yeni kişi için yeniden yüzlerce kişinin yüzünü sistemde eğitmemiz ve bunun için zaman ve donanım kaynaklarını israf etmemiz gerekir ki pek de mantıklı bir yol olduğu söylenemez.

Deneme aşamasında, WEKA’yı konsoldan çağırmak iyi bir çözümdür.

java weka.classifiers.trees.J48 -t egitim.arff -d egitilmis.model

Yukarıdaki komut ile J48 karar ağacını, verdiğimiz egitim.arff dosyası üzerinden eğitiyoruz ve eğitilmiş modeli egitilmis.model isimli dosyaya kaydediyoruz.

java weka.classifiers.trees.J48 -l egitilmis.model -T test.arff

Yukarıdaki komutu ise istediğimiz kadar, istediğimiz farklı dosyalar ile çağırabiliriz. Burada ise bir önceki adımda kaydettiğimiz egitilmis.model dosyasını kullanarak test.arff dosyasındaki verilerin sınıflandırılmasını istiyoruz. egitilmis.model dosyasını oluşturduktan sonra ikinci adımı istediğiniz kadar farklı dosyaya uygulayabilirsiniz.

Yukarıdaki, ikinci komutu, istediğimiz kadar farklı test dosyası üzerine uygulamamız ve sonuçlarını almamız mümkündür. Ancak yukarıdaki yaklaşımda bir problem, yapmış olduğumuz eğitim ve test işlemlerinin yazılım ile entegre olamamasıdır.

Bunun için biraz java kodlamaya girip yukarıdaki işlemin aynısını JAVA kodumuza entegre etmeye çalışalım. Bu yaklaşımda, java’nın bir özelliği olan nesne serileme (object serialization) özelliğini kullanacağız.

Ancak öncelikle nesne serileme işlemini kısaca hatıraltalım. Nesne serileme, basitçe bir nesnenin bütün bilgilerinin dizgiye (string) çevrilmesidir. Bu çevirim ne işe yarar derseniz, hafızada (RAM) yaşayan nesne bir kere dizgiye (string) çevrildikten sonra artık dosyaya yazılabilir veya ağ üzerinden farklı bir kaynağa yollanabilir. Biz de bu özelliği, java hafızada bir nesne olarak tuttuğumuz eğitilmiş model üzerine uygulayacağız ve bu sayede nesnenin içindeki eğitilmiş modeli her seferinde tekrar tekrar kullanabileceğiz.

// Modelin tanimi
 Classifier cls = new J48();
 
 // Egitim
 Instances inst = new Instances(
                    new BufferedReader(
                      new FileReader("egitimkumesi.arff")));
 inst.setClassIndex(inst.numAttributes() - 1);
 cls.buildClassifier(inst);
 
 // modelin serilenmesi
 ObjectOutputStream oos = new ObjectOutputStream(
                            new FileOutputStream("egitilmis.model"));
 oos.writeObject(cls);
 oos.flush();
 oos.close();

Yukarıdaki kodda, öncelikle bir sınıflandırıcı nesnesini tanımlıyoruz. Ardından dosyayı okuyup bir instance nesnesine transfer edip cls.buildClassifier metodu ile verilen inst değişkenindeki nesneyi eğitim için kullanıyoruz. Artık bu satırdan sonra elimizde eğitilmiş bir model bulunuyor. Ardından eğitilmiş ve eğitim verilerini tutan modelimizi serileyerek bir dosyaya kaydediyoruz. Bunun için JAVA’nın sınıflarından birisi olan ObjectOutputStream sınıfının ve bu sınıfın writeObject metodunu kullanıyoruz. Son olarak açtığımız akışları (stream) kapatıyoruz.

Alternatif olarak WEKA’nın 3.3.5 versiyonundan sonraki sürümleri için weka’nın içindeki bir sınıfı da kullanabiliriz:

weka.core.SerializationHelper.write("egitilmis.model", cls);

Yukarıdaki tek satır ile, ilk kodda bulunan ObjectOutputStream sınıfının tanımı ve writeObject metodunun çağırılması işlemlerini tek bir adımda yapılabilir.

Şimdi gelelim oluşturduğumuz bu modelin test için kullanılmasına. Bunun için tersserileme (deserialization) uygulayarak daha önce dizgiye (string) çevirdiğimiz nesneyi, tekrar dizgiden (string) nesneye geri çevireceğiz. JAVA’nın sınıflarını kullanarak aşağıdaki şekilde bu kodu yazabiliriz:

ObjectInputStream ois = new ObjectInputStream(
                           new FileInputStream("egitim.model"));
 Classifier cls = (Classifier) ois.readObject();
 ois.close();

Yukarıda, ObjectInputStream sınıfını ve bu sınıfın readObject metodunu kullanarak, daha önce kaydettiğimiz egitim.model dosyasından veriyi okuyarak cls isimli nesneye yükledik. Artık bu nesneyi test kümesini sınıflandırmak için kullanabiliriz. Veya yine alternatif olarak, weka’nın 3.3.5 versiyonu sonrası sürümleri ile gelen aşağıdaki satırı kullanabiliriz:

Classifier cls = (Classifier) weka.core.SerializationHelper.read("egitim.model");

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir