La régression linéaire est l'un des algorithmes les plus connus. Elle est toujours enseigné au lycée. Il permet de résoudre des problèmes de régression de type linéaire.
La régression logistique est un algorithme de classification binaire de type linéaire. Elle répond donc aux problèmes linéairement séparables c'est-à-dire qu'on peut séparer les points des deux clases avec une droite.
Binaire: deux classes Linéaire: on peut séparer les deux classes à l'aide d'une droite
La solution d'une régression s'obtient en minimisant l'entropie croisée binaire.
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
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()
sns.countplot(x='diagnosis_result', data=dt) plt.show()
<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.
sns.boxplot(data=dt, orient='h') plt.show()
<matplotlib.axes._subplots.AxesSubplot at 0x7f76ec339450>
Les variables ont des échelles (ou ordres de grandeur) différentes, il faut supprimer la dimension
X = dt.iloc[:, 1:] scaler = StandardScaler().fit(X) X_scaled = scaler.transform(X) dt.iloc[:, 1:] = X_scaled
<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) plt.show()
<matplotlib.axes._subplots.AxesSubplot at 0x7f76e9624510>
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.
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)
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
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.
# coding : utf-8 ''' Scikit-learn Challenge #02 : Logistic Regression ''' # Packages import pickle from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, confusion_matrix # Get data X, y = make_classification(n_samples=100, n_features=4, n_classes=2) # Design model clf = LogisticRegression(penalty='l2', C=0.8) # Train model clf.fit(X, y) # Evaluate model y_pred = clf.predict(X) score = accuracy_score(y, y_pred) print('Accuracy score: ', round(score, 2)) conf_mat = confusion_matrix(y, y_pred) print(conf_mat) # Inference output = clf.predict([[1.5, 0.24, 2.6, 0.1]])[0] print('Predcited class: ', output) # Save model with open('output/model.pkl', 'wb') as f: pickle.dump(obj=clf, file=f)
Pour signaler un problème que vous avez rencontré durant l'exécution des cahiers, merci de créer une issue. Assurez-vous que vous avez les bonnes versions des packages*
issue