<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Inspiré par l'exellent livre de Sebastian Raschka (@rasbt) 
Step1:  Numérique 
Step2:  La feature "Alcohol" (%/vol) et "Malic acid" (g/l) n'ont pas les mêmes échelles. On compare donc des choux et des carottes...
Step3:  "alcool" et "acide malique" ont maintenant une moyenne de 0 et un std de 1
Step4:  La normalisation est crucial lors d'un PCA (Principal Component Analysis), observons la différence à l'aide d'un graphique 
Step5:  Le PCA permet de réduire le nombre dimension tout en gardant le maximum d'information. On extrait en quelques sorte le substrat de l'information. Plus d'info ici et via cette vidéo
Step6:  PCA non normalisé 
Step7:  PCA normalisé
Step8:  Dans la verion "PCA normalisé", on retrouve nos 3 clusters assez délimités alors que pour la version "PCA non normalisé", la délimitation est beaucoup chaotique.
Catégorie
Les features contenant du texte doivent etre transformées afin de nourir l'algorithme par la suite.
Step9:  Ensuite se pose la question pour "color" et "size" 
Step10:  Nominal features
Step11:  Bien comprendre les métrics
Pour le challenge Rossman, la metric est le Root Mean Square Percentage Error (RMSPE). Compréhension par l'exemple 
Step12:  Plus la valeur est faible, plus la prédiction est précise.
Pour le challenge Homesite, la metric est Area under the curve (AUC), elle permet d'étudier la performance d’un classifieur binaire. Elle va de 0 à 1 (1 étant un classicateur parfait)
Step14:  Pour aller plus loin graphiquement. N'hésitez pas à modifier les valeurs de "real_value" et des prédiction. Attention "real_value" doit avoir le même nombre de valeurs que les prédictions.
Step15:  Mesurer le performance de son modèle 
Step16:  La performance du modèle varie selon le split (random_state). On est beaucoup trop dépendant des éléments présents dans la phase d'apprentissage (train) et dans la validation (test).
On utilisant le principe de Cross Validation, on s'assure que chaque ligne à été en phase d'apprentissage (train) ainsi que dans la phase de validation (test) 
Step17:  Chaque élément apparait uniquement une fois dans la phase de test
Utilisation de Cross Validation
Step18:  On a donc 10 mesures de performances différentes.
Step19:  Changer les paramètres de l'algorythme 
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
import numpy as np
import seaborn as sns
#sns.set_style('whitegrid')
import matplotlib.pyplot as plt
%matplotlib inline
import warnings
warnings.simplefilter('ignore', DeprecationWarning)
Explanation: Inspiré par l'exellent livre de Sebastian Raschka (@rasbt) : Python Machine learning et Notebook ainsi que par les tuto de Scikit Learn sur Kaggle
End of explanation
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)
df.columns = ["label", "Alcohol", "Malic acid", "Ash", "Alcalinity of ash", "Magnesium", "Total phenols", "Flavanoids",
                "Nonflavanoid phenols", "Proanthocyanins", "Color intensity", "Hue", "OD280/OD315 of diluted wines",
                "Proline"]
df.head()
df[['Alcohol', 'Malic acid']].describe()
Explanation: Numérique :
Log transformation log(x) / log(1 + x)
Graphiques représentant le nombre de retraité et le nombre de vote FN par ville durant le second tour des elections régionales (lien github).
A gauche : pas de log
A droit : log
On observe une meilleure distribution des données si celle-ci sont transformées 
Normalisation
End of explanation
sns.lmplot(x="Alcohol", y="Malic acid", hue="label", data=df, fit_reg=False, markers=['^', 's', 'o'])
# On normalise les features
from sklearn.preprocessing import  StandardScaler
df_scale = df.copy()
for col in df_scale.columns[1:]:
    scaler = StandardScaler()
    df_scale[col] = scaler.fit_transform(df_scale[col])
df_scale[['Alcohol', 'Malic acid']].describe()
Explanation: La feature "Alcohol" (%/vol) et "Malic acid" (g/l) n'ont pas les mêmes échelles. On compare donc des choux et des carottes...
End of explanation
sns.lmplot(x="Alcohol", y="Malic acid", hue="label", data=df_scale, fit_reg=False, markers=['^', 's', 'o'])
Explanation: "alcool" et "acide malique" ont maintenant une moyenne de 0 et un std de 1
End of explanation
# Using PCA
from sklearn.decomposition import PCA
# X = features, y = label
X, y = df.iloc[:, 1:].values, df.iloc[:,0].values # No scale
X_scale, y = df_scale.iloc[:, 1:].values, df_scale.iloc[:,0].values #scale
# non scale
pca = PCA(n_components=2).fit(X)
data_pca = pca.transform(X)
pca_df = pd.DataFrame(data_pca, columns=['pca_1', 'pca_2'])
pca_df['label'] = df['label']
# scale
pca_scale = PCA(n_components=2).fit(X_scale)
data_pca_scale = pca_scale.transform(X_scale)
pca_scale_df = pd.DataFrame(data_pca_scale, columns=['pca_1', 'pca_2'])
pca_scale_df['label'] = df['label']
Explanation: La normalisation est crucial lors d'un PCA (Principal Component Analysis), observons la différence à l'aide d'un graphique :
End of explanation
pca_df.head()
Explanation: Le PCA permet de réduire le nombre dimension tout en gardant le maximum d'information. On extrait en quelques sorte le substrat de l'information. Plus d'info ici et via cette vidéo
End of explanation
g=sns.lmplot(x="pca_1", y="pca_2", hue="label", data=pca_df, fit_reg=False, markers=['^', 's', 'o'])
Explanation: PCA non normalisé :
End of explanation
sns.lmplot(x="pca_1", y="pca_2", hue="label", data=pca_scale_df, fit_reg=False, markers=['^', 's', 'o'])
Explanation: PCA normalisé
End of explanation
import pandas as pd
df = pd.DataFrame([
            ['green', 'M', 10.1, 'class1'], 
            ['red', 'L', 13.5, 'class2'], 
            ['blue', 'XL', 15.3, 'class1']])
df.columns = ['color', 'size', 'prize', 'class label']
df
from sklearn.preprocessing import LabelEncoder
LE = LabelEncoder()
df['class label'] = LE.fit_transform(df['class label'])
df
Explanation: Dans la verion "PCA normalisé", on retrouve nos 3 clusters assez délimités alors que pour la version "PCA non normalisé", la délimitation est beaucoup chaotique.
Catégorie
Les features contenant du texte doivent etre transformées afin de nourir l'algorithme par la suite.
End of explanation
size_mapping = {
           'XL': 3,
           'L': 2,
           'M': 1}
df['size'] = df['size'].map(size_mapping)
df
Explanation: Ensuite se pose la question pour "color" et "size" :
    - "size": Il y a un ordre de grandeur. Il faut donc respecter cette ordre de grandeur avec notre transformation.
    - "color": Suivant le type d'algorythme utilisé, on peux la transformé comme "class label" ou bien la "binariser", c'est à dire que chaque valeur possible sera une colonne (avec des 0 ou 1)
Ordinal features
End of explanation
pd.get_dummies(df)
Explanation: Nominal features
End of explanation
# To compute RMSPE
def ToWeight(y):
    w = np.zeros(y.shape, dtype=float)
    ind = y != 0
    w[ind] = 1./(y[ind]**2)
    return w
def RMSPE(y, yhat):
    w = ToWeight(y)
    rmspe = np.sqrt(np.mean( w * (y - yhat)**2 ))
    return rmspe
real_value = np.array([3500, 6400, 5000])   # Les valeurs que je cherche à prédire
prediction_1 = np.array([3000, 5900, 5500]) # assez bonne
prediction_2 = np.array([2510, 4000, 8000]) # pas terrible
prediction_3 = np.array([3400, 6490, 5070]) # exellente
print "1 - Prédiction assez bonne : %s" %(RMSPE(prediction_1, real_value))
print "2 - Mauvaise prédiction : %s" %(RMSPE(prediction_2, real_value))
print "3 - Bonne prédiction : %s" %(RMSPE(prediction_3, real_value))
Explanation: Bien comprendre les métrics
Pour le challenge Rossman, la metric est le Root Mean Square Percentage Error (RMSPE). Compréhension par l'exemple :
End of explanation
from sklearn.metrics import roc_auc_score, roc_curve, auc
real_value = np.array([0, 0, 1, 1])   # Les valeurs que je cherche à prédire
prediction_1 = np.array([0.1, 0.4, 0.3, 0.8]) # assez bonne
prediction_2 = np.array([0.55, 0.4, 0.48, 0.35]) # pas terrible
prediction_3 = np.array([0.1, 0.2, 0.8, 0.9]) # exellente
print "1 - Prédiction assez bonne : %s" %(roc_auc_score(real_value, prediction_1))
print "2 - Mauvaise prédiction : %s" %(roc_auc_score(real_value, prediction_2))
print "3 - Bonne prédiction : %s" %(roc_auc_score(real_value, prediction_3))
Explanation: Plus la valeur est faible, plus la prédiction est précise.
Pour le challenge Homesite, la metric est Area under the curve (AUC), elle permet d'étudier la performance d’un classifieur binaire. Elle va de 0 à 1 (1 étant un classicateur parfait)
End of explanation
def plot_roc(true_positive_rate, false_positive_rate, roc_auc, title=''):
    
    To plot ROC curve
    
    title = 'Receiver Operating Characteristic' + title
    plt.title(title)
    plt.plot(false_positive_rate, true_positive_rate, 'b',
    label='AUC = %0.2f'% roc_auc)
    plt.legend(loc='lower right')
    plt.plot([0,1],[0,1],'r--')
    plt.xlim([-0.1,1.2])
    plt.ylim([-0.1,1.2])
    plt.ylabel('True Positive Rate')
    plt.xlabel('False Positive Rate')
    plt.show()
# List of all my predicitons
my_list_pred = [prediction_1, prediction_2, prediction_3]
my_predictions = []
for pred in my_list_pred:
    my_predictions.append(pred)
# Plot ROC 
i = 1
for prediction in my_predictions:
    false_positive_rate, true_positive_rate, thresholds = roc_curve(real_value, prediction)
    roc_auc = auc(false_positive_rate, true_positive_rate)
    plot_roc(true_positive_rate, false_positive_rate, roc_auc, title='_'+str(i))
    i += 1
Explanation: Pour aller plus loin graphiquement. N'hésitez pas à modifier les valeurs de "real_value" et des prédiction. Attention "real_value" doit avoir le même nombre de valeurs que les prédictions.
End of explanation
from sklearn.datasets import load_iris
# Get data
iris = load_iris()
# create X (features) and y (target)
X = iris.data
y = iris.target
print "Il y %d de lignes pour X" %(len(X))
print "Il y %d de lignes pour y" %(len(y))
X[0:5]
from sklearn.cross_validation import train_test_split
# Split le dataset en train (apprentissage) et test (phase de validation)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,
                                                    random_state=4)   # Hésitez pas à changer le random split
print "Il y %d de lignes pour X_train" %(len(X_train))
print "Il y %d de lignes pour y_train" %(len(y_train))
print "Il y %d de lignes pour X_test" %(len(X_test))
print "Il y %d de lignes pour y_test" %(len(y_test))
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)              # On entraine le modèle (sur train)
y_pred = knn.predict(X_test)           # On prédit le résultat sur un partie de données inconnu (test)
print accuracy_score(y_test, y_pred)   # On regarde précision du modèle de nos prédiction vers la réalité
Explanation: Mesurer le performance de son modèle :
End of explanation
from sklearn.cross_validation import KFold
kf = KFold(25, n_folds=5, shuffle=False)
# print the contents of each training and testing set
print '{} {:^61} {}'.format('Iteration', 'Training set observations', 'Testing set observations')
for iteration, data in enumerate(kf, start=1):
    print '{:^9} {} {:^25}'.format(iteration, data[0], data[1])
Explanation: La performance du modèle varie selon le split (random_state). On est beaucoup trop dépendant des éléments présents dans la phase d'apprentissage (train) et dans la validation (test).
On utilisant le principe de Cross Validation, on s'assure que chaque ligne à été en phase d'apprentissage (train) ainsi que dans la phase de validation (test) :
End of explanation
from sklearn.cross_validation import cross_val_score
knn = KNeighborsClassifier(n_neighbors=3)
scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy')
print scores
Explanation: Chaque élément apparait uniquement une fois dans la phase de test
Utilisation de Cross Validation
End of explanation
print "La performance moyenne est de : %s et un std de %s" %(np.mean(scores), np.std(scores))
Explanation: On a donc 10 mesures de performances différentes.
End of explanation
import matplotlib.pyplot as plt
from mlxtend.data import iris_data
from mlxtend.evaluate import plot_decision_regions
from sklearn.ensemble import RandomForestClassifier
# Get Data
X, y = iris_data()
X = X[:,[0, 2]]
# To plot graph
for criterion in ['gini', 'entropy']:                # Criterion 
    for n_estimators in [3, 15]:                     # You can change this value if you want to play
        RFC = RandomForestClassifier(criterion=criterion, n_estimators=n_estimators, random_state=12)
        RFC.fit(X,y)
        title = criterion + " + " + str(n_estimators)
        fig = plot_decision_regions(X=X, y=y, clf=RFC, legend=2)
        plt.title(title)
        plt.show()  
Explanation: Changer les paramètres de l'algorythme :
Dans la grande majorité des cas, un algoryhme possèdent plusieurs paramètres. Changer ces paramètres influent sur le résultat :
End of explanation
<END_TASK>