[PYTHON] Appliquer la fonction d'influence à la régression logistique

Quelle est la fonction d'influence

La fonction proposée dans Understanding Black-box Predictions via Influence Functions, qui est le meilleur article d'ICML2017, donne les perturbations données par l'exemple d'apprentissage au modèle d'apprentissage automatique. C'est une formulation.

Veuillez vous référer à ici et ici pour le plan et l'explication de l'article.

Dans cet article, nous ferons quelques expériences pour comprendre le comportement de la fonction d'influence.

Régression logistique et fonction d'influence

Pour la régression logistique, reportez-vous à Cette implémentation.

<détails>

Utiliser le jeu de données iris </ summary>

import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris

#jeu de données iris
iris = load_iris()

#Utilisez uniquement la longueur et la largeur des épées setosa et versicolor
X = iris.data[iris.target != 2][:, :2]
Y = iris.target[iris.target != 2]

#Standardisation
X = StandardScaler().fit_transform(X)

#Nuage de points
plt.scatter(X[:,0][Y == 0], X[:,1][Y == 0], label=iris.target_names[0], marker='o') 
plt.scatter(X[:,0][Y == 1], X[:,1][Y == 1], label=iris.target_names[1], marker='x')
plt.legend()
plt.show()
Premièrement, nous implémentons généralement la régression logistique, l'appliquons à l'ensemble de données iris et illustrons les limites de décision.
def sigmoid(x):
    """Fonction Sigmaid"""
    return 1 / (1 + np.exp(-x))

def logistic_regression(X,Y):
    """Retour logistique"""
    ETA = 1e-3  #Taux d'apprentissage
    epochs = 5000  #Nombre de mises à jour
    
    #Ajout de la colonne 0 pour calculer le terme de biais
    X = np.hstack([np.ones([X.shape[0],1]),X])

    #Initialisation des paramètres
    theta = np.random.rand(3)

    print('Paramètre avant la mise à jour θ')
    print(theta)

    #Mise à jour des paramètres
    for _ in range(epochs):
        theta = theta + ETA * np.dot(Y - sigmoid(np.dot(X, theta)), X)

    print('Paramètre θ mis à jour')
    print(theta)

    print('Limite de décision')
    print('y = {:0.3f} + {:0.3f} * x1 + {:0.3f} * x2'.format(theta[0], theta[1], theta[2]))

    return theta

def decision_boundary(xline, theta):
    """Limite de décision"""
    return -(theta[0] + theta[1] * xline) / theta[2]

theta = logistic_regression(X,Y)

#Tracé des échantillons de données
plt.plot(X[Y==0, 0],X[Y==0,1],'o', label=iris.target_names[0])
plt.plot(X[Y==1, 0],X[Y==1,1],'x', label=iris.target_names[1])

xline = np.linspace(np.min(X[:,0]),np.max(X[:,0]),100)

#Tracé des limites de décision
plt.plot(xline, decision_boundary(xline, theta), label='decision boundary')
plt.legend()
plt.show()

influence1.png

<détails> <résumé> Ensuite, implémentez la fonction d'influence. (Je suis désolé si l'implémentation est fausse!) </ Summary>

#la fonction d'influence est y dans{1,-1}Convertissez Y de cette façon
Y1 = np.copy(Y)
Y1[Y1==0] = -1

#Ajout de la colonne 0 pour calculer le terme de biais
X1 = np.hstack([np.ones([X.shape[0],1]),X])

def get_influence(x,y,theta):
    """fonction d'influence"""
    H = (1/X1.shape[0]) * np.sum(np.array([sigmoid(np.dot(xi, theta)) * sigmoid(-np.dot(xi, theta)) * np.dot(xi.reshape(-1,1), xi.reshape(1,-1)) for xi in X1]), axis=0)
    return - y * sigmoid(- y * np.dot(theta, x)) * np.dot(-Y1 * sigmoid(np.dot(Y1, np.dot(theta, X1.T))), np.dot(x, np.dot(np.linalg.inv(H), X1.T)))

#Liste des valeurs d'influence pour chaque échantillon
influence_list = [get_influence(x,y,theta) for x,y in zip(X1,Y1)]

#Tracé avec valeur d'influence
plt.figure(figsize=(12,8))
plt.plot(X[Y==0, 0],X[Y==0,1],'o')
plt.plot(X[Y==1, 0],X[Y==1,1],'x')
plt.plot(xline, decision_boundary(xline, theta), label='decision boundary')
#Insérer la valeur d'influence dans le graphique
for x,influence in zip(X, influence_list):
    plt.annotate(f"{influence:.1f}", xy=(x[0], x[1]), size=10)
plt.legend()
plt.show()

La figure ci-dessous montre les valeurs d'influence des échantillons individuels tracés ensemble.

influence2.png

On peut voir que plus l'échantillon est proche de la limite de décision, plus la valeur d'influence est élevée.

Lorsqu'une mauvaise étiquette est intentionnellement mélangée

Les étiquettes erronées sont des étiquettes incorrectes qui peuvent entraîner un apprentissage incorrect du modèle ou empêcher une évaluation correcte.

Ici, nous allons étudier quelle sera la valeur d'influence en mélangeant des erreurs d'étiquetage intentionnelles.

Certaines étiquettes sont intentionnellement remplacées. Si vous regardez la figure ci-dessous, vous pouvez voir qu'il y a une étiquette clairement erronée.
#Remplacer intentionnellement certaines étiquettes
Y[76] = 0
Y[22] = 1

#Nuage de points
plt.scatter(X[:,0][Y == 0], X[:,1][Y == 0], label=iris.target_names[0], marker='o') 
plt.scatter(X[:,0][Y == 1], X[:,1][Y == 1], label=iris.target_names[1], marker='x')
plt.legend()
plt.show()

influence3.png

<détails> <résumé> Pour ces données, appliquez la régression logistique de la même manière que ci-dessus, calculez la valeur d'influence et illustrez-la comme suit. </ résumé>

theta = logistic_regression(X,Y)

#la fonction d'influence est y dans{1,-1}Convertissez Y de cette façon
Y1 = np.copy(Y)
Y1[Y1==0] = -1

#Ajout de la colonne 0 pour calculer le terme de biais
X1 = np.hstack([np.ones([X.shape[0],1]),X])

def get_influence(x,y,theta):
    """fonction d'influence"""
    H = (1/X1.shape[0]) * np.sum(np.array([sigmoid(np.dot(xi, theta)) * sigmoid(-np.dot(xi, theta)) * np.dot(xi.reshape(-1,1), xi.reshape(1,-1)) for xi in X1]), axis=0)
    return - y * sigmoid(- y * np.dot(theta, x)) * np.dot(-Y1 * sigmoid(np.dot(Y1, np.dot(theta, X1.T))), np.dot(x, np.dot(np.linalg.inv(H), X1.T)))

#Liste des valeurs d'influence pour chaque échantillon
influence_list = [get_influence(x,y,theta) for x,y in zip(X1,Y1)]

#Tracé avec valeur d'influence
plt.figure(figsize=(12,8))
plt.plot(X[Y==0, 0],X[Y==0,1],'o')
plt.plot(X[Y==1, 0],X[Y==1,1],'x')
plt.plot(xline, decision_boundary(xline, theta), label='decision boundary')
#Insérer la valeur d'influence dans le graphique
for x,influence in zip(X, influence_list):
    plt.annotate(f"{influence:.1f}", xy=(x[0], x[1]), size=10)
plt.legend()
plt.show()

influence4.png

Vous pouvez voir que la valeur d'influence de l'échantillon mal étiqueté est très élevée.

De plus, l'échantillon en bas à gauche se trouve en dehors de la limite de décision, et on craint qu'une erreur d'étiquetage ait un effet négatif sur l'apprentissage.

Résumé

  • En utilisant la fonction d'influence, vous pouvez trouver des échantillons proches de la limite de décision (pas sûrs) et des étiquettes erronées.

Recommended Posts

Appliquer la fonction d'influence à la régression logistique
Retour logistique
Retour logistique
Précautions lors de l'exécution de la régression logistique avec Statsmodels
Régression logistique d'apprentissage automatique
Division de la trame de données ⇒ Application de la fonction
Covector pour penser en fonction
Qu'est-ce que l'analyse de régression logistique?
Comment appeler une fonction
Essayez de dessiner une fonction logistique
Algorithme d'apprentissage automatique (régression logistique)
Implémentation de la régression logistique avec NumPy
J'ai essayé de créer un pointage de crédit simple avec régression logistique.