Veri Hazırlığının Vazgeçilmezi : Özellik Ölçeklendirme
Merhaba VBO okuyucuları!
Bu yazımda sizlere veri hazırlığında çok önemli yeri olan ve Feature Scaling olarak da bilinen ‘Özellik Ölçeklendirme’ kavramından ve yöntemlerinden bahsedeceğim. Verileri modele vermeden önce dikkat edilmesi gereken önemli noktalardan bazıları şunlardır:
- Verinin dağılımı: Verinin normal dağılıp dağılmaması, bazı algoritmaların çalışmasını etkileyen bir faktör. Veriler sağa yatık, ya da sola yatıksa, model performansı bu durumdan etkilenebilir.
- Özellikler arasındaki ölçek farklılıkları: Klasik bir örnekten gidecek olursak, verimiz yaş ve gelir boyutlarını içeriyor olsun. Yaş aralığı 0-90 yaşlarını kapsıyor ve gelir boyutu da 0- 250.000 TL arasında değerler içeriyor olsun. Burada Öklid, Manhattan gibi uzaklık bazlı hesaplamaları kullanan algoritmalar için değerler sapacaktır. Bu bağlamda bu özellliklerin ortak bir veri aralığına çekilmesi ile daha doğru sonuçlar elde edebiliriz.
Bu değerleri normal hale getirmek ve baskınlığı azaltmak adına bazı yöntemler mevcuttur. Bunlar, normalizasyon, standardizasyon gibi metodlardır. Bu metodlar uzaklık tabanlı ve gradyan tabanlı tahminleyici algoritmaları kullanmadan önce uygulanması faydalı olan yöntemlerdir. Peki bu metodlar nedir ve hangi durumlarda kullanılır?
- MinMax Scaling, verinin 0 ile 1 arasında değerler aldığı bir durumdur. Burada dağılım, verinin dağılımı ile benzerdir. Burada ‘outlier’ denilen dışta kalan verilere karşı hassasiyet durumu vardır, bu yüzden bu değerlerin fazla olduğu bir durumda iyi bir performans gösteremeyebilir.
Formülü aşağıdaki gibidir. Açıklayacak olursak: Değerimizden o veri aralığındaki minimum değeri çıkartıyoruz, aralık değerine bölüyoruz.
X-Xmin / Xmax-Xmin
from sklearn import preprocessing min_max_scaler = MinMaxScaler() scaled_df = min_max_scaler.fit_transform(df) df_sc = pd.DataFrame(scaled_df)
- Robust Scaler, Normalizasyon ile benzer şekilde çalışır. Aykırı değerlere sahip verilerde daha iyi sonuçlar verebilir. Yine veri dağılımı ile benzerlik gösterir ancak aykırı değerler dışarıda kalır. Medyan değeri sonradan kullanılmak üzere elenir ve değerler 1.ve 3. kartil aralığına oturtulur.
X-Q1(X) / Q3(X)-Q1(X)
from sklearn import preprocessing robust_scaler = RobustScaler() scaled_df = max_scaler.fit_transform(df) df_sc = pd.DataFrame(scaled_df)
- MaxAbs Scaler, her özelliğin maksimum mutlak değeri 1 olacak şekilde her özelliği ayrı ayrı ölçeklendirir ve dönüştürülür.
X / max(abs(X))
from sklearn import preprocessing max_scaler = MaxAbsScaler() scaled_df = max_scaler.fit_transform(df) df_sc = pd.DataFrame(scaled_df)
- Standardizasyon, ortalama değerin 0, standart sapmanın ise 1 değerini aldığı, dağılımın normale yaklaştığı bir metoddur. Formülü şu şekildedir, elimizdeki değerden ortalama değeri çıkartıyoruz, sonrasında varyans değerine bölüyoruz.
(X - u) / s
from sklearn import preprocessing scaler = preprocessing.StandardScaler() scaled_df = scaler.fit_transform(df) df_sc = pd.DataFrame(scaled_df)
- PowerTransformer, varyansı stabilize etmek ve çarpıklığı en aza indirmek için en uygun ölçeklendirme faktörünü bulur. Yine ortalama değerin 0, standart sapmanın ise 1 değerini aldığı bir metoddur.
from sklearn import preprocessing transform_power = preprocessing.PowerTransformer() scaled_df = transform_power.fit_transform(df) df_sc = pd.DataFrame(scaled_df)
Bir önceki yazımda RFM analizinden bahsetmiştim, bu link üzerinden ulaşabilirsiniz. Şimdi çıkan RFM tablosundaki verileri normalize/standardize edelim.
Bu yöntemler ile uzaklık tabanlı algoritmalarda daha farklı sonuçlar alınabilir. Kullanılması faydalı olacaktır.
clus = rfm_table[['Monetary','Recency','Frequency']] from sklearn.preprocessing import StandardScaler scaler = StandardScaler() d_scaled = scaler.fit_transform(clus) data_scaled1 = pd.DataFrame(d_scaled) data_scaled1.head()
0 | 1 | 2 | |
---|---|---|---|
0 | 1.191780 | -0.959542 | 0.285250 |
1 | 1.317505 | -0.959542 | 2.360848 |
2 | 1.068039 | -0.959542 | 2.822092 |
3 | 0.452246 | -0.959542 | 2.437722 |
4 | 0.736600 | -0.959542 | 2.437722 |
Burada verileri incelediğimizde negatif ve pozitif değerler aldıklarını görüyoruz. Dağılım benzerlik gösteriyor.
data_scaled1.describe()
0 | 1 | 2 | |
count | 5.88E+03 | 5.88E+03 | 5.88E+03 |
mean | 2.54E-16 | -3.03E-15 | -8.97E-15 |
std | 1.00E+00 | 1.00E+00 | 1.00E+00 |
min | -2.05E-01 | -9.60E-01 | -4.07E-01 |
25% | -1.81E-01 | -8.40E-01 | -4.07E-01 |
50% | -1.44E-01 | -5.06E-01 | -2.53E-01 |
75% | -4.83E-02 | 8.51E-01 | 5.46E-02 |
max | 4.11E+01 | 2.57E+00 | 3.01E+01 |
from sklearn.preprocessing import MinMaxScaler min_max_scaler = MinMaxScaler() x_scaled = min_max_scaler.fit_transform(clus) data_scaled2 = pd.DataFrame(x_scaled) data_scaled2.head()
0 | 1 | 2 | |
0 | 0.0338 | 0 | 0.02267 |
1 | 0.036844 | 0 | 0.09068 |
2 | 0.030805 | 0 | 0.105793 |
3 | 0.0159 | 0 | 0.093199 |
4 | 0.022783 | 0 | 0.093199 |
Burada verileri incelediğimizde 0 ve 1 arasında değerler aldığını görüyoruz. Dağılımın bu iki değer arasında dağıldığını görüyoruz.
data_scaled2.describe()
0 | 1 | 2 | |
count | 5878 | 5878 | 5878 |
mean | 0.004953 | 0.272177 | 0.013323 |
std | 0.024207 | 0.283677 | 0.032769 |
min | 0 | 0 | 0 |
25% | 0.000568 | 0.033875 | 0 |
50% | 0.001472 | 0.128726 | 0.005038 |
75% | 0.003785 | 0.51355 | 0.015113 |
max | 1 | 1 | 1 |
Burada özellik ölçeklendirme metodlarından ikisini de örneklendirmiş olduk. Bu yöntemler gerçekten hayat kurtarıcı olabiliyor. Uzaklık temelli algoritmaları kullanırken öncesinde verileri bu işlemlere tabi tutarak maliyeti azaltıp, modelin performansını iyileştirebilirsiniz.
Yorumlarınız için şimdiden teşekkürler!
Kaynakça:
https://medium.com/analytics-vidhya/feature-scaling-in-scikit-learn-b11209d949e7
https://scikit-learn.org/stable/auto_examples/preprocessing/plot_all_scaling.html
Hocam merhaba, öncelikle yazınız için çok teşekkür ederim. Benim bir sorum olacak elimde bir veri seti var belirli özellikleri olan arabaların satış fiyatlarını içeren bir veri bu veri setini eğitip model haline getirdim. Girdi olarak 5 özellik girip fiyat tahmini yapmasını sağladım tensorflow ile istediğim gibi oldu ama bu modeli .tflite’a çevirip android studio’da kullandığım zaman aynı sonucu alamadım. Daha sonra farkettimki tensorflow’da tahmin edilmek üzere girilen özellik verileri ya da girdileri önce scaler transforma sokup tahmin ettiriyorum. Öyle yapmadığım zaman aynı android studio’daki gibi sonuç alıyorum. Acaba bu scale etme özelliğini android studio’da nasıl kullanabilirim fikriniz var mı