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.
Pour la régression logistique, reportez-vous à Cette implémentation.
<détails> <détails> <résumé> Ensuite, implémentez la fonction d'influence. (Je suis désolé si l'implémentation est fausse!) </ Summary> La figure ci-dessous montre les valeurs d'influence des échantillons individuels tracés ensemble. On peut voir que plus l'échantillon est proche de la limite de décision, plus la valeur d'influence est élevé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. <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é> 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.
Recommended Posts
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. résumé>
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()
#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()
Lorsqu'une mauvaise étiquette est intentionnellement mélangée
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. résumé>
#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()
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()
Résumé