In [1]:
import pandas as pd
import numpy as np
from sklearn.cross_validation import StratifiedKFold
from sklearn.grid_search import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import Lasso
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import matplotlib.pyplot as plt
from sklearn.metrics import roc_auc_score
%matplotlib inline
Il est important de pouvoir estimer l'utilité d'un attribut ou d'un sous ensemble d'attributs. Pour cela, deux approches sont possibles :
Les attributs peuvent être redondants (corrélation) ou non pertinents (bruit).
Il existe deux cas importants où la sélection d'attributs est souhaitée:
Si le temps d'exécution est important => faire une sélection au préalable.
La sélection d'attributs permet de:
Wrapper methods (approche symbiose) : utilise un modèle prédictif pour mesure la performance des sous ensembles d'attributs. L'algorithme d'apprentissage est utilisé comme une boite noire qui reçoit un sous ensemble d'attributs et retourne un score de validation en utilisant la validation croisée. Cette technique est très couteuse puisqu'il faut tester tous les sous-ensembles possibles (avec n attributs, on a 2^n sous-ensemble possible), mais elle permet d'obtenir le meilleur sous-ensemble possible pour le modèle choisi (avec un risque de sur-apprentissage). Tester 2^n possibilités est impossible en pratique. Pour contourner ce problème : 3 techniques peuvent être utilisées : random selection, forward selection et backward elimination.
Embedded methods (approche intégrée) : se base uniquement sur l'algorithme d'apprentissage utilisé. Certains algorithmes sont capables au moment de l'apprentissage d'associer des poids aux attributs. L'algorithme fait son apprentissage sur tous les attributs et la sélection se fait sur base des poids obtenus après apprentissage. Par exemple, la technique de régularization LASSO associe un poids de zéro aux attributs non pertinents.
In [3]:
df = pd.read_csv('./ticdata2000.csv')
Y = df.label
X = df.drop(['label'], axis=1)
print (X.shape)
X.head()
dfValid = pd.read_csv('./ticdata2000_Validation.csv')
YValid = dfValid.label
XValid = dfValid.drop(['label'], axis=1)
print (XValid.shape)
In [4]:
#CHOIX DU MODELE A UTILISER
#Pour des raisons de simplicité et de rapidité d'exécution, j'ai choisi les arbres de décision
#Dans un vrai projet, il faudra tester différents modèles et voir quelle combinaison d'attributs/modèle donne
#les meilleurs performances
clf = DecisionTreeClassifier(random_state=1)
params = {'max_depth':[3,5,7,9],
'min_samples_leaf' : [1,2,5]} #pour le gridSearch
metric = 'roc_auc'
#nombre d'attributs à utiliser
n_features=20
In [5]:
#fonction d'apprentissage avec cross validation et gridsearch sur le premier dataset
def performance(X,Y):
kf = StratifiedKFold(Y, n_folds=3, random_state=1)
gs = GridSearchCV(clf, params, scoring=metric, cv=kf)
gs.fit(X,Y)
return gs
#fonction de prédiction sur le dataset de validation
def validation(clf1, Xv, Yv):
preds = clf1.predict_proba(Xv)[:,1]
return roc_auc_score(Yv, preds)
gs = performance(X,Y)
print (gs.best_score_, gs.best_params_)
print (validation(gs.best_estimator_, XValid, YValid))
In [136]:
#Approche filtre
def variance_selection(X,n_features):
variance = [np.var(X[i]) for i in X.columns]
variance = sorted( zip(variance,X.columns) ,reverse=True)[:n_features]
return [x[1] for x in variance]
for n_features in [5,10,15,20, 25, 30]:
print n_features
varFeatures = variance_selection(X,n_features)
print 'Selected features : ', varFeatures
gs = performance(X[varFeatures], Y)
print gs.best_score_, gs.best_params_
#print validation(gs.best_estimator_, XValid[varFeatures], YValid)
print '***************************'
In [7]:
#Approche filtre
def variance_selection(X,n_features):
variance = [np.var(X[i]) for i in X.columns]
variance = sorted( zip(variance,X.columns) ,reverse=True)[:n_features]
return [x[1] for x in variance]
for n_features in [5,10,15,20, 25, 30]:
print (n_features)
varFeatures = variance_selection(X,n_features)
print ('Selected features : ', varFeatures)
gs = performance(X[varFeatures], Y)
print (gs.best_score_, gs.best_params_)
#print validation(gs.best_estimator_, XValid[varFeatures], YValid)
print ('***************************')
In [ ]:
In [10]:
#par filtre
def pearson_selection(X,y,n_features):
corr = np.abs( X.corrwith(Y))
corr = corr.sort_values(ascending=False)[:n_features]
return corr.index.values
for n_features in [10]:
print (n_features)
pearsonFeatures = pearson_selection(X,Y,n_features)
print ('Selected features : ', pearsonFeatures)
gs = performance(X[pearsonFeatures], Y)
print (gs.best_score_, gs.best_params_)
print ('************************')
print("best estamator : " , gs.best_estimator_)
print (validation(gs.best_estimator_, XValid[pearsonFeatures], YValid))
In [ ]:
In [147]:
#Approche integree
def random_forest_selection(X,Y,n_features):
params = {'max_depth':[3,5,7,9],
'min_samples_leaf' : [1,2,5]}
clf = RandomForestClassifier(random_state=1, n_jobs=2)
gs = GridSearchCV(clf, params)
gs.fit(X,Y)
bestClf = gs.best_estimator_
rf = bestClf.feature_importances_
rf=zip(rf,X.columns)
rf=sorted(rf,reverse=True)[:n_features]
return [x[1] for x in rf]
rfFeatures = random_forest_selection(X,Y,n_features)
print 'Selected features : ', rfFeatures
gs = performance(X[rfFeatures], Y)
print gs.best_score_, gs.best_params_
print validation(gs.best_estimator_, XValid[rfFeatures], YValid)
In [ ]:
In [87]:
def lasso_selection(X,Y,n_features):
cols = X.columns
X=StandardScaler().fit_transform(X)
params = {'alpha':[0.0001, 0.001, 0.01, 0.1, 1, 2, 5]}
clf = Lasso(random_state=1)
gs = GridSearchCV(clf, params)
gs.fit(X,Y)
ls = gs.best_estimator_.coef_
ls=zip(ls,cols)
ls=sorted(ls,reverse=True)[:n_features]
return [x[1] for x in ls]
lassoFeatures = lasso_selection(X,Y,n_features)
print 'Selected features : ', lassoFeatures
gs = performance(X[lassoFeatures], Y)
print gs.best_score_, gs.best_params_
print validation(gs.best_estimator_, XValid[lassoFeatures], YValid)
In [ ]:
In [150]:
#Wrapper
def forward_selection(X,Y,n_features):
fsFeatures = []
startFeatures = list(X.columns.values)
listOfScores=[]; listValidationScores=[]
while( len(startFeatures) > 0 ) : # len(fsFeatures)<n_features
bestScore = 0; bestFeature = None; bestClf=None
for feature in startFeatures:
sousEnsemble = fsFeatures+[feature]
gs = performance(X[sousEnsemble],Y)
if gs.best_score_>bestScore:
bestScore = gs.best_score_
bestFeature = feature
bestClf = gs.best_estimator_
fsFeatures.append(bestFeature)
listOfScores.append(bestScore)
listValidationScores.append( validation(bestClf, XValid[fsFeatures], YValid) )
startFeatures = list( set(startFeatures) - set(fsFeatures) )
return fsFeatures,listOfScores, listValidationScores
In [152]:
a,b,c = forward_selection(X[pearsonFeatures],Y,n_features)
In [155]:
plt.figure(figsize=(20,10))
plt.plot(b,'b')
plt.plot(c,'r')
_=plt.xticks(range(len(a)), a)
In [153]:
Out[153]:
In [ ]: