Titanic Verisi ile No Free Lunch Teoremi ve Algoritmaların Kaggle’daki Başarısı

https://www.kaggle.com/c/titanic

No Free Lunch Teoremi kısaca Makine Öğrenmesi algoritmalarının birbirlerine üstün olmadıklarını belirtir. Bir iş probleminin çözümü, kullanılan algoritmaya bağlı değildir veri setine bağlıdır!

Bu uygulamada herkesin nefret ettiği Titanic verisi ile sadece algoritmaların varsayılan hiperparametrelerini kullanarak tahmin değerleri üreteceğim ve her bir algoritmanın çıktılarını (submission) Kaggle’a yükleyeceğim ve ardından Kaggle’daki skorlarımı sizler ile paylaşacağım.

İlerideki zamanlarda bu çalışmayı genişletmeyi planlıyorum. Her bir algoritma için Öznitelik Mühendisliği (Feature Engineering) ve Hiperparametre Ayarlamaları (Hyperparameter Tuning) yaparak model performanslarını arttırmaya çalışabilirim ve bu işlemler sonucunda da Kaggle’daki skorumun ne kadar değiştiğini görebiliriz.

Bu çalışma içerisinde Lojistik Regresyon, Naive Bayes, KNN – En Yakın Komşu, SVC – Karar Destek Sınıflandırıcı, CART – Sınıflandırma ve Regresyon Ağaçları, Topluluk Öğrenme (Bagging, Voting, Random Forest), Boosting (Ada Boost, GBM – Gradient Boosting Machine, XGBoost, LightGBM, CatBoost) algoritmaları kullanılmıştır ve en sonunda her bir modelin başarı oranları karşılaştırılmıştır. Ayrıca vakit buldukça yeni ve farklı algoritmaları da buraya ekleyeceğim.

1. Kütühaneler

# Base
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

########## Sklearn #############

# Ön İşleme
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split

# Metrikler
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.metrics import roc_auc_score, roc_curve

# Modeller
from sklearn.linear_model import LogisticRegression     # Lojistik Regresyon
from sklearn.naive_bayes import GaussianNB              # Naive Bayes
from sklearn.neighbors import KNeighborsClassifier      # KNN - En Yakın Komşu
from sklearn.svm import SVC                             # SVC - Karar Destek Sınıflandırıcı
from sklearn import tree                                # CART - Sınıflandırma ve Regresyon Ağaçları
from sklearn.tree import DecisionTreeClassifier         # CART - Sınıflandırma ve Regresyon Ağaçları
from sklearn.ensemble import BaggingClassifier          # Bagging
from sklearn.ensemble import VotingClassifier           # Voting 
from sklearn.ensemble import RandomForestClassifier     # Random Forest
from sklearn.ensemble import AdaBoostClassifier         # Ada Boost
from sklearn.ensemble import GradientBoostingClassifier # GBM - Gradient Boosting Machine
from xgboost import XGBClassifier                       # XGBoost | !pip install xgboost
from lightgbm import LGBMClassifier                     # LightGBM | !conda install -c conda-forge lightgbm
from catboost import CatBoostClassifier                 # CatBoost | !pip install catboost

# Warnings
import warnings
warnings.filterwarnings("ignore")

2. Veri

Kaggle’dan alınan Titanic verisi Train ve Test setleri olmak üzere iki tanedir.

train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")
tr = train.copy()
ts = test.copy()
train.head() 
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th…female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
Tablo-1: Verinin ilk gözlemleri

NOT: Bu çalışmada sadece ham Titanic verisinin algoritmalardaki başarısının nasıl olduğu gözlenecektir. Bu yüzden bir Keşifçi Veri Analizi (EDA) yapılmayacaktır. Başka bir çalışmada hem keşifçi veri analizi ve hem de öznitelik mühendisliği yapılarak modelin başarısı arttırılabilir.

3. Eksik Gözlemler

train.isnull().sum(), test.isnull().sum() 
(PassengerId      0
 Survived         0
 Pclass           0
 Name             0
 Sex              0
 Age            177
 SibSp            0
 Parch            0
 Ticket           0
 Fare             0
 Cabin          687
 Embarked         2
 dtype: int64, PassengerId      0
 Pclass           0
 Name             0
 Sex              0
 Age             86
 SibSp            0
 Parch            0
 Ticket           0
 Fare             1
 Cabin          327
 Embarked         0
 dtype: int64)

Veride nümerik değişkenler eksik gözlem barındırdığından bu gözlemler için ortalama değerler atanır.

train["Age"] = np.where(train.Age.isnull(), train.Age.mean(), train.Age)
test["Age"] = np.where(test.Age.isnull(), test.Age.mean(), test.Age)
test["Fare"] = np.where(test.Fare.isnull(), test.Fare.mean(), test.Fare)

4. Makine Öğrenmesi Giriş

PassengerId ve Name değişkenleri çıkartılır. Name değişkeni daha sonrası için kullanılabilecek bir değişkendir fakat ilk basit modeller kurmak adına çıkartılabilir.

train.drop(["PassengerId", "Name"], axis = 1, inplace = True)
test.drop(["PassengerId", "Name"], axis = 1, inplace = True)

4.1. Label Encoder

cat = train.select_dtypes(include=["object"]).columns

for col in train[cat].columns:
        
    train[col] = train[col].astype(str)
    test[col] = test[col].astype(str)
        
    le = LabelEncoder()
    le.fit(list(train[col])+list(test[col]))
    train[col] = le.transform(train[col])
    test[col]  = le.transform(test[col])

Yazı tipinde olan kategorik verilerin sayısal hale dönüştürülmesi için Label Encoder kullanılır.

4.2. Train Test Split

Zaten titanic verisi train test olarak ayrılmış fakat burada modelin ne kadar iyi olduğunu ölçmek için train veri setini train test diye iki ayrı parçaya bölüyoruz.

X_train, X_test, y_train, y_test = train_test_split(train.drop("Survived", 
                                                               axis = 1),
                                                    train.Survived, 
                                                    test_size = 0.20,
                                                    random_state = 41)

4.3. Sınıflandırma Algoritmaları

Bu bölümde etiketli train verisi üzerinden veriyi ikiye parçalayarak ayrıca train test veri setleri oluşturmuştuk. Bunu yapmamızın amacı hangi modellerin daha iyi performans gösterdiğini bulmak.

# Logistic Regression
log = LogisticRegression(solver = "liblinear")
log.fit(X_train, y_train)
y_pred_log = log.predict(X_test)

# Naive Bayes
nb = GaussianNB()
nb.fit(X_train, y_train)
y_pred_nb = nb.predict(X_test)

# KNN
knn = KNeighborsClassifier() # k (n_neighbors) sayısı ön tanımlı değeri 5'tir.
knn.fit(X_train, y_train)
y_pred_knn = knn.predict(X_test)

# SVM - Linear
svc = SVC(kernel = "linear", probability=True) 
svc.fit(X_train, y_train)
y_pred_svc = svc.predict(X_test)

# SVM - RBF
svc_rbf = SVC(kernel = "rbf",probability=True) 
svc_rbf.fit(X_train, y_train)
y_pred_svc_rbf = svc_rbf.predict(X_test)

# CART
cart = DecisionTreeClassifier()
cart.fit(X_train, y_train)
y_pred_cart = cart.predict(X_test)

# BAGGING
bag = BaggingClassifier()
bag.fit(X_train, y_train)
y_pred_bag = bag.predict(X_test)

# VOTING
clf1 = LogisticRegression(solver = "liblinear")
clf2 = RandomForestClassifier()
clf3 = GaussianNB()
clf4 = KNeighborsClassifier()

vote = VotingClassifier(
    estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='hard')

vote.fit(X_train, y_train)
y_pred_vote = vote.predict(X_test)

# RANDOM FOREST
rf = RandomForestClassifier()
rf.fit(X_train, y_train)
y_pred_rf = rf.predict(X_test)

# ADABOOST
ada = AdaBoostClassifier()
ada.fit(X_train, y_train)
y_pred_ada = ada.predict(X_test)

# GBM
gbm = GradientBoostingClassifier()
gbm.fit(X_train, y_train)
y_pred_gbm = gbm.predict(X_test)

# XGBOOST
xgb = XGBClassifier()
xgb.fit(X_train, y_train)
y_pred_xgb = xgb.predict(X_test)

# LGBM
lgb = LGBMClassifier()
lgb.fit(X_train, y_train)
y_pred_lgb = lgb.predict(X_test)

# CATBOOST
cat = CatBoostClassifier()
cat.fit(train.drop("Survived",axis = 1), train.Survived, verbose = 0)
y_pred_cat = cat.predict(X_test)
ModelTrain AccuracyTest Accuracy
0Lojistik Regresyon0.8061800.810056
1Naive Bayes0.7696630.821229
2KNN0.7879210.692737
3Lineer SVM0.7921350.837989
4RBF SVM0.6867980.675978
5CART0.9985960.810056
6Bagging0.9817420.843575
7Voting0.8581460.849162
8Random Forest0.9985960.882682
9AdaBoost0.8469100.860335
10GBM0.9143260.877095
11XGBoost0.8960670.871508
12LightGBM0.9845510.854749
13CatBoost0.9620790.955307
Tablo-2: Model Performansları

Modellerin accuracy (isabet) oranı değerlerine bakıldığında train ve test ikilisi olarak en iyi sonucu veren algoritma CatBoost olarak karşımıza çıkmaktadır. Fakat çalışma içerisindeki bazı modellerde de denemeler yapılırsa iyi sonuçlar elde edilebilir. Örneğin CART, Bagging, Random Forest, GBM ve LGBM modellerinde train başarı oranı yüksek fakat test başarı oranı düşük.

Yukarıdaki çalışma hangi algoritmaların bu veride daha iyi sonuçlar verebileceğini anlamaya yöneliktir ve train verisi ayrıca train-test diye iki veri setine ayrılmıştır. Şimdi tüm train verisini eğiterek etiketli olmayan test verisindeki tahminler alınıp kaggle’a yüklenecektir ve ardından kaggle’daki başarı skorumuza bakacağız.

Ayrıca tahminlerimizi farklı threshold değerlerine göre yaparsak farklı sonuçlar da elde edebilmemiz mümkün. Burada ilk olarak lojistik regresyonun tahminlerini alacağız ve kaggle’a yükleyeceğiz ardından farklı threshold değerleri ile yeniden tahminler alarak kaggle’a yükleyeceğiz. Başarı oranımızın değişip değişmediğine bakacağız.

4.4. Lojistik Regresyon

log = LogisticRegression(solver = "liblinear")
log.fit(X_train, y_train)
y_predprob = log.predict_proba(X_test)[:,1]


for k in np.arange(0,1.1, 0.1).round(1):
    y_pred = [1 if i > k else 0 for i in y_predprob]
    print("Threshold: "+str(k)+ " ", "|", "Accuracy: "+ str(accuracy_score(y_test, y_pred)))
Threshold: 0.0  | Accuracy: 0.4134078212290503
Threshold: 0.1  | Accuracy: 0.48044692737430167
Threshold: 0.2  | Accuracy: 0.7150837988826816
Threshold: 0.3  | Accuracy: 0.7821229050279329
Threshold: 0.4  | Accuracy: 0.8156424581005587
Threshold: 0.5  | Accuracy: 0.8100558659217877
Threshold: 0.6  | Accuracy: 0.8268156424581006
Threshold: 0.7  | Accuracy: 0.776536312849162
Threshold: 0.8  | Accuracy: 0.6983240223463687
Threshold: 0.9  | Accuracy: 0.6312849162011173
Threshold: 1.0  | Accuracy: 0.5865921787709497

Görüldüğü üzere farklı threshold değerlerine göre tahminler ayarlandığında başarı oranlarının yükselebildiği gözlemlenmektedir. En iyi threshold değeri ise 0.6’dır. Kaggle’a tahminlerimizi yollarken farklı threshold değerlerini denemek yarar sağlayabilir.

log = LogisticRegression(solver = "liblinear")
log.fit(train.drop("Survived", axis = 1), train.Survived)
ypred = log.predict_proba(test)[:,1]
# En iyi threshold 0.6 idi
ypred = [1 if i > 0.6 else 0 for i in ypred]

ts["Survived"] = ypred
submissionlog = ts[["PassengerId", "Survived"]]
submissionlog.to_csv("submissionlog.csv",columns = ["PassengerId", "Survived"] , index = None)
Resim-1: Tahminlerin kaggle’a yüklenmesi ve elde edilen skor.
Resim-2: Lojistik Regresyon modelinin sonucunda Kaggle sıralaması.

Ham veri ile olan ilk modelimiz lojistik regresyonun kaggle’daki başarısı 0.78 olarak çıktı. Bu skor ile 16 bin kişi arasından 5 bin kişi olarak gözüküyorum. Şu an için sıralama hiç fena değil, biraz öznitelik mühendisliği (feature engineering) ve hiperparametre ayarlamaları (hyperparameter tuning) yaparak daha iyi modeller elde edebiliriz ve başarı oranı daha yukarılara çıkarılabilir. Kaggle’da Titanic verisinin doğru sonuçları olduğu için çok sayıda 1 skor elde edenler var 5155. sıralamada olmam bu durum göz önüne alındığında gayet iyi.

5. Model Sonuçları

ModelKaggle Skoru
0Bagging0.80382
1Lojistik Regresyon0.78468
2XGBoost0.77990
3Lineer SVM0.77511
4LightGBM0.77033
5GBM0.76555
6Voting0.76076
7CatBoost0.76076
8Random Forest0.74641
9AdaBoost0.74162
10Naive Bayes0.73205
11CART0.73205
12RBF SVM0.66985
13KNN0.63636
Tablo-3: Kaggle Skorları.
Resim-3: Bagging modelinin sonucu ve Kaggle başarı sıralaması.

Tüm algoritmalarda varsayılan hiperparametreleri kullandık ve yukarıda 14 tane algoritmanın sonuçları paylaşılmıştır. Titanic veri setine göre en başarılı yöntem Bagging olarak karşımıza çıktı. İlk yaptığımız çalışmalarda hangi model daha başarılı diye baktığımızda CatBoost’un sonuçları daha tatmin edici iken günün sonunda Bagging modeli kaggle’da en yüksek skoru verdi. Model geliştirmelerine devam edilerek kaggle’daki skor daha yukarılara çıkartılabilir.

Bir sonraki yazılarda görüşmek üzere.

Kaynak: https://www.udemy.com/course/python-egitimi/

Yazar Hakkında
Toplam 18 yazı
Ekrem Bayar
Ekrem Bayar
Yorumlar (1 Yorum)
Mustafa Vahit Keskin
Mustafa Vahit Keskin Cevapla
- 15:31

Hahaha 🙂

“Bu uygulamada herkesin nefret ettiği Titanic verisi ile sadece algoritmaların varsayılan hiperparametrelerini kullanarak tahmin değerleri üreteceğim ve her bir algoritmanın çıktılarını (submission) Kaggle’a yükleyeceğim ve ardından Kaggle’daki skorlarımı sizler ile paylaşacağım.”

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

×

Bir Şeyler Ara