Veri ön işleme adım 3 : Transformation

This image has an empty alt attribute; its file name is we-already-tried-using-facts-its-time-for-another-approach.jpg

Veri ön işleme adımlarını ayrıntılı ve uygulamalı olarak anlattığım yazı dizisinde önce eksik gözlem analizini yaptık sonra aykırı değer analizini gerçekleştirdik ve nispeten datamızı temizlemiş önümüze çıkabilecek taşların yarısını yoldan çekmiş olduk. Bu adımları geçtikten sonra yapmamız gereken önemli adımlardan bir diğeri ise değişken dönüşümleri. Peki değişken dönüşümü neden önemli yapılmazsa nelerle karşılaşırız gelin birlikte bu konular üzerinde konuşalım.

Değişken dönüştürme işlemleri hem sayısal değişkenler hem de kategorik değişkenlerde yapılabilir. Ancak her iki değişken tipinde uygulama amaçları ve yöntemleri birbirinden farklıdır. Şimdi sırayla ikisine de göz atalım.

Konuya geçmeden önce görselle bağlantı kurarak kısa bir şey söylemek istiyorum. Veri bilimi dünyasının hiç bir aşamasında genel geçer bir yargı yoktur. Tam yönteminizi bulduğunuzu düşündüğünüz anda farklı veri setleri için yöntemlerinizin çuvalladığını görebilirsiniz. Bu yüzden bulduğumuz her şeyi okumak , okuduklarımızı denemek bize farklı bir pencere sunabilir 🙂

Sayısal Değişkenlerde Dönüşüm / Ölçeklendirme

Sayısal olarak toplanan verilerin ölçekleri çoğunlukla birbirinden farklıdır. Bu farklılığı bazı makine öğrenmesi algoritmaları sevmez ve veri dönüşümü yapılmadan uygulandığında iyi performans gösteremez. Aynı zamanda farklı ölçeklere sahip değişkenleri model sonunda birbiriyle karşılaştırmamız doğru olmaz çünkü iki değişkenin konuşma dili aynı değildir.  Peki bu ölçek farklılığı ne anlama geliyor ve değişkenleri neden karşılaştıramıyoruz? İlkokulda sınıf arkadaşınız ile muhakkak karşılaştırılmış ve bu durumu hiç adil bulmamışsınızdır. Bu karşılaştırmanın adil gelmemesinin en büyük sebebi diğer kişinin maddi ve manevi olarak sizinle farklı şartlarda olmasıdır. Değişkenleri karşılaştırırken de iki birim üzerinden yorum yapmak için ölçeklerin aynı olması gerekir. Bir makine öğrenmesi modeli tasarladığınızı düşünün ve veri setinizde 5 değişken olsun. Bu değişkeleri Yaş, Kilo, Boy, Cinsiyet ve IQ olarak ele alalım. Burada her bir değişkenin ölçüm metriği farklılık gösterir. Kilo kg, boy cm, yaş yıl ve IQ matematiksel bir değer alır. Bu değişkenleri bir dönüşüme tabii tutmadan model sonucunda önemlilik ve öncelik düzeylerini karşılaştırmak sağlıklı olmayacaktır. Bir dönüşüm uygulayarak bu değişkenleri aynı metriğe getirmiş oluruz böylelikle artık hem karşılaştırma yapabiliriz hem de algoritmalardan daha iyi performans ede edebiliriz.

Değişken Dönüşüm Yöntemleri

Bu aşamada iki farklı yol ayrımına geliriz. Değişken dönüşümü yapacağız ama bunu normalizasyon ile mi standardizasyon ile mi yapmalıyız? Burada her veri için kesin doğrudur diyebileceğimiz bir yöntem yok. Dikkat etmemiz gereken şey temel olarak iş probleminize uygun hareket etmeniz ve dönüşüm yapacağınız değişkenlerin normal dağılıma sahip olup olmadığı. Gauss dağılıma sahip verilerinizi normalizasyon ile dönüştürebilirsiniz eğer verileriniz Gauss dağılımdan gelmiyorsa o zaman standardizasyon uygulayarak verilerinizi ölçeklendirebilirsiniz. Eğer vaktiniz varsa veri setine her iki yöntemi de uygulamak ve sonuçları karşılaştırarak karar vermek en doğrusu olur.

Not!! Eğer tek veri seti üzerinden çalışıyorsanız (Test ve Train için ayrı veri setleriniz yoksa) öncelikle verinizi test-train olarak ayırmanız faydalı olur. Çünkü ölçeklendirme yaparken train setinden test setine bilgi sızabilir. Bu durum modelimiz için yanıltıcı sonuçlara sebep olur. 

1) STANDART SCALER

Standardizasyon işleminde her bir sütundaki gözlem birimi ortalamadan çıkarılır ve standart sapmaya bölünür. Böylelikle değişkenler ortalaması 0 varyansı 1 olan normal dağılım aralığına getirilmiş olur. Ancak bu yöntem verinin normal dağıldığı varsayımına dayanır işleme geçmeden önce bu varsayımı kontrol etmelisiniz.  Standardizasyon ölçeklendirmesi veride bir bilgi kaybına/değişimine neden olmaz yalnızca değişkenleri belirli bir standarda taşımış olur. Bu dönüşümden sonra değişkenler [-1,1] arasında değerler alırlar.

This image has an empty alt attribute; its file name is 1562153074679.png
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

std_scaler[['mileage','engV']] = scaler.fit_transform(std_scaler[['mileage','engV']])
std_scaler
Dönüşümden sonra değerler standartlaştırıldı.

2) NORMALİZASYON

Normalizasyon işleminde bilmemiz gereken nokta dönüşümün sütun bazında değiş satır bazında olduğudur. Normalizasyon işleminde verinin varyansını, ortalamasını ve dağılımını değiştirmez. Bu işlemden sonra veriler [0,1] arasında değer alırlar.

from sklearn import preprocessing
normalize_df[['mileage','engV']]=preprocessing.normalize(normalize_df[['mileage','engV']])
normalize_df.head()

3) MİN-MAX SCALER

Öncelikle veri setinde (sütun bazında) minimum ve maksimum değerleri bulur daha sonra her bir gözlem birimini minimum değerden çıkarır ve maksimum-minimum değerine böler. Burada diğer yöntemlerin aksine feature_range(min,max) parametresini kullanarak değişkenlerin ölçekleneceği aralığı kendimiz belirtebiliriz. Eğer bu parametreyi boş bırakırsak default olarak değişkenleri [0,1] aralığında ölçeklendirir.

This image has an empty alt attribute; its file name is scr.jpg
#MinMaxScaler() argümanının içerisine range belirtmezsel default olarak (0,1) aralığını kullanır.
trans = MinMaxScaler()
minmax_df[['mileage','engV']]= trans.fit_transform(minmax_df[['mileage','engV']])
minmax_df.head()

4) MAXABS SCALER

MaxAbs ölçekleme yönteminde öncelikle sütundaki her bir değişkenin mutlak değeri bulunur daha sonra ise mutlak değerce maksimum değer tespit edilir ve tüm gözlem birimleri (X)  max|X| değerine bölünür. Böylelikle değişkenler [-1,1] aralığına çekilerek ölçeklenmiş olur.

This image has an empty alt attribute; its file name is scr-1.jpg
from sklearn.preprocessing import MaxAbsScaler
abs_scaler= MaxAbsScaler()
abs_scaler.fit(maxabs_df[['mileage','engV']])
maxscale=abs_scaler.transform(maxabs_df[['mileage','engV']])
scaled= pd.DataFrame(maxscale, columns=['mileage','engV'])
scaled.head()

5) ROBUST SCALER

Aykırı değişken sorunundan bir önceki yazıda uzunca bahsetmiştik. Diğer ölçeklendirme yöntemleri minimum-maksimum- ortalama değeri kullandığı için aykırı değerlere duyarlılardı ancak Robust Scaler yöntemi ölçeklendirmede IQR (Çeyrekler Açıklık) kullandığı için aykırı değerlere karşı sağlam bir yöntemdir.

This image has an empty alt attribute; its file name is scr-2.jpg
from sklearn.preprocessing import RobustScaler
robust_scale = RobustScaler() 
robust_df[['mileage','engV']]=robust_scale.fit_transform(robust_df[['mileage','engV']])

6) QUANTILE TRANSFORMER SCALER

Quantile transformer scaler yöntemi öncelikle değişkeni normal dağılıma dönüştürür daha sonra ölçeklendirir. Bu yöntemde dikkat etmemiz gereken en önemli nokta değişken dağılımının değişmesidir.

Mileage değişkeninin herhangi bir dönüşüm yapılmadan önceki dağılımına bakalım.

Mileage değişkeni sağa çarpık bir dağılıma sahiptir.

NOT: Quantile transformer scalerde çıktı dağılımını ‘normal’, ‘uniform’ olarak belirleyebiliriz. Eğer herhangi bir argüman belirtmezsek default olarak uniform dağılıma göre çıktı verecektir.

from sklearn.preprocessing import QuantileTransformer
quantile = QuantileTransformer(output_distribution='normal')
quantile_df[['mileage','engV']] = quantile.fit_transform(quantile_df[['mileage','engV']])
quantile_df.head()
Çıktı değişkenini normal dağılım olarak belirlediğimizde sağa çarpık dağılıma sahip değişken dönüşümden sonra normal dağılıma dönüştü.
quantile_uniform=new_data.copy()
quantile_uni = QuantileTransformer()
quantile_uniform[['mileage','engV']] = quantile_uni.fit_transform(quantile_uniform[['mileage','engV']])
quantile_uniform.head()
Çıktı dağılımını uniform olarak belirttiğimizde ise uniform dağılıma dönüştü.

7) POWER TRANSFORMER SCALER

Power transformer dönüşümü özellikle normalliğin istendiği durumlarda kullanılır. Değişken varyans durumunda varyansı stabilize etmek ve verideki çarpıklığı azaltmak için maksimum olabilirlik yöntemi kullanılır. Power Transformer ölçeği şuan BOX-COX dönüşümünü ve YEO-JOHNSON dönüşümünü destekler.

from sklearn.preprocessing import PowerTransformer
power = PowerTransformer(method='yeo-johnson', standardize=True)
power_trans[['mileage','engV']] = power.fit_transform(power_trans[['mileage','engV']])

Kaynak : https://scikit-learn.org/stable/auto_examples/preprocessing/plot_all_scaling.html

KATEGORİK DEĞİŞKENLERDE DÖNÜŞÜM

Veri setinde object (cinsiyet, eğitim durumu, sokak adı vb.) tipinde değişkenlerimiz olabilir. Bu değişkenleri modelimizde kullanabilmek için makinenin anlayıp kendince anlamlandıracağı bir formata dönüştürmemiz gerekir. Dönüşümü yaparken öncelikle dikkat etmemiz gereken şey kategorilerin birbiri üzerinde bir üstünlüğü/sıralaması olup olmadığını kontrol etmektir. Kategorilerin birbiri üzerinde nasıl üstünlüğü olur ? Mesela eğitim düzeyi (İlkokul – Ortaokul – Lise – Lisans – Lisansüstü) sıralama gerektiren bir kategoridir bu değişkeni sırasıyla 0-1-2-3-4 olarak makineye öğretmeniz model performansı açısından önemlidir. Diğer yandan cinsiyet değişkenini dönüştürürken böyle bir üstünlük sıralamasına değil 0-1 şeklinde kodlama yaparak değişkenleri makinenin anlayabileceği dile çevirmek yeterli olur. Peki değişken kategorilerinin birbiri üzerinde üstünlüğü/sıralaması yoksa o zaman ne yapmalıyız? Veri setimizde sokak isimlerinin bulunduğu 10 kategorisi bulunan bir değişken olduğunu düşünelim böyle bir durumda kukla değişken (dummy variable) yöntemini kullanarak veri setini öğrenmeye hazır hale getirebiliriz. Kısa bir ön giriş yaptıktan sonra tüm bu yöntemleri sırayla incelemeye başlayalım.

Kategoriler Arasında Sıralama Yoksa

ONE HOT ENCODER (Scikit-Learn)

Kategoriler arasında sıralama olmadığında kullanılan yöntemdir. Cinsiyet değişkenini bu yöntemle dönüştürdüğümüzde kadın ve erkek için iki ayrı sütun oluşturur ve 0-1 olarak değer atar.

#Burada one hot encoding yapmadan önce değişkenleri sayısal forma çevirmeliyiz. Bunun için labelencoder kullanıyoruz.
from sklearn.preprocessing import OneHotEncoder
from sklearn import preprocessing

label_encoder = preprocessing.LabelEncoder()

cat_data['engType']= label_encoder.fit_transform(cat_data['engType']) 
cat_data.head()
encoder= OneHotEncoder()
df_encoder = pd.DataFrame(encoder.fit_transform(cat_data['engType'].values.reshape(-1,1)).toarray())
df_encoder

GET DUMMIES (Pandas)

One Hot Encoder yöntemi ile aynıdır yalnızca dönüşüm yaparken farklı kütüphaneleri kullanırlar. Bu yöntemde değişkenin tüm kategorileri veri setine sütun olarak eklenir ve her satır için sahip olunan kategori sütunda 1 diğer kategoriler ise 0 olarak etiketlenir.

NOT!! Çok kategoriye sahip değişkenler için bu dönüşüm çok boyutluluk ve sparse veri problemine neden olabilir. 

dummy_df=pd.get_dummies(dummy_df,columns=["engType","drive"])
dummy_df.head()

Kategoriler Arasında Sıralama Varsa

ORDINAL ENCODER (Scikit-Learn)

Değişken kategorileri arasında sıralama söz konusu olduğunda bu yöntemi kullanabiliriz.

from sklearn.preprocessing import OrdinalEncoder
col_names=[]
for i in cat_data.columns:
  col_names.append(i)

col_names
ordinal_encoder = OrdinalEncoder()
result = ordinal_encoder.fit_transform(cat_data)
print(result)
ord_enc = pd.DataFrame(result,columns=col_names)

PANDAS MAP FONKSİYONU

Pandas kütüphanesi MAP fonksiyonu aslında Ordinal Encoder ile aynı işlevi görür. Ancak burada manuel olarak bir etiketleme söz konusu olur bu sebeple gözden kaçan kategoriler olabilir. Fazla kategoriye sahip değişkenler için pek kullanışlı olmayabilir.

map_data['engType'].unique()
map_data['engType'] = map_data['engType'] .map({  'Gas':1, 'Petrol':2, 'Diesel':3})

Alternatif olarak cat.codes() kullanılabilir.

map_data['engType'] = map_data['engType'].astype('category').cat.codes

BINARIZE DÖNÜŞÜM

Binarize dönüşümde kategorik datayı önce labelencoder yardımıyla sayısal ifadeye çeviririz daha sonra binary dönüşüm uygularız.

pip install category-encoders
from category_encoders import BinaryEncoder
bin = BinaryEncoder(cols=['engType','drive','body'],return_df=True)
bin_data= bin.fit_transform(cat_data)
bin_data.head()

BONUS!! Değişkeni Replace metodunu kullanarak yeniden kodlayabilirsiniz 🙂

cat_data = new_data[['car','body','engType','model','drive']]
cat_data['body'].unique()
cat_data['body']= cat_data.body.replace(['crossover', 'sedan', 'other', 'van', 'vagon', 'hatch'],[0,1,2,3,4,5])
cat_data.head()

Kaynak : https://www.analyticsvidhya.com/blog/

Değişken dönüşümlerinden bahsettiğim yazım burada sona eriyor umarım sizler için faydalı ve açıklayıcı olmuştur.

Veri Ön İşleme Adımlarını İçeren Repoya Ulaşmak İçin : https://github.com/kserdem/Veri-On-Isleme-Adimlari

Bir Sonraki Yazıda Görüşmek Dileğiyle 🙂

Keyifli Çalışmalar

Leave a Reply

Your email address will not be published. Required fields are marked *