Machine Learning Uygulaması: Giriş
Geçtiğimiz aylarda, takımdan bir arkadaşın ayrılması sonucunda, bir Machine Learning projesini kucağımda buldum. Sorun şu ki ben üniversitede yazılım dilleri ve DSL geliştirilmesi üzerine çalıştım ve hemen hemen hiç Machine Learning dersi almadım.
Tabi bu durum bana engel olmak yerine beni daha da heveslendirdi ve bir hevesle öğrenmeye baÅŸladım. Öğrendikçe de çok zevkli bir alan olduÄŸunu gördüm.Her ne kadar bu tip iÅŸler için Amazon’un kendi kütüphaneleri olsa da, bir çok açık kaynak kütüphane ile de kolaylıkla Machine Learning uygulamaları gerçekleyebilirsiniz. Bende bu yazı dizisinde basit bir Machine Learning uygulamasını Apache Spark ve Spring kullanarak nasıl gerçeklenebileceÄŸini anlatmaya çalışacağım.
Öncelikle bu yazı dizisinde neler olacağına bakalım:
- GiriÅŸ: (bu yazı) Bu bölümde, kısaca Machine Learning terimlerinden ve elimizdeki problemden bahsedeceÄŸim. Ama belirteyim amacım Machine Learning’in ne olduÄŸunu anlatmaya çalışmak deÄŸil. Bunun için online çok güzel dersler ve kaynaklar mevcut.
- Modelin Geliştirilmesi: Elimizdeki veri setini ve Apache Spark kullanarak modelimizi nasıl üretebileceğimize bakacağız.
- REST servisler üzerinden yeni tahminlerin yapılması: Son olarak Spring MVC ile web servisimizi geliştireceğiz. Web servisimiz önceki yazıda hazırladığımız modeli kullanarak, yeni veriler üzerinden kararlar verecek. Zaten Machine Learning ile akademik olarak ilgilenmiyorsanız, yarattığınız modelinizin servis olarak erişilebilir olması lazım. Örneğin spam olarak sınıflandırabilen model mi geliştirdiniz, eğer yeni gelen mailleri bu modeli kullanarak sınıflandıramıyorsanız yarattığınız model çok bir işe yaramayacaktır.
Machine Learning
Machine Learning alıştığımız, klasik programlama mantığından farklı çalışıyor. Klasik programlamada, bir uygulama geliÅŸtirirsiniz, daha sonra geliÅŸtirdiÄŸiniz uygulamaya deÄŸerleri gönderip, çıktılar alırsınız. Machine Learning’te ise bir uygulama geliÅŸtirirsiniz, uygulamaya hangi girdiler için hangi çıktıları almayı beklediÄŸinizi söylersiniz, uygulama da size sonuç olarak bir model geliÅŸtirir. Daha sonra bu modeli klasik uygulamalarınıza dahil ederek akıllı uygulamalar geliÅŸtirebilirsiniz.
Machine Learning uygulamanızı geliştirken kullandığınız veri kümesinden yazı boyunca veri seti (training set) diye bahsedeceğim. Bu veri setinin bir kısmı modelinizi geliştirmekte kullanılırken bir kısmı da modelinizi test etmede kullanıyorsunuz. Test seti sayesinde oluşturduğunuz modelin ne kadar tutarlı olduğunu ölçebilirsiniz. Yani oluşturduğunuz model test seti ile çalıştırıp sonuçları karşılaştırıyoruz. Böylelikle modelimizin tutarlılığını buluyoruz. Tahmin edeceğiniz üzere veri setinizin büyüklüğü, tutarlılığınızın doğruluğunu, tutarlılığınızı ise veri setinizin kalitesi etkilemektedir.
Şöyle anlatmaya çalışayım, diyelim ki maillerinizi spam ya da spam değil olarak sınıflandırmaya çalışıyorsunuz. Elinizdeki veri setinde dört farklı veri olsun. Gönderen kişinin email adresi, mail başlığı, maildeki kelime sayısı ve sınıfı (spam ya da spam değil). Gönderen kişinin email adresi ve mail başlığı büyük ihtimalle sınıfını etkiliyordur. Peki ya maildeki kelime sayısı? Etkilediğini hiç düşünmüyorum. Eğer kelime sayısını modelinize katarsanız büyük ihtimal tutarlılığınız düşecektir. (Fakat kelime sayısını katsanız bile küçük veri setlerinde yüksek tutarlılıklar alabilirsiniz.) Bu sebepten modelinizin özelliklerini (features) seçerken dikkat etmelisiniz.
Kısaca temel bilgilere değindiğimize göre şimdi problem tanımına geçebiliriz.
Problem Tanımı
Problemi olabildiÄŸince basit seçmeye çalıştım ki problem detaylarında boÄŸulmayalım. Problemi kısaca “Farklı etkene bakarak bir ÅŸirketin batmaya meyilli olup olmadığını  anlamak” olarak belirleyebiliriz. Bunun için yazılımcı olarak oturup kendimiz araÅŸtırma yapmak yerine, 2014 te yapılmış araÅŸtırmanın sonuçlarını kullanacağız. Sonuçları bu adresten indirebilirsiniz. Böyle problem tanımlarından sonra veri genelde yazılımcıya saÄŸlanacaktır. Hatta Machine Learning üzerinde uzmanlaÅŸmış ÅŸirketlerde model bile yazılımcıya hazır olarak gelebiliyor.
EÄŸer Amazon’da nasıl yapıldığını soracak olursanız, benim çalıştığım projede biraz daha farklı bir durum söz konusu. Perakende ürün verileri bizde olduÄŸundan veritabanından bu verileri biz çekiyoruz. Daha sonra bu verilerin etiketlenmesi / sınıflandırılması için iÅŸ birimine gönderiyoruz. Etiketleme bittikten sonra, bu verilere bakarak, hangi özelliklerin (features) etkili olabileceÄŸine karar verip modelimizi geliÅŸtiriyoruz. Son olarak servis üzerinden modelimizi yeni veriler için tekrar tekrar kullanıyoruz.
Neyse konumuza dönecek olursak, indirdiğimiz veri seti 6 temel özelliğe göre sınıflandırılmış:
- Endüstriyel Risk Seviyesi
- Yönetimsel Risk Seviyesi
- Finansal EsnekliÄŸi
- Piyasadaki Güvenilirliği
- Rekabet
- Operasyonel Risk Seviyesi
Daha sonra bu etkenler için 250 farklı şirket incelenmiş ve her bir şirketi iflas eder (Bankruptcy) / iflas etmez (Non-Bankruptcy) diye etiketlemişler.
Burada diğer değinmek istediğim nokta bu 6 etkenin değerleri. Eğer veriyi indirip incelediyseniz her bir değerin ortalamanın üzerinde (Positive), ortalamanın altında (Negative) ve ortalama (Average) şeklinde değerler aldıklarını göreceksiniz. Ne yazıkki bu değerleri doğrudan kullanmamız mümkün değil. Bu değerleri kullanabilmemiz için bu değerleri normalize etmeniz gerekiyor. Her ne kadar nasıl normalize edeceğimiz, kullanacağımız algoritmaya göre değişse de sadece bir tane nomalizasyon fonksiyonunu kullanmamız gerekiyor. Yani modelimizi eğitirken kullandığımız normalizasyon fonksiyonu ile, bu altı etkeni web servis üzerinden alıp modelimize göndermeden önce kullanacağımız normalizasyon fonksiyonunun aynı olması gerekiyor. Bu konuya modelimizi eğitirken ve servislerimizi geliştirirken tekrar değineceğim.
Kullanacağımız Teknolojiler
Giriş kısmını bitirmeden önce, son olarak kullanacağımız teknolojilere değinmek istiyorum.
Apache Spark büyük veri iÅŸleme amaçlı bir proje. Hadoop’un rakibi olarak düşünebilirsiniz, Hadoop’tan 100 kat daha hızlı olduÄŸunu iddia ediyor. Scala dili ile geliÅŸtirilmiÅŸ, zaten java kullanarak Spark uygulaması geliÅŸtirmeye kalktığınızda bir çok Scala bağımlılığı ile birlikte geldiÄŸini görüyorsunuz. Spark’ın en güzel özelliklerinden biri dağıtık olması ve gönderdiÄŸiniz iÅŸleri dağıtık olarak çalıştırması. Yer yer bu programlama da karmaşıklığa yol açsa da güzel bir özellik diye düşünüyorum. ÖrneÄŸin ÅŸirketinizde kuvvetli makinelerle Spark cluster’ı kurabilir ve modellerinizi bu cluster üzerinde çalıştırabilirsiniz ya da AWS servislerinden Elastic Map Reduce servisini kullanarak hızlıca kendi cluster’ınızı kurabilirsiniz. Bir diÄŸer seçenek de, diÄŸer bir AWS servisi olan EC2 yu kullanarak Spark cluster’ı kurabilirsiniz. Zaten Spark kendi sitesinde hızlıca EC2 cluster’ı kurabileceÄŸiniz scriptleri de paylaşıyor. AWS kullandığınız taktirde ucuza veri saklamak için S3’yi kullanabilirsiniz. Spark S3 ve diÄŸer dağıtık dosya sistemlerini doÄŸrudan desteklediÄŸinden, dosyalarınıza ulaşırken tek yapmanız gereken S3 linklerini kullanmak oluyor.
Biz basit olması açısından, cluster kurulumu yapmayacağız. Spark’ı basitçe bellekte ayaÄŸa kaldıracağız ama iÅŸleyeceÄŸiniz veri büyükse mutlaka cluster kurulumunu düşünmelisiniz.  Yine basit olması açısından biz veri setimizi projenin içerisinde yükleyeceÄŸiz ve modelimizi elle dağıtacağız. (S3  ya da baÅŸka dağıtık dosya sistemi kullandığınızda modelinizi dağıtmakla uÄŸraÅŸmıyorsunuz.)
Tabi veri iÅŸleme haricinde Spark’ın baÅŸka özellikleri de var :
- Spark Streaming: Gerçek zamanlı veri işleminize olanak sağlayan bir alt proje. (Daha detaylı bilgi için bu blog yazısından faydalanabilirsiniz)
- Spark SQL: RDB (Relational Database) olmayan bir veri kaynağında (örneÄŸin S3’teki bir dosya) SQL komutu ile sorgu yapabilmenize olanak saÄŸlıyor.
- Spark GraphX: Spark cluster’ınızı kullanarak grafik oluÅŸturmanıza yarayan bir kütüphane. Grafik çizmek basit bir problem gibi gözükse de büyük verilerle çalıştığınızı düşündüğünüzde zor bir problem halini alıyor. Ayrıca eÄŸer Machine Learning üzerine çalışıyorsanız verinizi görselleÅŸtirmek, problemi anlamanıza yardımcı olabiliyor.
- Spark MLlib: Spark’ın Machine Learning kütüphanesi, yani bizim kullanacağımız kütüphane. Java için farklı bir çok kütüphane olsa da bunların çok azı hem dağıtık veri iÅŸleme yapıp hem da çok sayıda Machine Learning algoritması destekliyorlar. Spark MLlib Classification, Regression, Decision Trees, Random Forest, Reccomendation ve daha bir çok farklı algoritmayı destekliyor.
Son
Artık problemin ne olduğunu ve kullanacağımız teknolojileri biliyoruz. Bir sonraki yazıda bu veri setini kullanarak, Apache Spark yardımıyla, modelimizi nasıl geliştireceğimize bakacağız. Daha sonra bu modelimizi kullanarak yeni şirketlerin iflas etmeye meyilli olup olmadığına karar verecek bir uygulama geliştireceğiz.