Özellik Oluşumu ve Özellik Seçimi(Feature Selection)-3
Özellik seçimi ile ilgili yazı serisinin 3. yazısını okumaktasınız, eğer ilk yazıyı ve ikinci yazıyı okumadıysanız öncesinde onları okumanız konu bütünlüğünü anlamak adına faydanıza olacaktır.
4.4 Özyinelemeli olarak özellik seçme ( Recursive Feature Elimination)
4.5 Başka bir modelin sonuçlarını kullanarak özellik seçme ( Select From Model)
4.6 Boyut İndirgeme (Dimensionality Reduction)
i) Temel Bileşenler Analizi (Principal Component Analysis (PCA))
ii) Lineer Diskriminant Analizi (Linear Discriminant Analysis (LDA))
iii) Genelleştirilmiş Diskriminant Analizi (Generalized Discriminant Analysis (GDA))
4.4 Özyinelemeli olarak özellik seçme ( Recursive Feature Elimination)
2. yazıda bahsettiğimiz sarmal yöntemlerdeki geri yönde seçim yöntemini kullanan özyinelemeli özellik seçme yöntemi, en az önemli olan değişkenleri eleyerek en doğru sonuca gitmeye çalışır. Bu eleme işlemini makine öğrenmesi algoritmasına uyarak ve onun sonucunu değerlendirerek uygular.
Bu yöntemde ki işleyiş, verilen model sonucuna göre tahmin edicilerin önemlilik katsayılarını almak ve onları sıralamaktır. Bu sayede en iyi x özelliği seçebiliriz. Aşağıda ki örnekte özyinelemeli yöntemi hem destek vektör ve hem de karar ağacı algoritmasını kullanarak özellik seçmesi için kullandım.
Örnek:
#ihtiyacımız olan kütüphaneler ve verisetifrom sklearn import datasets
import pandas as pd
from pandas import Series
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import LinearSVC
from sklearn.feature_selection import RFE
#iris data setini alıyoruz iris = datasets.load_iris()
x=pd.DataFrame(iris.data, columns=['var1','var2','var3', 'var4'])
y=(pd.Series(iris.target, name='target')==2).astype(int)
#Destek Vektör Sınıflandırma algoritmasını seçerek, özyinelemeli yöntemi kullanıyoruz.estimator = LinearSVC()
selector = RFE(estimator, n_features_to_select=2, step=1)
selector = selector.fit(x, y)
# Karar Ağacı Sınıflandırma algoritmasını seçerek, özyinelemeli yöntemi kullanıyoruzestimator2=DecisionTreeClassifier()
selector2 = RFE(estimator2, n_features_to_select=2, step=1)
selector2 = selector.fit(x, y)
#Çıkan sonuçlara bakalım, hangi model hangi değişkenleri seçmiş
selector.support_
selector.ranking_
selector2.support_
selector2.ranking_
RFECV olarakta bir versiyonu vardır uygulamanın, bizim n_features_to_select olarak verdiğimiz parametrik değer yerine en uygun durma noktasını bulmak için çapraz doğrulama yöntemini kullanılır. Aynı kullanıma sahiptir. O kütüphaneyi getirmek gerekir. Sabit özellik seçmek yerine bunu kullanmak daha doğru olacaktır.
from sklearn.feature_selection import RFECV
selector=RFECV(estimator,step=1,cv=5)
4.5 Başka bir modelin sonuçlarını kullanarak özellik seçme ( Select From Model)
Bu yöntemde aslında yukarıda yaptığımız RFE içinde uygulayabildiğimiz model seçimi yapabilmemizin özyinelemeli olmadan ki hali diye yorumlayabiliriz.
Verini uygulamak istediğin model ile eğit, o model sonucundaki önemlilk katsayısına göre de top x tanesini seçebilirsin.
Örnek:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_diabetes
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LassoCV
from sklearn.linear_model import RidgeCV
#diabetes datasını yükleyelim
diabetes = load_diabetes()
X = diabetes.data
y = diabetes.target
feature_names = diabetes.feature_names
print(feature_names)
#lasso ve ridge regresyon modellerini deneyelim ve önemlilik katsayılarını çıkartalım
clf = LassoCV().fit(X, y)
importance = np.abs(clf.coef_)
print(importance)
clf2= RidgeCV().fit(X,y)
importance2= np.abs(clf2.coef_)
print(importance2)
#önemlilik katsayısı için kısıt belirleme,en önemli 3.özellik katsayısına 0.01 ekleyerek bundan yüksek olanları seçtirdik ve bu sayede en önemli 2 özelliği seçmiş olduk
idx_third = importance.argsort()[-3]
threshold = importance[idx_third] + 0.01
idx_features = (-importance).argsort()[:2]
name_features = np.array(feature_names)[idx_features]
print('Selected features: {}'.format(name_features))
#lasso algoritmasını kullanarak ve verilen önemlilik katsayısı kısıtına göre değişkenleri seçtik, transform ile de x üzerinde bunu uyguladık. Aynı clf2 diye tanımladığımız ridge algoritması içinde yapılabilir.
sfm = SelectFromModel(clf, threshold=threshold)
sfm.fit(X, y)
X_transform = sfm.transform(X)
n_features = sfm.transform(X).shape[1]
Kurduğunuz bir modelin test sonuçlarının değerlendirme metriklerine bakmadan önce mutlaka özelliklerin önem seviyelerini kontrol etmenizi tavsiye ederim. Bu sayede modeli daha iyi anlama fırsatı yakalar ve mantıksal bir hata var ise bu sebepten model performansı çok iyi veya çok kötü çıkmış ise bunu anlama fırsatı bulursunuz.
4.6 Boyut İndirgeme (Dimensionality Reduction)
Boyut indirgeme özellik seçme konusunda daha önceden yazdığımız uygulamalardan farklıdır. Oradaki yöntemlerde mutlaka bir özelliği çıkartarak ve geriye kalan diğer özellikleri kullanarak ilerledik. Boyut indirgeme yöntemlerinde özelliklerin içinden bir tanesi seçip elemek değil, o özelliklerden bir karma özellik oluşturarak, bir nevi sıkıştırarak özellik sayısın azaltmış oluruz.
i) Temel Bileşenler Analizi (Principal Component Analysis (PCA))
PCA orijnal veriyi daha az boyut indirgeyerek daha az boyutlu veride işlem yapmamızı sağlar. Aynı zamanda çoklu doğrusallık problemini çözer. 100 değişken kullanacağımız yerde bu 100 değişkenin karmasından oluşan ve bu 100 değişkenin açıklayıcılığını taşıyan 10 değişken ile yolumuza devam etmemizi sağlar.
PCA konusunda çok daha detaylı bilgiler için Veri Bilimi Okulun’da daha önceden bu konuda yazmış olan arkadaşım Emre Rıdvan Muratlar’ın yazısını okumanızı tavsiye ederim.
ii) Lineer Diskriminant Analizi (Linear Discriminant Analysis (LDA)
LDA’da PCA gibi bir doğrusal dönüşüm tekniğidir. LDA ‘da hedef değişkene göre boyut azaltma yapılırken, PCA ‘da ise hedef değişkensiz bu boyut azaltmayı yapar. Yani LDA denetimli öğrenme uygularken, PCA ise denetimsiz öğrenme uygular.
PCA, mevcut değişkenlerden birbiri ile korelasyonu yüksek olanlar var ise o değişkenleri ikisini birden kullanmaya gerek yoktur. PCA bu birbirine benzeyen değişkenleri sadeleştirir. Bu işlemi yaparkende girdi değişkenlerin hedef değişken ile olan ilişkilerine bakmadan bunu yapar. Amacı maksimum varyansı olan özellikle kümelerini ortaya çıkarmaktır.
LDA ise yine bu adımları uygular fakat hedef değişkene göre yani sınıflar arasındaki ayrımı en üst düzeye çıkaran boyutları bulmaya çalışır. İkisi de aşırı öğrenmeyi engellemek, çoklu doğrusallık problemini çözmek ve hesaplama maliyetini azaltmak için kullanılır.
Scikitlearn sitesinde PCA ve LDA yöntemlerini iris veri setine uygulayarak, karşılaştırma yapan scripti aşağıda bulabilirsiniz. Yöntemlerin tam olarak nasıl işe yaradığı ile ilgili basit ama anlaşılması kolay bir örnektir. Aynı zamanda görselleştirerek daha net anlaşılması sağlanmıştır.
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names
pca = PCA(n_components=2)
X_r = pca.fit(X).transform(X)
lda = LinearDiscriminantAnalysis(n_components=2)
X_r2 = lda.fit(X, y).transform(X)
# Her bileşen için açıklanan varyans yüzdesi-PCAprint('explained variance ratio PCA(first two components): %s'
% str(pca.explained_variance_ratio_))
# Her bileşen için açıklanan varyans yüzdesi-LDAprint('explained variance ratio LDA(first two components): %s'
% str(lda.explained_variance_ratio_))
Yukarıda 4 değişkenli iris veri setini LDA ve PCA kullanarak 2 değişkene indirgedik fakat daha önceki yöntemlerde de uyguladığımız gibi bizim buradaki amacımız değişken sayısını azaltmak ama bunu kesin rakam vermek yerine mümkünse en optimum özellik sayısını seçmesini otomatik olarak sağlamalıyız.
PCA ve LDA da değişken indirgerken oluşan yeni boyutların açıklayacılık seviyelerini kendimize bir kısıt olarak koyabiliriz. En az bu seviyede bir açıklayıcılık olacak şekilde bu yapılan boyut azaltma yöntemini kullan diye bir fonksiyon tanımlayalım.
# Açıklanan varyans yüzdelerini tanımlayalım
lda_var_ratios = lda.explained_variance_ratio_
pca_var_ratios= pca.explained_variance_ratio_
#Fonksiyonu tanımla def select_n_components(var_ratio, goal_var: float) -> int: # Totalde ulaşmak istediğim varyans değeri, 0 dan başla total_variance = 0.0 # İlk olarak x boyuttan başla n_components = 0 # Her bir bileşen için açıklanan varyans değeri: for explained_variance in var_ratio: # Her bir bileşen için hesapladığını totale ekle total_variance += explained_variance # Bileşen sayısını arttır n_components += 1 # Hesaplanan toplam açıklayıcılık varyansı bizim kısıt olarak verdiğimizde değer ile kıyasla if total_variance >= goal_var: # Büyük ise loop durdur break # bileşen sayısını göster return n_components
# pca ve lda yöntemlerini kullanacağım , varyans açıklayıcılığım 0.93 üstü olmasını yeterlidir diyorum.select_n_components(pca_var_ratios, 0.93)
select_n_components(lda_var_ratios, 0.93)
Bunun sonucu PCA için 2 boyut çıkar iken LDA 1 boyutta istenilen açıklayıcılığı sağlayabiliyor.
plt.figure()
colors = ['navy', 'turquoise', 'darkorange']
lw = 2
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
plt.scatter(X_r[y == i, 0], X_r[y == i, 1], color=color, alpha=.8, lw=lw,
label=target_name)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('PCA of IRIS dataset')
plt.figure()
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
plt.scatter(X_r2[y == i, 0], X_r2[y == i, 1], alpha=.8, color=color,
label=target_name)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('LDA of IRIS dataset')
plt.show()
iii) Genelleştirilmiş Diskriminant Analizi (Generalized Discriminant Analysis (GDA))
Genelleştirilmiş Ayırım Analizi (GDA) yaklaşımı, doğrusal olmayan bir yöntemdir. LDA’nın genelleştirmiş hali diye geçer. LDA’nın çekirdek yaklaşımları kullanarak evrilmiş bir biçimidir. Altta yatan teori, destek vektör makinelerinin (SVM) teorisine yakındır. GDA diğer yöntemlere göre daha ileri bir okuma ve araştırma gerektirir.
SONUÇ
Yazı serisinin ilk bölümünde uzunca bir giriş yaptığım için sonuç kısmında tekrardan uzun uzun yazmayacağım. Gördüğünüz gibi doğru değişkenler ile modele gitmek için bir sürü yol var. İhtiyaca ve elinizdeki veriye göre uygun yöntemler ile ilerlemek gerekir.
Bu kadar yöntemi mutlaka uygulamak gerekiyor mu? sorusunun cevabı da eğer model tuningte istenilen başarılı sonuç gelmiyor ise artık geriye dönüp, özellikler üzerinde ne gibi hareketler yapabilirsiniz düşüneceksiniz. Eğer ki uygun bir zaman ve kaynak var ise modele gitmeden önce ince eleyip sık dokumak yani yeni özellikler yaratmak veya mevcut özellikleri azaltmak veya dönüştürmek daha doğru ve sağlam adımlarla ilerlemek iyi olacaktır. Öyle açıklayıcı ve temiz veri ile model kurmaya gidin ki artık arkanıza bakmadan model üzerinde yoğunlaşın.
Lezzetli değişkenlerle ile enfes bir model kurmanız dileğiyle. Beraber gelişim için sorularınız ve yorumlarınız olursa çok memnun olurum.
Kaynak :
- https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html#sklearn.feature_selection.RFE
- https://scikit-learn.org/stable/auto_examples/feature_selection/plot_select_from_model_diabetes.html#sphx-glr-auto-examples-feature-selection-plot-select-from-model-diabetes-py
- https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html
- https://scikit-learn.org/stable/auto_examples/decomposition/plot_pca_vs_lda.html
- https://chrisalbon.com/machine_learning/feature_engineering/select_best_number_of_components_in_lda/
- http://alumni.cs.ucr.edu/~hli/glda/index.html
- https://github.com/mhaghighat/gda/blob/master/gda.m
Görsel Kaynak:
Merhabalar
Öncelikle çok açıklayıcı bir yazı olmuş çok teşekkürler.
Aklıma takılan bir kaç soru vardı;
selector.support_
selector.ranking_ kodunun çıktısında gördüğümüz değerler tam olarak neyi ifade ediyor?
İkinci olarak ,
RFECV yi kodladığınız kısımda çıktı olarak
RFECV(cv=5,
estimator=LinearSVC(C=1.0, class_weight=None, dual=True,
fit_intercept=True, intercept_scaling=1,
loss=’squared_hinge’, max_iter=1000,
multi_class=’ovr’, penalty=’l2′, random_state=None,
tol=0.0001, verbose=0),
min_features_to_select=1, n_jobs=None, scoring=None, step=1, verbose=0)
böyle bir şey alıyorum bunu nasıl yorumlamamız gerekir?
Merhaba Salih,
support sonucunda array([False, True, False, True]) böyle bir şey çıkar. 2. ve 4. değişkenleri seçmiş olduğunu anlıyoruz buradan. Yukarıda scriptte n_features_to_select=2 dediğimiz için bu 2’nin hangi 2 olduğunu gösteriyor.
ranking sonucunda array([3, 1, 2, 1]) böyle bir şey çıkar. Yukarıdaki True’ları 1 yazıyor sonrasında model için önem derecesine göre diğer özellikleri sıralıyor.
İkinci sorun için ;
Sen anladığım kadarıyla print(selector) bu şekilde çağırıyorsun, bu şekilde çağırman o değişken üzerindeki tanımlı parametreleri gösteriyor.
Aslında sen yine model sonucu göstermek için attribute kullanmak gerekir. Attribute dediğimiz şeyler ise ; yine selector.support_, selector.ranking_ , bunlar üzerinden sonuçlar gelir.
Eğer ki eksik kalan bir yer olursa tekrar yaz lütfen.
Kolaylıklar