Makine Öğrenmesinde Python ile Basit Doğrusal Regresyon Modelinin Kurulması ve Yorumlanması

Yiğit Şener
7 min readFeb 2, 2020

--

Bu makale makine öğrenmesindeki basit doğrusal regresyon modelini uygulama ve teorik bir arada olacak şekilde anlatımı kurgulanarak hazırlanmıştır. İçerik basit doğrusal regresyon anlatımı ile başlayıp bir diğer yazıda çoklu regresyon anlatılmaktadır. Ayrıca Python’da en popüler iki regresyon analizi kütüphanesi olan Sklearn ve Statsmodels’den bahsedilerek karşılaştırılmaya çalışılmıştır.

Doğrudan problemi tanımlayarak başlayalım

Bu makaledeki tüm kodlara Github’daki repomdan erişebilirsiniz. Elimizde 22 kişinin yaşı ve aldıkları maaş bilgisi yer alıyor. Bu 22 kişinin yaşını ve maaşını aşağıdaki kodda olduğu gibi tanımlayabiliriz. Yaş bilgisini biz yazdık ancak maaş bilgisini her bir yaş için farklı sonuçlar döndürebilecek random üretilen sayılar ile belirliyoruz. Ardından bu iki değişkeni Pandas’da bir DataFrame yapısına dönüştürüyoruz.

# İlgili kütüphanelerin kurulması
import numpy as np
import pandas as pd
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from sklearn import metrics
import matplotlib.pyplot as plt
# El ile yaş bilgisinin girilmesi
yas = [20,21,22,24,25,25,
26,27,27,28,28,28,
29,30,31,31,32,33,
33,34,35,36]
# list comprehension ile her bir yaş için farklı ücret bilgisinin yaratılması
gelir = [x**3/np.random.randint(2,4) for x in yas]
# İki liste verisinin DataFrame'e aktarılması
df = pd.DataFrame({"yas":yas,
"gelir":gelir})

Yaş ve ücret bilgisinin yer aldığı veriyi inceleyelim (Tablo 1)

Tablo 1: Yaş — Gelir Tablosu
Tablo 1: Yaş — Gelir Verileri

İsterseniz Python “df.describe()” kodunu çalıştırarak basit istatistikleri de görebilirsiniz. Şimdilik sadece regresyon analizine odaklanacağımız için veri hazırlığı/dönüşümü gibi işlemlerini yapmayacağız.

İki değişkenli bir verimiz olduğu için scatter plot üzerinden değerlerin nasıl dağıldığını bir inceleyelim.

import matplotlib.pyplot as plt
plt.scatter(df.yas,df.gelir)
plt.title("Yaş - Gelir Dağılımı")
plt.xlabel("Yaş")
plt.ylabel("Gelir")
plt.show()
Şekil 1: Yaş — Gelir Dağılımı

Şekil 1'de yer alan scatter plot incelendiğinde noktaların doğrusal ve her iki eksen içinde düşünüldüğünde pozitif yönde olduğu görülmektedir. Bu demek oluyor ki yaş arttıkça gelirde artmaktadır. Dolayısı ile artık bir hipotez elde ettik diyebiliriz. Peki gerçekten pozitif yönlü bir güçlü bir ilişkiden bahsedebilir miyiz? Korelasyon analizi ile inceleyelim.

df.corr() # Korelasyon 
# 0.90023

Yaş ve gelir arasında oldukça güçlü (>.90) bir ilişki olduğunu görmekteyiz çünkü verileri biz yarattık :)

Korelasyon bize sadece ve sadece bu iki değişken arasında bir ilişki olup olmadığını ve kuvvetini söyleyebilir. Ancak regresyon öyle mi? Tabi ki hayır, regresyon bize yaşın gelir üzerindeki etkisini söyleyebilir. Ancak regresyon da sadece tahmin edip bize yaklaşık bir değer üretebilir. İşte modelleme yaparken başarı oranının artırılması için yapılan optimiazyon/transformansyon gibi çalışmalar bu yüzdendir.

Şekil 1'de yer alan noktaların arasında artık güçlü bir ilişki olduğunu korelasyon analizinde gördük. Peki biz bu noktaların arasından bir doğru(line) çizsek ve yeni gelecek olan değerler için yardımcı olsa, olabilir sanki. Scatter plot içindeki ilk noktaya bakalım 20 yaşında olan birisinin geliri 2,500 TL (nettir umarım) olarak görülürken 36 yaşındaki birisi 15,552 TL kazanıyor. Ama 34 yaşındaki birisi de 19,652 TL alıyor. Yani mükemmel doğrusallık bulunmuyor. Bizim öyle bir çizgi (line) belirlememiz gerekiyor ki tüm bu ortalamanın dışında kalanlar için bile yaklaşık bir tahminleme yapabilsin. O halde en popüler formül olan (E=mc²)’den sonra gelen regresyon formülünü paylaşıyorum.

Y = mX + b (doğrunun eğimi)

Y tahmin edilecek değer anlamında burada “Gelir” değişkenini ifade eder (dependent variable, target). X ise bağımsız değişkendir (Yordayan, independent variable, predictor). “m” eğimi verirken “b” ise sabit hata değeridir. Eğer biz doğruyu 20 yaşındaki noktadan itibaren çizmeye başlarsak formül “2500 = m20 + b” olacaktır. Doğru bu noktadan geçtiği için hata terimi 0'dır.

Python’da Basit Lineer(Doğrusal) Regresyon Analizi

Öncelikle Python’da bulunan Statsmodels kütüphanesi üzerinden regresyon analizi yapacağız. Bunun sebebi Statsmodels’in tek bir fonksiyonu ile modelin yorumlanmasına izin veren tabloyu verebilmesi. Model yorumundan sonra ise Sklearn kütüphanesi ile makine öğrenmesini sağlayıp test edeceğiz.

Bu bölümün başlığında basit yazılmasının sebebi doğrusal regresyon modelinin iki değişken arasında olmasından kaynaklanmaktadır. Aşağıdaki kodda görüldüğü üzere en saf hali ile statsmodels kütüphanesinde regresyon modeli kurulur.

import statsmodels.api as sm
x = df.yas # bağımsız değişken (independent variable)
y_gercek = df.gelir # bağımlı değişken (target, dependent variable)
# Sabitin eklenmesi
x = sm.add_constant(x)
# Modelin çalıştırılması
model = sm.OLS(y_gercek,x).fit()
# Modelin yorumlanacağı tablo
print(model.summary())

Yukarıdaki kodda görüldüğü üzere önce kütüphaneleri yükledik. Sonra makinemize öğretmek için kim bağımlı (target) kim bağımsız değişken onları gösterdik. Statsmodels kütüphanesinde yer alan OLS fonksiyonunun içerisine değişkenleri tanımlayıp modeli eğittik. Eğitilen modelin çıktılarını ise değerlendirmek için aşağıdaki tabloya bir bakalım.

Tablo 2: Regresyon Model Çıktıları

Tablo 2'de yer alan kırmızı ile işaretli maddelerin anlamlarını verilen sonuçlar ile birlikte yorumlayarak açıklayalım.

  1. OLS (Ordinary Least Squared): Sıradan en küçük kareler yöntemidir. Doğrusal regresyon modeli kurulurken verilerin ortasından geçen eğime (çizgiye) en az kare farkı ile yaklaşmaya çalışan bir yöntemdir.
  2. R-Squared (R2): Verilerin yerleştirilmiş regresyon çizgisine ne kadar yakın olduğunun istatistiksel bir ölçüsüdür. Bizim tablomuzda bu değer 0.80 olup görece iyi bir sonuç diyebiliriz. Sosyal bilimler için 0.70 üzeri ve doğa bilimleri için ise değişkenlik göstermekte olup 0.60 üzeri kabul edilebilir bir başarı ölçütü sayılabilir.
  3. Adjusted (Düzenlenmiş) R-Squared: Bu değer genellikle çoklu regresyon analizinde kullanılır. Modele değişken eklendikçe R2 değeri değişkeni etkili varsayıp varyansını açıkladığını sanabilir. Ancak düzenlenmiş R2 mantığında her bir değişkenin bağımlı değişken üzerindeki etkisi ölçülerek daha optimum sonuçlar vermektedir. Tabloyu yorumlarken bu iki değerin birbirine yakın çıkması önemli bir konu olup bizim tablomuzda her iki değerinde (0.80-0.79) birbirine yakın olduğu görülmektedir. Bu çıktının anlamak için şöyle bir örnek verilebilir. Örneğin bir evin hem brüt hem de net metrekaresi bulunur. Brüt metrekare her şeyi içine dahil ederken net ise sadece yaşam alanına odaklanır. Dolayısı ile ev bakarken bu ikisi arasındaki farkı bilmek önemlidir. Model sonucunu incelerken de bu alana bakılması önemlidir.
  4. Coefficients (Katsayılar): Regresyon katsayısı, iki veya daha fazla değişken arasındaki ortalama fonksiyonel ilişkinin istatistiksel bir ölçüsüdür. Tablo 2'de const için yazan yerde regresyon formülündeki sabitin değerini verirken, Yas için yazan yerde ise yaştaki bir birimlik değişimde gelirin ne kadar değişeceğini göstermektedir. Dolayısı ile regresyon tahmin yaparken buradaki katsayılardan yararlanır. Formülde yerine yerleştirecek olursak; Y(tahmin edilecek değer) = X(Yaş) * m(Eğim) + b (sabit değer). Örneğin: Yaşı 20 olan birinin gelirine 2666.666 demiştik. Şimdi regresyon doğrusunu çizdikten sonra bu modele göre yaşı 20 olan birisine ne kadarlık bir gelir belirleyecek hesaplayalım. Y (Gelir) = (20 * 953.512) + (-17320) ise tahmini gelir = 1749 olacaktır. Arada neredeyse 900 TL gibi bir fark var. Yüksek görünse de doğrusal bir model olduğu için en optimum noktadaki eğimin verdiği sonuç budur.
  5. P-Value: Bu değer bize bağımsız değişkenden çıkan katsayının istatistiksel olarak anlamlı olup olmadığını vermektedir. Bilim dünyasında genel olarak kabul edilen anlamlılık değeri x<0.05'dir. Eğer bu değerin üzerinde bir sonuç çıkıyorsa ilgili bağımsız değişkenin modele etkisi anlamlı değildir. Bu değer, çok değişkenli regresyon analizinde değişkenlerin seçimi sırasında kullanılmaktadır. Tablo 2'de çıkan P-Value değerinin ise .05'den küçük olduğu görülmekte olup yaş değişkeninin katsayısının istatistiksel olarak anlamlı olduğu düşünülebilir. Aslında yukarıdaki (4. madde) işlemin yapılmasından önce bu değerin kontrolünün sağlanması gerekmektedir.

Şimdi tablomuzu da incelediğimize göre model sonucunda oluşan regresyon doğrusunu yukarıda yer alan şekil 1'deki scatter plotun üzerine çizdirelim.

fig, ax = plt.subplots(figsize=(12, 8))
fig = sm.graphics.plot_ccpr(model,"yas" ,ax=ax)
plt.title("Basit Doğrusal Regresyon ile Yaş - Gelir Tahmini")
plt.xlabel("Yaş(X): Bağımlı Değişken")
plt.ylabel("Gelir(Y): Bağımsız Değişken")
plt.show()
Şekil 2: Regresyon Doğrusunun Gösterimi

Şekil 2'de de görüldüğü üzere regresyon doğrusu noktalar arasında en az hata yaparak çizilmiş durumda.

Peki inşa edilen modelde yaşa göre gelir ne çıkmaktadır? Bunun için önceden yazdığımız gelir ile tahmin edilen geliri aynı tabloda yan yanan getirerek inceleyelim.

# Modelin var olan yaş değerleri için çalıştırılması
y_pred_stat = model.predict(x)
# Gerçek gelir değerleri ile tahmin edilen gelir değerlerinin birleştirilmesi
karsilastirma = pd.DataFrame({'Gercek_Degerler': y_gercek, 'Tahmin_Degerler': y_pred_stat}).sort_index()
# Gerçek değer ile tahmin edilen değer arasındaki hata
karsilastirma["tahminleme_hatalari"] = karsilastirma.Gercek_Degerler - karsilastirma.Tahmin_Degerler
print(karsilastirma)
Tablo 3: Gerçek ile Tahmini Gelirlerin Karşılaştırılması

Tablo 3'de görüldüğü üzere gerçek değerler ile tahmin edilen değerler arasında bir paralellik bulunuyor. Aradaki farkı ise hata değerinin olduğu kolonda görebilirsiniz. En fazla hata en yüksek gelirin olduğu satırda görülmektedir.

Sklearn Üzerinden Basit Doğrusal Regresyon

Python’da makine öğrenmesi algoritması inşa ederken Sklearn kullanılmasının birçok sebebi bulunmaktadır. Pipline gibi fonksiyonlara sahip olması ve geniş bir algoritma ağının bulunması bu kütüphanede yer alması sebepleri başta gösterilebilir. Aynı veri için Sklearn’de modeli inşa edelim.

# Yazının başında zaten bu kütüphaneleri import etmiştik ama yeniden paylaşıyorum
from sklearn.linear_model import LinearRegression
from sklearn import metrics
# Doğrusal regresyon sınıfı çağırılıyor
lr = LinearRegression()

# Model verileri içine alarak uyarlanıyor
lr.fit(x,y_gercek)

# uyarlanan model aynı yaşlar için tahmini gelir sağtıyor
y_pred_sklearn = lr.predict(x)

# Gerçek gelir değerleri ile tahmin edilen gelir değerlerinin birleştirilmesi
karsilastirma = pd.DataFrame({'Gercek_Degerler': y_gercek, 'Tahmin_Degerler': y_pred_sklearn}).sort_index()
# Gerçek değer ile tahmin edilen değer arasındaki hata
karsilastirma["tahminleme_hatalari"] = karsilastirma.Gercek_Degerler - karsilastirma.Tahmin_Degerler
print(karsilastirma)

Kodda görüldüğü üzere Sklearn kütüphanesi ile Statsmodels neredeyse aynı şekilde modeli çalıştırıyor. Ancak Sklearn kütüphanesinde Statsmodels’de olduğu gibi analiz özeti (Tablo 2) çıkarmıyor. Ancak yukarıdaki kodda yine gerçek ve tahmini gelirler ile hataları çıkarabileceğiniz karşılaştırma tablo kodunu ekledim. Ayrıca aşağıda modele dair diğer çıktıları da bulabilirsiniz.

print("coefficients ",lr.coef_)  # katsayı
print("intercept",lr.intercept_) # Kesim noktası
print("r2 score",metrics.r2_score(y_gercek,y_pred_sklearn))
print('Mean Squared Error:', metrics.mean_squared_error(y_gercek, y_pred_sklearn))
print('Root Mean Squared Error:', np.sqrt(metrics.mean_squared_error(y_gercek, y_pred_sklearn)))

Sonuç

Bu yazıda olabildiğince regresyonun kod üzerinde çalışma mantığına denildi. Bununla beraber derin analizler için Statsmodels ve makine öğrenmesi için Sklearn kütüphanelerinin kullanımının daha uygun olacağı vurgulanmıştır.

--

--