In [2]:
# charger les données dans un dataframe de Pandas
import pandas as pd
col_names = ['pregnant', 'glucose', 'bp', 'skin', 'insulin', 'bmi', 'pedigree', 'age', 'label']
pima = pd.read_csv('./pima-indians-diabetes.data.txt', header=None, names=col_names)
In [3]:
# afficher les 5 premières lignes
pima.head()
Out[3]:
In [4]:
# On définit X et y, on va supposer que nous n'avons que 4 attributs : 'pregnant', 'insulin', 'bmi', 'age'
feature_cols = ['pregnant', 'insulin', 'bmi', 'age']
X = pima[feature_cols]
y = pima.label
In [5]:
# diviser X et y en training and testing
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,
random_state=0)
In [6]:
# on va apprendre un modèle de régression logistique
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(X_train, y_train)
Out[6]:
In [7]:
# On prédit pour les données de test
y_pred_class = logreg.predict(X_test)
Classification accuracy: pourcentage de prédictions correctes, c'est le nombre d'instances correctement prédite sur le nombre d'instances total
In [9]:
# accuracy
from sklearn import metrics
print (metrics.accuracy_score(y_test, y_pred_class))
Le taux de prédiction est 0.6927, ce qui à première vue peut sembler satisfaisant Mais est-ce le cas? Nous devons comparer la performance de notre score avec un score de base.
Null accuracy: est le taux de prédiction qui peut être atteint en prédisant toujours la classe dominante. Nous allons comparer les perfformances de notre modèle avec celles de Null
In [10]:
# on examine la distribution des classes des données de test, la classe dominante est la classe 0
print ('classe 0 :', sum(y_test==0))
print ('classe 1 :', sum(y_test==1))
In [11]:
import numpy as np
zero_preds = np.zeros_like(y_test) #Un tableau de 0 (classe 0) de la même taille que y_test
print ('Null accuracy :',metrics.accuracy_score(y_test, zero_preds))
La performance du modèle : 0.6927 est presque similaire à celle du modèle Null. On peut donc en conclure sur base de l'indicateur de performance taux de prédiction que notre modèle n'est pas très performant
Afin de mieux comprendre pourquoi notre modèle n'est pas performant, nous allons copmparer visuellement les vrais valeurs avec celles prédites
In [11]:
# Afficher les 25 premières valeurs
print 'True:', y_test.values[0:25]
print 'Pred:', y_pred_class[0:25]
In [12]:
#..................Que REMARQUEZ VOUS?
In [12]:
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(8,4))
plt.subplot(1,2,1)
_=plt.hist(y_test.values, color='red', normed=True)
plt.title('Vrais valeurs')
_=plt.ylim(0,10)
plt.subplot(1,2,2)
_=plt.hist(y_pred_class, color ='blue', normed=True)
plt.title('Valeurs Predites')
_=plt.ylim(0,10)
Conclusion:
In [13]:
print (metrics.confusion_matrix(y_test, y_pred_class))
Terminologie de base
In [ ]:
In [15]:
print 'True:', y_test.values[0:25]
print 'Pred:', y_pred_class[0:25]
In [16]:
# on stocke la matrice de confusion et on récupère les TP, TN, FP, FN
confusion = metrics.confusion_matrix(y_test, y_pred_class)
TP = confusion[1, 1]
TN = confusion[0, 0]
FP = confusion[0, 1]
FN = confusion[1, 0]
Taux de prédiction (accuracy): pourcentage d'instances correctement classifiées?
In [17]:
print (TP + TN) / float(TP + TN + FP + FN)
print metrics.accuracy_score(y_test, y_pred_class)
Erreur de classification (Classification Error ou Misclassification Rate): pourcentage d'instances incorrectement classifiées
In [18]:
print (FP + FN) / float(TP + TN + FP + FN)
print 1 - metrics.accuracy_score(y_test, y_pred_class)
Sensibilité (Sensitivity) ou Rappel (Recall) ou "True Positive Rate" : Quand la vrai valeur est positive combien de fois je prédis positif?
In [79]:
print TP / float(TP + FN)
print metrics.recall_score(y_test, y_pred_class)
Precision: Lorsque je prédis une valeur comme positive, combien de fois ma prédiction est correcte?
In [19]:
print TP / float(TP + FP)
print metrics.precision_score(y_test, y_pred_class)
Spécificité (Specificity): Quand la vrai valeur est negative, combien de fois je prédis négatif?
In [21]:
print TN / float(TN + FP)
In [22]:
print FP / float(TN + FP)
Conclusion:
Exemple de choix de metrics en fonction du problème posé?
Dans le problème qui nous concerne (Diabète), que faut-il optimiser?
Réponse et pourquoi?
In [20]:
# afficher les 10 premières prédictions
logreg.predict(X_test)[0:10]
Out[20]:
In [81]:
# afficher les degrés d'appartenance (les 10 premiers)
logreg.predict_proba(X_test)[0:10, :]
Out[81]:
In [24]:
# afficher les degrés d'appartenance pour la classe 1 (les 10 premiers)
logreg.predict_proba(X_test)[0:10, 1]
Out[24]:
In [82]:
# on stocke les degrés d'appartenance pour la classe 1
y_pred_prob = logreg.predict_proba(X_test)[:, 1]
In [83]:
# histogramme des probabilités prédites
plt.hist(y_pred_prob, bins=8)
plt.xlim(0, 1)
plt.title('Histogramme des probabilites predites')
plt.xlabel('Probabilite Predite d etre diabetique')
plt.ylabel('Frequence')
Out[83]:
Diminuer le seuil de prédiction du diabète pour augmenter la sensitivity du classifieur
In [89]:
# Predire un diabete si la probabilité prédite est supérieure à 0.3
y_pred_class = np.array(y_pred_prob>0.3, dtype=int)
In [90]:
# afficher les 10 premières probabilités prédites
y_pred_prob[0:10]
Out[90]:
In [91]:
# afficher les 10 premières classes prédites
y_pred_class[0:10]
Out[91]:
In [92]:
# ancienne matrice de confusion (seuil par défaut = 0.5)
print confusion
In [94]:
# nouvelle matrice de confusion (seuil = 0.3)
print metrics.confusion_matrix(y_test, y_pred_class)
In [95]:
# la sensitivity a augmenté (avant sensitivité = 0.24)
print 46 / float(46 + 16)
In [96]:
# la spécificité a diminué (avant spécificité = 0.91)
print 80 / float(80 + 50)
Conclusion:
In [97]:
fpr, tpr, thresholds = metrics.roc_curve(y_test, y_pred_prob)
plt.plot(fpr, tpr)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.title('courbe ROC du classifieur de diabetes')
plt.xlabel('False Positive Rate (1 - Specificity)')
plt.ylabel('True Positive Rate (Sensitivity)')
plt.grid(True)
In [98]:
print metrics.roc_auc_score(y_test, y_pred_prob)
In [87]:
x = np.array( [0.6, 0.4, 0.2] )
In [88]:
np.array (x>0.3 , dtype=int )
Out[88]:
In [ ]: