Aller au contenu

Module 2: Machine Learning - Apprentissage non supervisé


Partie 2.3: Régression logistique

La régression est un algorithme d'apprentissage supervisé (classification binaire).

Objectifs * Visualiser les données * Étudier les liens de corrélation linéaire entre les variables * Réduire le nombre de dimensions

L'idée de l'ACP est de projeter les données sur des axes préservant la variance des données. Avec p=2 ou p=3, on peut visualiser ls données.

Principe : approximer un nuage de points X de dimension p par sa projection linéaire en dimension d < p.
L'ACP maximise la variance des points projectés.

On cherche à réaliser la projection x app Rp-->Rd, d<p
L'espace de projection P inclus dans Rd sera construit de manière progressive. * D'abord on va chercher le meilleur axe de projection (1D) u1 * Ensuite le meilleur plan en trouvant le deuxième axe u2 * Et ainsi de suite jusqu'à obtenir P

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix

Importation des données

Le jeu de donnés contient des donnés récuellies chez des patients, il comporte 100 lignes et 9 colonnes. La colonne diagnosis_result est la variable à expliquer qui represente le resultat du diagnostic. Les 8 dernières colonnes représentent les variables explicatives.

dt = pd.read_csv('datasets/Prostate_Cancer.csv', index_col='id')
dt.head()
diagnosis_result radius texture perimeter area smoothness compactness symmetry fractal_dimension
id
1 M 23 12 151 954 0.143 0.278 0.242 0.079
2 B 9 13 133 1326 0.143 0.079 0.181 0.057
3 M 21 27 130 1203 0.125 0.160 0.207 0.060
4 M 14 16 78 386 0.070 0.284 0.260 0.097
5 M 9 19 135 1297 0.141 0.133 0.181 0.059

Exploration

Variable à expliquer

sns.countplot(x='diagnosis_result', data=dt)
<matplotlib.axes._subplots.AxesSubplot at 0x7f7718598e10>
dt.diagnosis_result.value_counts()
M    62
B    38
Name: diagnosis_result, dtype: int64

Les classes M et B sont déséquilibrées M(62) et B(38), il faudra en tenir compte dans la suite. Un modèle naïf qui prédit la classe M aurait une accuracy de 62% sans avoir appris les données.

Variables explicatives

sns.boxplot(data=dt, orient='h')
<matplotlib.axes._subplots.AxesSubplot at 0x7f76ec339450>

Les variables ont des échelles (ou ordres de grandeur) différentes, il faut supprimer la dimension

Centrage et Réduction

  • Centrer une variable consiste à retrancher la moyenne de toutes les données, la nouvelle moyenne est 0.
  • Réduire (ou normliser) une variable consiste à diviser toutes les données par l'écart-type, le nouvel écart-type est 1.
X = dt.iloc[:, 1:]
scaler = StandardScaler().fit(X)
X_scaled = scaler.transform(X)
dt.iloc[:, 1:] = X_scaled
sns.boxplot(data=dt, orient='h')
<matplotlib.axes._subplots.AxesSubplot at 0x7f76ec265150>
sns.pairplot(data=dt, hue='diagnosis_result')
<seaborn.axisgrid.PairGrid at 0x7f76ec390810>
sns.scatterplot(x='compactness', y='area', hue='diagnosis_result', data=dt)
<matplotlib.axes._subplots.AxesSubplot at 0x7f76e9624510>

Encodage de la variable explicative

On encode les valeurs B et M en 0 et 1.

y = dt.iloc[:, 0]
encoder = LabelEncoder().fit(y)
y = encoder.transform(y)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, stratify=y, test_size=.3)

L'argument stratify c'est pour indiquer que l'on souhaite que la séparation soit équilibrée suivant la variable diagnosis_result.

Régression logistique avec Scikit-learn

clf = LogisticRegression()
clf.fit(X_train, y_train)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=100,
                   multi_class='auto', n_jobs=None, penalty='l2',
                   random_state=None, solver='lbfgs', tol=0.0001, verbose=0,
                   warm_start=False)

Évaluation

Plusieurs métriques peuvent être utilsés pour évaluer un modèle de classification (binaire). Le plus utilsé est l'accuracy. * Accuracy: le taux de bonnes prédictions. Lorsque les classes sont déséquilibrées, elle peut être trompeuse. * Précision: le taux de bonnes prédictions sur les prédictions positives. * Rappel: le taux de bonnes prédictions sur les données positives. * F1_score:

y_pred = clf.predict(X_test)

acc = accuracy_score(y_test, y_pred) 
f1 = f1_score(y_test, y_pred)
confmat = confusion_matrix(y_test, y_pred)

print('Accuracy: %0.2f' % acc)
print('F1 score: %0.2f' % f1)

plt.matshow(confmat, cmap=plt.cm.Greens, alpha=.3)
for i in range(confmat.shape[0]):
    for j in range(confmat.shape[1]):
        plt.text(x=j, y=i, s=confmat[i, j], va='center', ha='center')
plt.xlabel('Valeur prédite')
plt.ylabel('Vraie valeur')
plt.show()
Accuracy: 0.83
F1 score: 0.86

Interprétaion

Le premier axe conserve 41,2% le deuxième axe 19,4% et le troisème axe 14,3%. Les trois axes permettent de conserver environ 75% de variance des données. Si l'on souhaite conserver plus de variance, on peut ajouter un axe supplémentaire ou plus. Remarquons qu'il est peu pertinent de conserver toute la variance, autant travailler avec les données initiales, il ne faut pas perdre de vue que l'un des objectifs de l'ACP, c'est la réduction du nombre de dimensions.

Références * Appilquez l'apprentissage statistique aux objets connectés * Appilquez l'apprentissage statistique aux objets connectés * Appilquez l'apprentissage statistique aux objets connectés

Contribuer à ce projet
Toute contribution de votre part serait vivement appréciée. Si vous souhaiter contribuer à ce projet, merci de consulter ce guide CONTRIBUTING

Signaler un bug
Si vous avez rencontré un bug durant l'éxecution de ce notebook, pour le signaler, il suffit d'ouvrir une issue.

Sponsors
* Rintio * Solidar'IT

Copyright & Licence
Sous licence MIT