GitHub üzerinden tam haline bakabilirsiniz: https://github.com/berkanaslan/TitanicDatasetClassificationTutorial
Merhaba, makine öğrenmesinin popüler veri setlerinden birisi olan “Titanic: Machine Learning from Disaster” ile karar ağaçlarını kullanarak bir Python projesi geliştireceğim. Amaç kimin hayatta kaldığını tahmin etmek olacak.
BAŞLANGIÇ
Veri setini yerel bilgisayarıma indirdikten sonra ilk başta Pandas kütüphenesini, ardından veri setlerini uygulamama gömdüm.
#Küpüthaneler
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
egitim = pd.read_csv('train.csv', header = 0)
Ardından, yüklediğim eğitim veri setinin özniteliklerini inceledim.
egitim.info()
Çıktı:
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
Yukardaki tablo sayesinde toplam 891 satır verinin olduğunu ve “Cabin”, “Age” ve “Embarked” adlı özniteliklerde eksik verilerin olduğunu öğrendim. Ayrıca, “Dtype” adlı sütun sayesinde veri tiplerini de öğrendim.
VERİ SETİ DÜZENLEME
Amacımız kimin hayatta kalacağını tahmin etmek olduğu için, pek de işimize yaramayacak olan öznitelikleri modelimizden çıkarabiliriz. Veriyi, hızlı bir inceleme sonucunda, çokça eksik verisi olan Cabin, makine öğrenmesine faydası olmayacak olan Name ve Ticket başlıklı özniteliklerini veri setimden çıkarıyorum.
cikarilacaklar = ['Name','Ticket','Cabin']
egitim = egitim.drop(cikarilacaklar, axis = 1)
Bir sonraki veri düzenleme işlemime, egitim.info() metodu kullanımı sonucunda eksik verilerin olduğunu öğrendiğim veri setinden eksik verilerin bulunduğu satırların silinmesini sağlayacağım.
egitim = egitim.dropna()
Bu işlemin ardından tekrardan egitim.info() metodunu kullanarak veri hakkında bilgi ediniyorum.
Çıktı:
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 712 non-null int64
1 Survived 712 non-null int64
2 Pclass 712 non-null int64
3 Sex 712 non-null object
4 Age 712 non-null float64
5 SibSp 712 non-null int64
6 Parch 712 non-null int64
7 Fare 712 non-null float64
8 Embarked 712 non-null object
dtypes: float64(2), int64(5), object(2)
Yukarıda görüldüğü üzere, toplam satır sayım başlangınçta 891 iken artık 712 olarak uygulamamda duruyor ve artık 9 öznitelikten oluşuyor.
VERİ DÖNÜŞTÜRME İŞLEMLERİ
Verilerimizi, makine öğrenmesinin anlayabileceği bir dile yani 0 ve 1’lerden oluşan bir yapıya dönüştürmemiz gerekiyor. Bu amaçla, öğrenme algoritması üzerinde büyük bir öneme sahip olacağını düşündüğüm 3 özniteliği; Pclass, (Yolcu sınıfı) Sex, (Cinsiyet) ve Embarked (Biniş noktası) başlıklı öznitelikleri kullanacağım.
Veri dönüştürme işlemleri için Pandas kütüphanesinin get_dummies metodunu kullanacağım. Bu metot sayesinde kategorik verileri, yer tutucu değişkenler ile değiştirmiş olacağım. Bu işlemi, her bir satıra uygulayabilmek adına da bir for döngüsünden yararlanacağım.
yolcular = []
sutunlar = ['Pclass','Sex','Embarked']
for sutun in sutunlar:
yolcular.append(pd.get_dummies(egitim[sutun]))
Yukarıdaki kod sayesinde yolcular adlı bir liste içerisinde, Pclass, Sex ve Embarked adlı özniteliklerimizin ayrı dönüşümlerini tamamladık. Dönüşüm sonucunda öznitelikler, içerisinde bulundurduğu kategorik sınıfların, sütun başlıklarından oluşmaya başladı. Örnek vermek gerekirse, x satırı y sütunu özelliği taşıyor ise eşleşen hücre değeri 1, diğerleri 0 değeri taşıyacak hale geldi. Buna One Hot Encoding dönüşümü de diyebiliriz. Artık kodlarımı çalıştırıp elde ettiğim DataFrame’leri inceleyebilirim.

Yukarıdaki görüntüde soldan sağa, Pclass, Sex ve Embarked özniteliklerinin dönüşüm geçirmiş DataFrame’lerini başarıyla görüntüleyebildim. Her bir öznitelik ayrı bir DataFrame olduğu için, bu DataFrame’leri birleştirmem gerekiyor.
Tek bir DataFrame elde etmek için yine Pandas kütüphanesinin bir metotu olan concat metodunu kullanıyorum. Metodu kullandıktan sonra sonucu görüntüleyebilmek adına değişkenimi konsola yazdıracağım. Burada belirttiğim axis, “x’inci index değerinden itibaren” anlamı taşımakta.
yolcular = pd.concat(yolcular, axis = 1)
print(yolcular)
Çıktı:
1 2 3 female male C Q S
0 0 0 1 0 1 0 0 1
1 1 0 0 1 0 1 0 0
2 0 0 1 1 0 0 0 1
3 1 0 0 1 0 0 0 1
4 0 0 1 0 1 0 0 1
.. .. .. .. ... ... .. .. ..
885 0 0 1 1 0 0 1 0
886 0 1 0 0 1 0 0 1
887 1 0 0 1 0 0 0 1
889 1 0 0 0 1 1 0 0
890 0 0 1 0 1 0 1 0
Yukarıdaki veri kesitinden de anlaşılacağı üzere, female ve female adında iki özniteliğimiz bulunmakta. Birisi 1 iken diğeri 0 değeri alıyor. İki öznitelikten birisini silip bir tanesi ile devam edebiliriz. Örneğin, 4. satır için female değeri 0 iken male değeri 1 olarak gözükmekte. Ben eğer female sütununu silersem ilgili satırın male değerine baktığımda zaten 1 mi yoksa 0 mı olduğunu anlayabilirim.
yolcular = yolcular.drop(['female'], axis = 1)
Bu işlem sonrasında artık dönüştürdüğümüz öznitelikler ile dönüşüm uygulamadığımız öznitelikleri birleştirebiliriz. Ancak bu birleştirme işleminde kullanacağımız eğitim adlı değişken de bulunduğu için, içerisinden dönüşüm uyguladığımız öznitelikeri çıkaracağız. Yine bu işlemler için tekrardan concat ve drop metotlarını kullanacağım.
egitim = pd.concat((egitim,yolcular), axis = 1)
egitim = egitim.drop(['Pclass','Sex','Embarked'], axis = 1)
MAKİNE ÖĞRENMESİ İŞLEMLERİ
Artık makine öğrenmesi işlemlerine geçebilirim. Bu bölümde,
X: Öznitelikler
Y: Survived çıktıları değerlerini taşıyacak.
X = egitim.values
Y = egitim['Survived'].values
X, içerisinde 1 sütun başlıklı olarak hala Survived özniteliğini taşıyor. Bunu girdi değişkenlerinden çıkarmam gerekiyor.
X = np.delete(X,1,axis=1)
Artık veri setimi, scikit kütüphanesinden kullanacağım train_test_split ile %70 eğitim – %30 test olarak parçalayabilirim.
X_train, X_test, y_train, y_test=train_test_split(X,Y,test_size=0.3, random_state=0)
MAKİNE ÖĞRENMESİ ALGORİTMASI KULLANIMI VE MODELİN TESTİ
Basit bir makine öğrenmesi algoritması olan Decision Tree algoritmasını kullanacağım.
from sklearn import tree
siniflama = tree.DecisionTreeClassifier(max_depth=5)
siniflama.fit(X_train,y_train)
skor = siniflama.score(X_test,y_test)
Yukardaki kod bloğu sayesinde, train verilerimizi fit() metodu sayesinde eğittim. Ardından, önceden parçalama işlemi yaptığımız test verilerimiz ile başarı oranımızı skor adlı değişkenin içine attım. Son olarak skoru konsola yazdıracağım.
print("Başarı: ",skor)
Çıktı:
Başarı: 0.7476635514018691
Başarılı bir modelleme sonucunda 0.747 gibi bir skor elde ettim. Modelin %74 doğrulukla çalışıyor olmasını kabul edilebilir bir değer olarak yorumlayabiliriz.
TAHMİN VE DOĞRULUK TABLOSU SKORU
Buraya kadar özetle, verilerin düzenlenmesi, öğrenme algoritmasının kullanılması ve test edilmesi adımlarını tamamladım. Şimdi ise eğitim veri setimizi kullanarak kendi Survived tahminlerimi elde edeceğim. Ardından gerçek Survived değerleri ile kıyaslayarak bir doğruluk tablosu skoru elde edeceğim.
from sklearn.metrics import accuracy_score
tahminler = siniflama.predict(X)
as_egitim = accuracy_score(tahminler, Y)
print("Doğruluk tablosu skoru: ", as_egitim)
Yukarıdaki kod parçacığında, scikit kütüphanesinden accuracy_score’u uygulamama import ettikten sonra predict() metodu ile uygulamamın, eğitim veri içerisinden Survived sütununu göstermeden tahminlerde bulunmasını ve bu tahminleri tahminler adlı değişkende saklanmasını sağladım. Ardından accuracy_score() metodunu kullanarak tahminler ile, içerisinde eğitim verimden gerçek Survived değerlerini taşıyan Y değişkenlerinin skorunu konsola yazdırdım.
Çıktı:
Doğruluk tablosu skoru: 0.848314606741573
CONFUSION MATRIX KULLANIMI
Yukarıda uygulamanın doğruluk skorunu elde ettik ancak, doğruluk skoru tek başına bir başarı ölçme kriteri olamaz. Diğer kriterlere (hata oranı, hassasiyet vb.) bakabilmek için confusion matrix kullanacağım. Bunun için pandas kütüphanesinden crosstab() metodu kullancağım.
confusion_matrix = pd.crosstab(Y, tahminler, rownames=['Gerçek'], colnames=['Tahmin'])
print (confusion_matrix)
Çıktı:
0 1
0 371 53
1 55 233
Yukarıda elde ettiğim değerler sayesinde, accuracy score’un sağlamasını yapabilir, hata payını ve hassasiyetini ölçebilirim.
Accuracy Score: (371+233) / 712 = 0.848314606741573
Error Rate: (55+53) / 712 = 0. 151685393258427
True Positive Rate: 233 / (55+233) = 0,8090277777777778
False Positive Rate: 53 / (371+53) = 0,125
SONUÇ
Yukarıdaki confusion matrix değerleri ışığında accuracy score değerimizin doğruluğunu sağladık. Ayrıca elde ettiğimiz hassaslık değerine ve diğer başarı kriterlerine bakacak olursak, uygulamamızın yaklaşık olarak her 5 kişiden 4’ünü doğru tahmin ediyor olduğundan bahsedebilir, başarılı bir sınıflandırma işlemi yapıyor diyebiliriz.
Detaylı bilgiler için:
- Titanic: Machine Learning from Disaster, https://www.kaggle.com/c/titanic
- pandas.concat, https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html
- pandas.get_dummies, https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html
- 1.10. Decision Trees, https://scikit-learn.org/stable/modules/tree.html
- Decision Tree Classification in Python, https://www.datacamp.com/community/tutorials/decision-tree-classification-python
- Example of Confusion Matrix in Python, https://datatofish.com/confusion-matrix-python/
- Hata Matrisini Yorumlama, https://www.veribilimiokulu.com/hata-matrisini-confusion-matrix-yorumlama/
- Öne çıkan görsel: https://www.pinterest.dk/pin/684758318332122509/