Aralık 17, 2018

Python ile Makine Öğrenmesine Giriş 1 (Linear Regression)

 Öncelikle belirtmem gerekiyor ki bu yazı paylaşıldığı zaman Python’a Giriş serisi henüz tamamlanmadı, yani bu yazıyı tam anlamıyla anlamanız için Python’a biraz da olsa hakim olmanız gerekiyor. Eğer seri tamamlandıysa, öncelikle seriyi okumanızı öneriyorum.


Bu yazı için bilmeniz gerekenler:

  • Basit – Orta seviye Python bilgisi
  • Lise matematiği

Bu yazıda kullanacağımız kütüphaneler:

  • Numpy  
  • Pandas
  • Matplotlib
  • Sklearn

İlgili kütüphaneleri kurmak için konsol kodu:

pip install kütüphane_adı

Kütüphanelerimizi kurduğumuza göre artık makine öğrenmesi modeli nasıl oluşturulur görebiliriz.

Ne yapmak istiyoruz?

Makine öğrenmesi modellerinin genel mantığı, bir veri kümesinden yola çıkarak, o veri kümesinde olmayan bir girdinin çıktısının ne olacağının tahmin etmeye çalışmaktır. Olayı daha basite indirgemek için şu örneği vereceğim.

Elinizde 2005 yılından beri Ankara’da satılan evlerin metrekare ve fiyat bilgisi var. Bunlar için bir veri seti oluşturdunuz ve bu veri setinde yer almayan bir evin metrekare bilgisine göre fiyatını öğrenmek istiyorsunuz. Bu verileri inceledikten sonra verilerin dağılımına göre uygun makine öğrenmesi modelini seçerek tahmin yaptırabilirsiniz.

Yapmamız gereken işlemleri sıralayacak olursak;

  1. Veri setini incelemek, düzeltmek
  2. Veri setine uygun makine öğrenmesi algoritması seçmek
  3. Veri setini eğitim, test ve doğrulama (her zaman gerekli değil) ayırmak
  4. Modeli eğitmek ve sonucu incelemek

Biz bu yazımızda hem veri setini dahil ederken, hem de modelimizi eğitirken Scikit-learn kütüphanesini kullanacağız. 

Scikit-learn nedir?

Scikit-learn makine öğrenmesi modelleri oluştururken kullanılan güçlü bir Python kütüphanesidir. İçerisinde regression, clustering, classification ve daha birçok farklı yapı için fonksiyonlar ve veri setleri içermektedir.

Hadi başlayalım!

Öncelikle kütüphanelerimizi içeri aktarıyoruz.

%matplotlib inline #Jupyter notebook kullanacağımız zaman grafikleri görebilmek için dahil ediyoruz.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets

Ardından bu yazıda kullanacağımız veri seti olan diabetes veri setini dahil ediyoruz.

diabetes = datasets.load_diabetes()

Veri setini inceleyelim.

#Veri setinin açıklamasını okuyalım.
print(diabetes.DESCR)
>> Diabetes dataset
----------------

Ten baseline variables, age, sex, body mass index, average blood
pressure, and six blood serum measurements were obtained for each of n =
442 diabetes patients, as well as the response of interest, a
quantitative measure of disease progression one year after baseline.

**Data Set Characteristics:**

  :Number of Instances: 442

  :Number of Attributes: First 10 columns are numeric predictive values

  :Target: Column 11 is a quantitative measure of disease progression one year after baseline

  :Attribute Information:
      - Age
      - Sex
      - Body mass index
      - Average blood pressure
      - S1
      - S2
      - S3
      - S4
      - S5
      - S6

Note: Each of these 10 feature variables have been mean centered and scaled by the standard deviation times `n_samples` (i.e. the sum of squares of each column totals 1).

Yani elimizdeki veri setinde 10 adet parametremiz (yaş, cinsiyet, vücut kitle indeksi, ortalama kan basıncı vs.) , 1 adet çıktımız ve 442 adet hastamız varmış. 

Parametrelerimize ait olan verileri inceleyelim.

#Parametrelere ait verileri görüntülemek için data yapısını kullanıyoruz.
raw_data = diabetes.data
print(raw_data)
>>> [[ 0.03807591  0.05068012  0.06169621 ... -0.00259226  0.01990842
  -0.01764613]
 [-0.00188202 -0.04464164 -0.05147406 ... -0.03949338 -0.06832974
  -0.09220405]
 [ 0.08529891  0.05068012  0.04445121 ... -0.00259226  0.00286377
  -0.02593034]
 ...
 [ 0.04170844  0.05068012 -0.01590626 ... -0.01107952 -0.04687948
   0.01549073]
 [-0.04547248 -0.04464164  0.03906215 ...  0.02655962  0.04452837
  -0.02593034]
 [-0.04547248 -0.04464164 -0.0730303  ... -0.03949338 -0.00421986
   0.00306441]]

Verileri böyle görünce kafanızda pek bir şey canlanmamıştır diye düşünüyorum. Bu verileri dataframe olarak gösterelim.

Bunun için Pandas kütüphanesinin DataFrame() fonksiyonunu kullanacağız ve ardından head() fonksiyonu ile ilk 5 veriyi görüntüleyeceğiz.

diabetes_df = pd.DataFrame(raw_data)
diabetes_df.head()

Sanırım şimdi daha açıklayıcı oldu ancak 0,1,2,3… diye giden parametrelerin ne anlama geldiğini bilmiyoruz. Bunun için oluşturduğumuz dataframe’in columns parametresini güncelleyelim.

diabetes_df.columns = diabetes.feature_names
diabetes_df.head()

Evet, şimdi güzel oldu. Hangi verinin hangi parametreye ait olduğunu çok daha düzgün bir şekilde görüntüleyebiliyoruz.

Aynı işlemi çıktılarımız için de uygulayalım.

output_df = pd.DataFrame(diabetes.target, columns=["output"])
output_df.head()

Evet verileri düzgün bir şekilde görebiliyoruz, son olarak bütün parametrelerin ve çıktıların bir arada olduğu genel bir dataframe oluşturalım. Bunun için Pandas kütüphanesinin concat() fonksiyonunu kullanacağız, ancak çıktıların en sonda kalmasını istediğimiz için sort parametresine False değerini veriyoruz.

all_df = pd.concat([diabetes_df, output_df], sort=False, axis=1)
all_df.head()

Verileri incelemeye devam etmeden önce neden veri setini bölümlere ayırmamız gerektiğini konuşalım. Verileri eğitim ve test verisi olacak şekilde ayırmamızın amacı modelin overfitting (ezberleme) problemi yaşamamasını sağlamak. Her ne kadar eğitim sırasında sonuçları çok yakın veya tam bulması işimize gelecek gibi gözüksede bu aslında bizim için bir problem. Bizim amacımız modelin genel bir kanıya varması, bütün verileri ezberlemesi değil. Yani eğitim verileriyle çok iyi sonuçlar verdiğini gördüğümüz modeli test verileriyle tahmin ettirince çuvallıyorsa bir şeylerin ters gittiği kanısına varabiliriz.

Olayı anladığımıza göre artık verileri eğitim ve test verisi olarak ikiye bölebiliriz fakat bundan önce hangi parametrede eğitim yapmak istediğimizi seçmeliyiz. Bu eğitim için “bmi” yani vücut kitle indeksini kullanacağım fakat siz hepsini veya başka bir parametreyi kullanarak eğitim yapabilirsiniz.

X = diabetes_df['bmi'].values
Y = output.df.values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=9)
X_train = X_train.reshape(-1,1)
X_test= X_test.reshape(-1,1)

Scikit-learn kütüphanesiden train_test_split() fonksiyonu yardımıyla, %80’i eğitim ve %20’si test verisi olacak şekilde x_train, x_test, y_train ve y_test değişkenlerine atadık. Parametrelerde bulunan random_state = 9‘un amacı ise siz bu fonksiyonu çağırdığınızda aynı sonuçları alabilmeniz için kullandığımız bir yöntem yani zorunlu değil.  Ardından X_train ve X_test verilerinin eğitim sırasında problem oluşturmaması için reshape() fonksiyonuyla boyutlarını düzenledik.

Verileri eğitim ve test verisi diye ayırdıktan sonra dersimizin konusu olan Linear Regression yapısını anlamaya çalışalım.

Genel denklem:  y = Xβ + c + ϵ

X: Veriler 
β: Kat sayılar
c: Kestiği nokta
ϵ: Hata oranı
y: Çıktı 

Yani burada yapmaya çalıştığımız şey, veri kümesini en iyi şekilde ifade eden lineer bir doğru elde edebilmek. Tahmin edebildiğiniz gibi bu doğru her veriyi tam olarak kapsamayacağı için bir error rate (hata oranı) elde edeceğiz ve bu hata oranını kullanarak modeli en doğru hale getirmeye çalışacağız ama bundan önce modelin lineer yapıya uygun olup olmadığına grafiksel olarak bakalım. 

plt.scatter(X_train, y_train)

Verilerimiz çoğunlukla lineer bir yapı göstermiyor. Aslında bu veriye Linear Regression yerine farklı makine öğrenmesi algoritmaları uygulayabiliriz ancak dersimizin konusu Linear Regression 🙂 

Scikit-learn kütüphanesinde bulunan LinearRegression() fonksiyonu ile modelimizi oluşturuyoruz.

from sklearn.linear_model import LinearRegression
model = LinearRegression()

Modelimizde fit() fonksiyonuna X_train ve y_train eğitim verilerini vererek eğitimi başlatıyoruz. Burada X_train vücut kütle indekslerini temsil ederken, y_train ise bu indekslere göre diyabet hastalığının ilerleme boyutunu temsil ediyor.

model.fit(X_train, y_train)

Predict() fonksiyonuna X_test verilerini veriyoruz ve modelden Y_test verilerini tahmin etmesini istiyoruz. Yani vücut kitle indeksleri verip diyabet hastalığının ilerleme boyutunu tahmin etmesini istiyoruz.

diabetes_y_pred = model.predict(X_test)
from sklearn.metrics import mean_squared_error, r2_score
print('Kat sayı değeri:', model.coef_)
print("Hata oranı: %.2f" % mean_squared_error(y_test, diabetes_y_pred))
print('Varyans skoru (1 en iyi): %.2f' % r2_score(y_test, diabetes_y_pred))

%55 gibi fena olmayan bir doğruluk payı elde ettik. Oluşan denklemi grafik ile gösterelim.
plt.scatter() fonksiyonu ile var olan test değerlerini (X_test, y_test) noktasal bir şekilde düzlemde gösteriyoruz.
plt.plot() fonksiyonu ile makineye girdi olarak verdiğimiz 
vücut kitle indeksi (X_test) ve tahmin etmesini istediğimiz diyabet hastalığının ilerleme boyutu verilerinin (diabetes_y_pred) lineer grafiğini çizdiriyoruz.

plt.scatter(X_test, y_test,  c='g')
plt.plot(X_test, diabetes_y_pred, linewidth=2)
plt.show()

Artık modelimiz veriler hakkında genel bir fikre sahip oldu, yeni bir veri verdiğiniz zaman kendisi yorumlayabilecek. 

Sonuç olarak, yüksek başarı elde edemedik fakat Linear Regression yapısını kavramış olduk. Kendiniz test etmeniz için daha lineer yapıda olan veri setlerini UCI Machine Learning Repository adresinden elde edebilirsiniz.

Anlamadığınız noktaları mutlaka yorum bölümünde sormayı unutmayın, diğer yazılarda görüşmek üzere.

Share

Can Umay

Can UMAY, 19 yaşında. Ankara Yıldırım Beyazıt Üniversitesinde Bilgisayar Mühendisliği öğrencisi ve Gais Siber Güvenlik Teknolojileri şirketinde Yapay Zeka geliştiricisi olarak çalışmakta. Deep Learning Türkiye tarafından kurulan Yapay Zeka ve İnsansız Sistemler Öğrenci Birliğinin ilk üyesi olan Biltek Yapay Zeka ekibinin kuruculuğunu ve başkanlığını üstlenen UMAY şuanda şirket bünyesinde Peyk projesinin ekip yöneticiliğini yürütmektedir.

You may also like...

4 Responses

  1. Taner Akdeniz dedi ki:

    Merhaba,
    Çalışmanız çok güzel olmuş. Elinize, beyninize sağlık. Bir, iki sıkıntı yaratan yer var:
    Pandas concat() için axis=1 belirtmek gerekiyor sanırım (all_df = pd.concat([diabetes_df, output_df], axis=1, sort=False)) .
    Bir de sklearn.metrics’den bazı metotları import etmek gerekiyor.
    Kolay Gelsin,

  2. Hüseyin Kaya dedi ki:

    Birkaç gündür böyle yalın bir anlatım arıyordum tıkanmıştım. Eline sağlık.

Bir cevap yazın

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