Python ile Makine Öğrenimi

For English version please see here.

Merhaba,

Biraz teknik içeriğe sahip olan bu yazıda, Python ve Makine Öğrenimi(MÖ)’den bahsedeceğim. Yıldız Teknik Üniversitesi(YTÜ) Bilgisayar Mühendisliği Bölümü(BMB)’nde öğrencilerin okuldan mezun olabilmesi için iki adet projeyi tamamlaması gerekmektedir. Bilgisayar Projesi(BPI) ve Bitirme Projesi(BPII) olarak adlandırılan bu projeler, öğrencilerin sistem tasarımı ve yazılım geliştirme konularındaki yeteneklerini geliştiren ve onları Bilgisayar Mühendisliği alanında belirli bir alana yönlendiren projelerdir. Bu yazıyı yazmamın sebeplerinden biri bu projelerden herhangi birine başlayacak olan öğrencilerin korkularını yenmelerine yardımcı olmak ve temel olarak MÖ ve Python ile çalışmak hakkında bir fikir vermektir.

MÖ’yü ilk defa duyanlar için; MÖ tekniklerinin yaptığı temel şey, bilgisayarı bir işi yapması için açıkça programlamadan çalışmasını sağlamak ve biz insanlar gibi, bilgisayarları da geçmiş tecrübelerinden öğrenebilen cihazlar haline getirerek onların daha akıllı sonuçlar üretmesini sağlamaktır. Verilen bilgisayar, telefon gibi örnek nesneleri birbirinden ayırt etmeye çalışan bir MÖ tekniğinin yaptığı şey, bir bilgisayarı bilgisayar ve bir telefonu telefon yapan özelliklerin neler olduğunu anlamaya çalışmaktır.

YTÜ BMB’de öğrencilerin gerçekleştirdiği projelerde her ne kadar Java programlama dili baskın olsa ve sıklıkla kullanılsa da, bu tek seçenek değildir. Daha yatkın olduğumuz farklı dillerde de projeler geliştirebilecek imkanlara sahip olmamızdan dolayı farklı seçenekleri değerlendirmek güzel bir yoldur. Bunu yaparken tabii ki, seçtiğimiz programlama dilinin imkanlarına ve bize neler sunduğuna bakarak bir ön araştırma yapmamız gerektiğini unutmamak gerekiyor. Bunun bir sonucu olarak, bende her iki projede de Python’un sağladığı birçok olanaktan dolayı Python ile çalışmayı seçtim. Bunları şöyle listeleyebilirim:

  1. Python ile daha rahat hissetmem ve verilen bir görev için doğru şeyleri yaptığım sürece Python’un olanaklarının projeyi tamamlamamda bana bir sorun oluşturmayacağını düşünmem bu avantajlardan ilki diyebilirim.
  2. Python programlama dili ile MÖ alanında çok fazla sayıda araştırmanın ve projenin yapılmış/geliştirilmiş olması projeyi geliştirirken karşılaşılacak bir sorunun çözümünün de bulunma ihtimalini arttırıyor. Bu da Python ile hiç bilmediğim bir alanda proje geliştirmeye başlarken bana güven veriyor.
  3. Muhteşem kütüphaneler ve araçlar sayesinde, Python gerçek hayatta kullanılan sistemlere çok yakın bir sistemi kurmanıza olanak sağlıyor. Python programlama dili ile geliştirilmiş olgun kütüphanelerin çokluğu işlerinizi de kolaylaştırıyor. Bir web uygulaması geliştirip projenizin sınıflandırma sonuçlarını web uygulaması üzerinde gösterirken bir API aracılığıyla mobil uygulamalarınızdan yeni eğitim verileri alıp onları MÖ sisteminizde eğitebileceğiniz bir programlama dili Python.
  4. Ufak demo uygulamarını dakikalar içerisinde geliştirebilir, Python üzerinde bir projenin yapılıp yapılamayacağını görebilirsiniz. Google veya Github üzerinde yapacağınız bir arama ile sonucu kendiniz de görebilirsiniz. Bahsettiğim her iki projede de, genellikle proje yürütücüsü size bir veya iki haftalık görevler vereceğinden dolayı, Python’un esnekliği ve hızlı geliştirme olanakları sayesinde görevleri zamanında tamamlama şansınızı arttırmış oluyorsunuz.
  5. Sektörde liderlerin her gün kullandığımız birçok ürünü geliştirirken bu dili kullanması bir projeye başlarken insana daha da güven veriyor. Spotify ve eBay bunlardan sadece birkaçı.

Sonuç olarak, Python MÖ de dahil olmak üzere birçok genel amacın dışında Veri Bilimi uygulamaları için de çok uygun bir programlama dili.

Bu listeye daha birçok madde eklenebilir fakat bu yazının kapsamı için yeterli olduğunu düşünüyorum. Bir MÖ sisteminin genel adımları aşağıdaki gibidir:

  1. Verinin elde edilmesi
  2. Verinin ön işlenmesi ve özellik çıkarımı (gereksiz bilgilerin atılması, verinin vektör haline getirilmesi, verinin normalleştirilmesi)
  3. Model oluşturulması
  4. Modelin test edilmesi
  5. Modelin performansının ölçülmesi

Bundan sonraki kısımda, her bir adımda neler yapıldığını birkaç satırdan oluşan kod parçacıkları ile anlatmaya çalışacağım. Çok güzel bir MÖ kütüphanesi olan scikit-learn kütüphanesinide bu kod parçacıkları içerisinde kullanacağım.

  1. Verinin elde edilmesi

Bir MÖ sistemi oluşturabilmek için üzerinde çalışacağımız bir veri setine ihtiyacımız var. Bir program yardımı ile internet üzerinden kendi verinizi toplayabileceğiniz gibi, Iris veri seti gibi örnek veri setlerini de kullanabilirsiniz. Daha fazla veri seti, sklearn.datasets sayfasında, UCI KDD Archive sayfasında veya UCI Machine Learning Repository sayfasında bulunabilir.

Bu veri setlerini uygulamanıza yükleyebileceğiniz Python projeleri bile var. Sizce de çok iyi değil mi?

2. Ön işleme ve özellik çıkarımı

Veriyi elde ettikten sonra, genellikle veriyi başka bir formata dönüştürme ya da bazı gereksiz bilgileri verimizin içinden atma ihtiyacı hissederiz. Bir örnekle açıklayacak olursak, bir tweet verinizin olduğunu ve bir duygu analizi sistemi gerçekleştirmek istediğinizi düşünün. Bu sistem için tweetlerin duygularını belirleyen asıl özellikler web adresleri, mention, hashtag gibi bilgiler olmayacağı için bu özelliklerin atılması mantıklı bir iştir.

Başka bir örnek ise, modelinizi özgün özellikler ile beslemek için kelimelerin köklerini bulmak isteyebilirsiniz. Türkçe bir veri seti üzerinde çalışan bir duygu analizi uygulaması için, “gidiyorum” ve “gidiyorsun” kelimelerini iki farklı özellik olarak almak, özellik sayınızı arttıracak ve verinizin boyutunu da fazlalaştıracaktır. Bu sebepten dolayı, özellik çıkarımı aşamasında Zemberek gibi bir morfolojik ayrıştırıcı yardımı ile kelimelerin köklerini özellik olarak kullanabilir veya yanlış yazılmış kelimeleri düzeltebilirsiniz.

Ön işleme her zaman bir veriyi veri setinden çıkarma anlamına gelmiyor tabii ki. Örneğin spam sınıflandırma gibi bir problemle karşılaştığımız zaman web adreslerini $WEBURL$ gibi bir ifade ile değiştirerek bir web adresinin bir veri içerisinde geçtiğini ifade edebiliriz. Genel olarak bu adımların tamamına ön işleme ismi verilmektedir.

Bazı problemlerde ise farklı aralıklarda değişen özelliklerimiz olabilir. Ev fiyatlarını tahmin etme gibi bir problem için, bir evin odası 1 ile 6 arasında değişirken, evin genişliği 60 ile 200 metrekare arasında değişebilir. Bu tarz problemlerde ise normalleştirme adımı uygulayarak özelliklerimizin aynı aralıkta olmasını sağlayabiliriz. Bu da scikit-learn ile kolaylıkla yapılabilir.

Görüntü işlemeden metin sınıflandırmaya kadar birçok farklı MÖ probleminde istatistiksel modeller her zaman vektörler ve matrisler ile çalışmaktadır. Bu da bizim dış dünyadan aldığımız girdiyi, bir şekilde bu formata uygun bir hale dönüştürmemizi elzem kılmaktadır. Buna bir çözüm olarak ise, scikit-learn içerisinde birden fazla vektörleştirici bulunmaktadır. Verilen bir metini(dökümanı) özelliklerin geçme sıklığı matrisine çeviren CountVectorizer bunlardan sadece biridir. Aşağıdaki kod parçasında bu işleme bir örnek görülebilir:

from sklearn.feature_extraction.text import CountVectorizer

document = [
'I love going out at weekends',
'Yesterday we went to theatre with some friends.',
'How many tickets do I need?',
'Weekends are awesome. I love them.']

vectorizer = CountVectorizer(n=1, analyzer='word')
X = vectorizer.fit_transform(document).toarray()
features = vectorizer.get_feature_names()
print X  
print features

Bu kod parçacığına göre dökümanımızın içerisindeki her bir kelime bir özellik olarak ele alınacaktır. Fakat CountVectorizer modelini oluştururken farklı parametreler vererek, modelinizi farklı özellikler ile oluşturabilirsiniz. Örneğin, n=3, analyzer=’char’ gibi bir parametre dizisi ile 3-gramlardan oluşan özelliklere sahip olabilirsiniz. Yukarıdaki kod parçacığının çıktısı ise aşağıdaki gibidir:

Normalde fit_transform fonksiyon çağrısından sonra elde edilen X değeri bir spars matristir. Spars matris ise, çok az sayıda 0'dan farklı değer içeren bir matris tipidir. Bu yazının amacıyla paralel olarak elimizdeki vektör haline çevrilmiş veriyi daha iyi görebilmek amacıyla spars formatındaki veri dense formatına çevrilmiştir. Yukarıdaki çıktıda da görülebileceği üzere dökümanımızdaki her bir satır bir vektör haline dönüştü ve bütün özelliklerimiz ayrı bir liste haline geldi. Bunun sonucunda bir özelliğin dökümanın bir satırında geçip geçmediğini temsil eden 0 ve 1'lerden oluşan verimiz, dış dünyadan aldığımız metinleri temsil etmiş oldu.

3. Model üretme ve eğitim

Bir model üreteceğimiz zaman problemimizi ve veri setimizi iyi anlamamız gerekmektedir. Örneğin, verilen bir örnek veriye göre değişen ev fiyatlarını tahmin edeceksek, lineer regresyon modeli, verilen bazı mekanları özelliklerine veya kategorilerine göre kümelememizin gerektiği denetimsiz(unsupervised) öğrenme tipindeki bir problemde ise kMeans gibi bir model kullanmak daha mantıklı olacaktır. Bir fikir verebilmek amacıyla aşağıdaki kod parçacığında Iris veri seti üzerinde gerçekleştirilen bir sınıflandırma örneği görülebilir:

from sklearn.svm import SVC  
from sklearn.datasets import load_iris
from sklearn.cross_validation import train_test_split

dataset = load_iris()

X = dataset.data
y = dataset.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)

model = SVC()
model.fit(X_train, y_train)

Yukarıdaki kod parçacığında yaptığımız şey örnek bir veri seti yüklemek, eğitim ve test parçalarını ayırmak ve ardından SVM modelimizi eğitim verimiz ile eğitmektir. Modelimiz lineer bir kernel ile üretilmiş bir Support Vector Classifier(SVC) sınıflandırıcısıdır.

4. Modeli test etme

Modelimizi eğitim verimiz ile eğittikten sonra test etmek scikit-learn’ün tatlı API’si ile çok kolay bir şekilde yapılabilir:

predictions = model.predict(X_test)

Bu işlemin ardından predictions listesi içerisinde her bir test örneği için modelimizin tahminleri yer almaktadır.

5. Modelin değerlendirilmesi

Modelimizi oluşturup, eğitip test ettikten sonra sıra modelimizin nasıl bir performans sergilediğini öğrenmekte. Sonuçların değerlendirilmesi aşaması bir MÖ sisteminin önemli bir parçasıdır çünkü alınan sonuçlara göre farklı yolların izlenmesine sebep olmaktadır. Modelimizin performansını farklı ölçümler ile yorumlayabiliriz:

  • Mean Squared Error (MSE), Mean Absolute Error (MAE)
  • Accuracy değeri
  • Precision, Recall ve F1 değerleri

Bu aşamada, her bir ölçümün ne anlama geldiğini ve neyi gösterdiğini bilmemiz gerekmektedir. Örneğin, %90 pozitif, %10 negatif örneklerden oluşan dengesiz bir veri setimiz varsa accuracy değeri her zaman modelimizin gerçek başarısını göstermeyebilir. Bu durumda F1 değerine bakarak modelimizin performansını yorumlarız. Yukarıda eğittiğimiz modelin test verisi üzerinde nasıl çalıştığını ise sklearn.metrics modülü ile kolayca bulabiliriz.

from sklearn.metrics import accuracy_score

acc_score = accuracy_score(y_test, predictions)
print acc_score

Buna ek olarak, beklenilenden daha düşük sonuçlar üreten bir sistem ile izleyebileceğimiz birden fazla yol vardır. Modelimizin öğrenme eğrisini çizerek modelimizin nasıl bir sorunu olduğunu bulabilir, buna göre özellik sayımızı azaltma(dimensionality reduction) kararı alabilir veya ek eğitim verisine ihtiyaç duyduğumuza karar verebiliriz.


Genel olarak, bir MÖ sisteminin genel parçaları üzerinden geçmiş olduk. Umarım bu yazı size Python ile bir MÖ problemi üzerinde çalışma hakkında bir fikir vermiştir. BPI ve BPII projelerini gerçeklemek için bir platform ve fikir arayanlar için Python ve MÖ güzel bir başlangıç olabilir. Python’un ve ek kütüphanelerin gücü ile probleminize uygun bir veri seti seçerek dilediğiniz bir MÖ alanında çalışabilirsiniz. MÖ alanında üzerinde çalışılan bazı alanlar ise şunlardır:

  • Deep learning
  • Active learning
  • Sentiment analysis
  • Recommender systems
  • Collaborative filtering
  • Image recognition

MÖ alanında çalışmak isteyenler için MÖ alanında bir bilgi birikimi oluşturmak amacıyla yararlanabilecekleri bazı kaynaklar ise şöyle sıralanabilir:

Stanford Üniversitesi tarafından açılan MÖ kursunun çok geniş kapsamının olması ve temel bilgileri vermesi açısından bu kursu tavsiye ederim.

Yazının sonuna kadar okuduğunuz için teşekkür ederim. Eğer sorularınız varsa yorum aracılığıyla duymak isterim.

/Said.