Importation et inspection des données¶

In [ ]:
#dossier par défaut
import os
os.chdir("C:/Users/ricco/Desktop/demo")

#data train
import pandas
dfTrain = pandas.read_excel("log_reg_fn_transformer.xlsx",sheet_name="train")
dfTrain.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   X1      150 non-null    float64
 1   X2      150 non-null    float64
 2   CLASSE  150 non-null    object 
dtypes: float64(2), object(1)
memory usage: 3.6+ KB
In [ ]:
#premières valeurs
dfTrain.head()
Out[ ]:
X1 X2 CLASSE
0 0.581752 0.563745 pos
1 0.692583 0.791619 pos
2 0.409230 0.199816 neg
3 0.042712 0.765088 pos
4 0.789292 0.108848 neg
In [ ]:
#structures
XTrain = dfTrain.iloc[:,:-1]
yTrain = dfTrain.CLASSE
In [ ]:
#data test
dfTest = pandas.read_excel("log_reg_fn_transformer.xlsx",sheet_name="test")
dfTest.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   X1      5000 non-null   float64
 1   X2      5000 non-null   float64
 2   CLASSE  5000 non-null   object 
dtypes: float64(2), object(1)
memory usage: 117.3+ KB
In [ ]:
#structures
XTest = dfTest.iloc[:,:-1]
yTest = dfTest.CLASSE

Modélisation et évaluation sur données originelles¶

In [ ]:
#régression logistique sur données originelles
from sklearn.linear_model import LogisticRegression

#instanciation, entraînement
lr_one = LogisticRegression(penalty=None,random_state=0)
lr_one.fit(XTrain,yTrain)

#affichage des coefs.
lr_one.coef_
Out[ ]:
array([[ 6.06937431, 14.51846216]])
In [ ]:
#performances en test
lr_one.score(XTest,yTest)
Out[ ]:
0.8838

Pipeline avec transformation de variables¶

(1) ColumnTransformer pour appliquer des transformations différenciées selon les colonnes.

(2) FunctionTransformer pour transformation à la volée d'une variable.

In [ ]:
#librairies
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import FunctionTransformer
import numpy

#fonction pour binariser une variable
def ma_binarisation(x):
    return numpy.where(x<0.5,0,1)

#préparation des données
#approche différente selon les variables
#on remarque que l'on peut passer 
# (a) fonction définie à la volée (lambda)
# (b) ou une fonction définie au préalable
prepa_data = ColumnTransformer([
    ('v1',FunctionTransformer(func=lambda x:x**2),['X1']),
    ('v2',FunctionTransformer(func=ma_binarisation),['X2'])])

Pipeline incluant la préparation des variables et la modélisation prédictive.

In [ ]:
#librairie
from sklearn.pipeline import Pipeline

#pipeline incluant la préparation
#et la régression logistique
wkf = Pipeline([
    ('preparation',prepa_data),
    ('lr',LogisticRegression(penalty=None,random_state=0))
])
In [ ]:
#entraînement
wkf.fit(XTrain,yTrain)

#affichage des coefficients
wkf.named_steps['lr'].coef_
Out[ ]:
array([[35.58866273, 43.11505234]])
In [ ]:
#visualisation des données (descripteurs)
#qui ont été présentées à la régression
Z = wkf.named_steps['preparation'].transform(XTrain)

#les 5 premières lignes seulement
Z[:5,:]
Out[ ]:
array([[0.33843503, 1.        ],
       [0.47967181, 1.        ],
       [0.16746881, 0.        ],
       [0.00182433, 1.        ],
       [0.62298246, 0.        ]])
In [ ]:
#performances en test
wkf.score(XTest,yTest)
Out[ ]:
0.9844

Sérialisation avec le package "dill"¶

Sauvegarde¶

In [ ]:
#sérialisation du Pipeline - attention "pas pickeable"
#quand FunctionTransformer avec fonctions lambda
#cf. https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.FunctionTransformer.html

#librairie dill, plus puissant, lui, peut le faire
#cf. https://dill.readthedocs.io/en/latest/
import dill

#créer le fichier en écriture binaire
f = open("workflow.sav","wb")

#sérialisation
dill.dump(wkf,f)

#ne pas oublier de fermer
f.close()
In [ ]:
#vérification des fichiers dans le dossier
os.listdir()
Out[ ]:
['log_reg_fn_transformer.xlsx',
 'pipeline_fn_transformer.ipynb',
 'workflow.sav']
In [ ]:
#supprimer la référence du workflow
wkf = None

Chargement dans un nouvel objet et déploiement¶

In [ ]:
#chargement
#ouvrir le fichier en lecture binaire
f = open("workflow.sav","rb")

try:
    #chargement
    modele = dill.load(f)
finally:
    #fermeture quoiqu'il en soit
    f.close()

#affichage des étapes
modele.named_steps
Out[ ]:
{'preparation': ColumnTransformer(transformers=[('v1',
                                  FunctionTransformer(func=<function <lambda> at 0x000002550F3E5580>),
                                  ['X1']),
                                 ('v2',
                                  FunctionTransformer(func=<function ma_binarisation at 0x0000025514CB8720>),
                                  ['X2'])]),
 'lr': LogisticRegression(penalty=None, random_state=0)}
In [ ]:
#performances en test du modèle chargé
#on a bien la même accuracy que précédemmentplus haut
modele.score(XTest,yTest)
Out[ ]:
0.9844