Veri ön işleme adım 3 : Transformation
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.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
std_scaler[['mileage','engV']] = scaler.fit_transform(std_scaler[['mileage','engV']])
std_scaler


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.
#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.
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.
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.

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()


quantile_uniform=new_data.copy()
quantile_uni = QuantileTransformer()
quantile_uniform[['mileage','engV']] = quantile_uni.fit_transform(quantile_uniform[['mileage','engV']])
quantile_uniform.head()


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