jeudi 13 août 2020

Régression logistique en Python : cours du professeur ng Andrew

Dans l'article précédent  (lien ici), je traduisais en Python le premier TP de la formation Machine learning de ng Andrew. Le TP introduisait les problèmes de régression linéaire. 
La deuxième semaine avait comme  objectif de présenter la régression logistique.
Cette notion est un prolongement de la régression linéaire. Le résultat est une probabilité qui permet de dresser une ligne de démarcation (deux clusters) entre 2 régions : oui ou non. Le jeu de données propose les notes d'examen pour  2 épreuves et le résultat de l'admission finale.
Il est demandé de tracer une droite qui partage au mieux les étudiants reçus et les recalés. 


Le gros point bleu en haut à droite est la visualisation de la probabilité estimée pour un cas de test.



x1_test =45
x2_test = 85
plt.scatter(x1_test, x2_test, c = 'lightblue', s = 400 )
plt.pause(40)
plt.show(block=False)
propa = thc[0] + thc[1] * 45 + thc[2] * 85
#print(propa)
print('estimation probabilite recu 45 ep1 et 85 ep2:',sigmoid(propa))

On utilise les principes de la régression linéaire pour ensuite appliquer une fonction (sigmoïde) qui ventile les résultats entre la valeur 0 et 1.

Autant pour le TP1 il était possible d'effectuer la descente en gradient par itération en étant sur de converger vers un résultat, dans ce cas de figure,  il  est nécessaire de faire appel à une fonction de calcul de minima.  

Avec octave ça donne ceci:

%  Run fminunc to obtain the optimal theta
%  This function will return theta and the cost 
[theta, cost] = ...
fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);


Avec Python , j'utilise  la fonction fmin_tnc de scipy


from scipy.optimize import fmin_tnc
Cette fonction à la signature suivante:
scipy.optimize.fmin_tnc(funcx0fprime=Noneargs=()approx_grad=0bounds=Noneepsilon=1e-08scale=Noneoffset=Nonemessages=15maxCGit=- 1maxfun=Noneeta=- 1stepmx=0accuracy=0fmin=0ftol=- 1xtol=- 1pgtol=- 1rescale=- 1disp=Nonecallback=None)

Minimize a function with variables subject to bounds, using gradient information in a truncated Newton algorithm. This method wraps a C implementation of the algorithm.


D'une manière  simple, il faut lui fournir la fonction de coût à minimiser, la fonction de gradient, les jeux de données et les résultats attendus.

essai = fmin_tnc(func = costFunction2, x0 = initial_theta.flatten(), fprime = None , args = (XX , yy.flatten() ) )
J'ai ajouté le calcul de la matrice de confusion importé de la librairie sklearn:

from sklearn.metrics import confusion_matrix
confusion
= confusion_matrix(pr,cible,[0,1])
print('matrice de confusion',confusion)
total = np.sum(confusion)
prec = (confusion[0][0] + confusion[1][1]) / total
effic = confusion[1][1]/np.sum(confusion, axis = 0)[1]
print('precision',prec)
print('pertinence', effic)

;
Le code n'est pas fameux en raison des contraintes sur le format des paramètres en entrée. C'est cette partie qu'il faudra améliorer.