Machine Learning Uygulaması: Servisler

İlk yazıda Machine Learning girişini yapıp, ikinci yazıda modelimizi oluşturmuştuk. Şimdi yazı dizimizin son halkasında modelimizi kullanacak servisimizi geliştireceğiz.

Hazırlık

Servislerimizi SpringBoot ve Spring MVC kullanarak geliştireceğiz. Modelimizi okumak ve çalıştırmak için yine Apache Spark kullanacağız. Servisimiz basit bir servis olacak ve ilk yazıda konuştuğumuz veri setinde olan etkenleri JSON olarak alan bir servis yazacağız. Servisimiz daha sonra bu verileri, ikinci yazıda kullandığımıza benzer bir fonksiyonla normalize edecek. Son olarak da, bu yeni veriyi modelimize gönderecek.

Projenin Yaratılması

Projemizin ne olduğuna kısaca değindiğimize göre şimdi projemizi nasıl yaratılacağına değinebiliriz. Dediğim gibi ben intellij kullanarak anlatacağım ama start.spring.io üzerinden de aynı işlemleri gerçekleyebilirsiniz.

Öncelikle yeni bir proje yaratıyoruz. Proje tipi olarak Spring Initializr seçiyoruz:

spring_book_ml_1

Daha sonra gelen ekranda proje bilgilerini dolduruyoruz. Ben aşağıdaki şekilde doldurdum.

spring_boot_ml_2

Daha sonra gelen ekranda hangi kütüphaneleri kullanacağımızı seçiyoruz. Biz sadece Spring-MVC kullanacağımız için Web‘i seçiyoruz. Her ne kadar Spring-Boot’un Spark için de bir paket olsa da biz onu kullanmayacağız. Bu daha çok Map Reduce işlemleri (YARN scripti çalıştırmak vs.) için kullanılıyor. Biz kendi Spark ayarlarımızı kendimiz yapacağız.

 

spring_boot_ml_3

Son olarak, projemize isim verip lokasyon seçiyoruz.

Machine Learning Modelinin Tanıtılması

Öncelikle spark bağımlılıklarımızı ekleyelim. Spark bağımlılıklarını eklerken Spark ile Spring MVC’nin kullandığı Jackson versionlarının uyuşmadığını göreceksiniz. Bunu gidermek için Spring MVC’nin kullandığı versiyonu düşürüyoruz.

Hatırlarsanız ikinci yazıda modelimizi üretmiştik. Ürettiğimiz modeli Spark bir dizin olarak kaydediyor. İçerisinde ihtiyaç duyduğu bütün bilgiler var. Sizin uygulamanızda tek yapmanız gereken bu dizini parametre olarak vermek. Biz de src/main/resources dizinindeki application.properties dosyasını açıyoruz ve aşağıdaki satırı ekliyoruz.

application.properties

Şimdi spark context’imizi oluşturabilir ve modelimizi yükleyebiliriz. Bunun için com.bahadirakin.ml paketinin altına SparkConfiguration isminde bir sınıf yaratıp içeriğini aşağıdaki gibi yapıyoruz.

SparkConfiguration.java

Burada tek yaptığımız gerekli Spark sınıflarını ve modelimizi oluşturmak.

Servis Katmanının Geliştirilmesi

Web servislerimizi yazmadan önce servis katmanımızı geliştirelim. Bu katman Machine Learning modelimizi kullanarak, tahminler yapacak. Girdi olarak kullanacağım nesne, İlk yazıda bahsettiğimiz özellikleri içerecek. Bunun için com.bahadirakin.ml.dto altına CompanyInfo ismindeki sınıfımızı yaratıp içeriğini aşağıdaki gibi yapıyoruz.

CompanyInfo.java

Burada kullandığımız RiskStatus nesnesi ise aşağıdaki gibidir.

RiskStatus.java

Son olarak üreteceğimiz nesneyi belirleyelim. Bildiğiniz üzere sınıflandırma yapıyoruz. 2 adet sınıfımız var Bankruptcy ve Non-Bankruptcy. Aynı pakete bu bilgileri içeren CompanyPrediction isminde bir enum yaratıyoruz.

CompanyPrediction.java

Nesnelerimizi belirlediğimize göre sırada servisimizin tanımı var. Servisimizin tanımını (interface ve implementasyonu) com.bahadirakin.ml.service paketine oluşturuyoruz.

QualitativeBankruptcyService.java

QualitativeBankruptcyServiceImpl.java

Burada dikkatinizi çekmek istediğim bir kaç nokta var :

  • Farkettiyseniz RiskStatus nesnesini normalize ederken hemen hemen aynı metodu kullanıyorum. Tek fark bir önceki yazıda String üzerinden işlem yaparken bu yazıda Enum değerleri üzerinden işlem yapıyorum. Aynı şekilde CompanyInfo nesnesinden vektörü oluşturken sıralamaya sadık kalıyorum. Bir önceki yazıda String nesnesini virgüllere göre ayırmış ve array üzerinden işlem yapmıştım. Burada nesnenin alanlarını aynı sırada çağırarak işlem yapıyorum.
  • CompanyInfo nesnesini Serializable olarak oluşturuyorum. Bu keyfi bir durum değil. Burada JavaRDD üzerinden işlem yaparken Spark nesneleri cluster üzerinde dağıtmaya çalışıyor. Dağıtma işleminide object serialization üzerinden yapıyor. Her ne kadar bizim cluster’ımız olmasa da ve tek nesne üzerinden de çalışıyor olsak Spark buna ihtiyaç duyuyor.
  • Önceki yazıda tahmin sonuçlarını bizim yorumlamamız gerektiğinden bahsetmiştim. Burada ki deNormalizeResult metodu bu yorumlamadan sorumlu. Enum içerisine değer verilerekte yapılabilir bu. Ama bu şekilde yapmanın daha netlik kazandıracağını düşündüm.

Web Servisin Geliştirilmesi

Son olarak web servisimizi geliştirelim. Web servisimizin tek yapacağı, servis katmanını çağırmak olacak. Bunun için com.bahadirakin.ml.mvc paketi altına QualitativeBankruptcyController isminde sınıfımızı yaratıp içeriğini aşağıdaki gibi yapıyoruz.

QualitativeBankruptcyController.java

Burada sıradan bir servis yazdık. JSON alıp JSON üretiyor. Tek yaptığı servis katmanını çağırmak.

Uygulamanın Test Edilmesi

Uygulamamızı main methodunu içeren sınıfı (MlSparkMvcServiceApplication.java) çalıştırarak başlatabiliriz. Sonrasında aşağıdaki sorgulara göndererek test edebiliriz.

Non-Bankruptcy durumunu test etmek için:

Bankruptcy durumunu test etmek için:

Sonoctobiwan

Umarım bu yazı dizisi, Spark kullanarak bir Machine Learning uygulamasının nasıl hayata geçirilebileceği konusunda size yardımcı olmuştur.

Projenin kaynak kodlarına bu adresten erişebilirsiniz.

 

  • Uğurcan Laçin

    Machine Learning konusunu programlanabilir bir şekilde nasıl kullanıldığını bir süredir merak ediyordum. Daha önce Coursera üzerinden ders almıştım. Fakat ağırlıklı olarak teorik gittiği için uygulamada nasıl kullanıldığını pek kavrayamamıştım. Bu kısa ve öz yazı dizisiyle pratikte nasıl olduğunu görmüş oldum. Vakit ayırıp paylaşımda bulunduğunuz için teşekkürler. Elinize sağlık.

    • bhdrkn

      Çok sağol Uğurcan. Böyle yorumlar almak insanı çok motive ediyor.