Comment créer/personnaliser votre propre fonction de marqueur dans scikit-learn?
j'utilise Régression À Vecteurs De Support comme un estimateur GridSearchCV. Mais je veux changer la fonction d'erreur: au lieu d'utiliser la valeur par défaut (R-squared: coefficient de détermination), je tiens à définir ma propre fonction d'erreur.
j'ai essayé de faire un make_scorer
, mais il ne fonctionne pas.
j'ai lu la documentation et a trouvé qu'il est possible de créer estimateurs sur mesure, mais je n'ai pas besoin de refaire le estimateur entier - seulement la fonction d'erreur / de notation.
je pense que je peux le faire par la définition d'un callable en tant que correcteur, comme il est dit dans le docs.
mais je ne sais pas comment utiliser un estimateur: dans mon cas SVR. Devrais-je passer à un classificateur (comme SVC)? Et comment pourrais-je l'utiliser?
ma fonction d'erreur personnalisée est la suivante:
def my_custom_loss_func(X_train_scaled, Y_train_scaled):
error, M = 0, 0
for i in range(0, len(Y_train_scaled)):
z = (Y_train_scaled[i] - M)
if X_train_scaled[i] > M and Y_train_scaled[i] > M and (X_train_scaled[i] - Y_train_scaled[i]) > 0:
error_i = (abs(Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(z))
if X_train_scaled[i] > M and Y_train_scaled[i] > M and (X_train_scaled[i] - Y_train_scaled[i]) < 0:
error_i = -(abs((Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(z)))
if X_train_scaled[i] > M and Y_train_scaled[i] < M:
error_i = -(abs(Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(-z))
error += error_i
return error
la variable M
n'est pas null/zero. Je viens de mettre à zéro pour simplicité.
Quelqu'un pourrait-il montrer un exemple d'application de cette fonction de notation personnalisée? Merci pour votre aide!
2 réponses
comme vous l'avez vu, ceci est fait en utilisant make_scorer
( docs).
from sklearn.grid_search import GridSearchCV
from sklearn.metrics.scorer import make_scorer
from sklearn.svm import SVR
import numpy as np
rng = np.random.RandomState(1)
def my_custom_loss_func(X_train_scaled, Y_train_scaled):
error, M = 0, 0
for i in range(0, len(Y_train_scaled)):
z = (Y_train_scaled[i] - M)
if X_train_scaled[i] > M and Y_train_scaled[i] > M and (X_train_scaled[i] - Y_train_scaled[i]) > 0:
error_i = (abs(Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(z))
if X_train_scaled[i] > M and Y_train_scaled[i] > M and (X_train_scaled[i] - Y_train_scaled[i]) < 0:
error_i = -(abs((Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(z)))
if X_train_scaled[i] > M and Y_train_scaled[i] < M:
error_i = -(abs(Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(-z))
error += error_i
return error
# Generate sample data
X = 5 * rng.rand(10000, 1)
y = np.sin(X).ravel()
# Add noise to targets
y[::5] += 3 * (0.5 - rng.rand(X.shape[0]/5))
train_size = 100
my_scorer = make_scorer(my_custom_loss_func, greater_is_better=True)
svr = GridSearchCV(SVR(kernel='rbf', gamma=0.1),
scoring=my_scorer,
cv=5,
param_grid={"C": [1e0, 1e1, 1e2, 1e3],
"gamma": np.logspace(-2, 2, 5)})
svr.fit(X[:train_size], y[:train_size])
print svr.best_params_
print svr.score(X[train_size:], y[train_size:])
Jamie a un exemple étoffé, Mais voici un exemple utilisant make_scorer directement de scikit-learn documentation:
import numpy as np
def my_custom_loss_func(ground_truth, predictions):
diff = np.abs(ground_truth - predictions).max()
return np.log(1 + diff)
# loss_func will negate the return value of my_custom_loss_func,
# which will be np.log(2), 0.693, given the values for ground_truth
# and predictions defined below.
loss = make_scorer(my_custom_loss_func, greater_is_better=False)
score = make_scorer(my_custom_loss_func, greater_is_better=True)
ground_truth = [[1, 1]]
predictions = [0, 1]
from sklearn.dummy import DummyClassifier
clf = DummyClassifier(strategy='most_frequent', random_state=0)
clf = clf.fit(ground_truth, predictions)
loss(clf,ground_truth, predictions)
score(clf,ground_truth, predictions)
lors de la définition d'un marqueur personnalisé via sklearn.metrics.make_scorer
, la convention est que les fonctions personnalisées se terminant par _score
retourner une valeur pour maximiser. Et pour les buteurs se terminant par _loss
ou _error
, une valeur est retournée pour être minimisée. Vous pouvez utiliser cette fonctionnalité en définissant le greater_is_better
paramètre à l'intérieur de make_scorer
. C'est, ce paramètre devrait être True
pour les marqueurs où des valeurs plus élevées sont meilleures, et False
pour les marqueurs où les valeurs inférieures sont meilleures. GridSearchCV
peut alors optimiser dans la bonne direction.
vous pouvez alors convertir votre fonction de marqueur comme suit:
from sklearn.metrics.scorer import make_scorer
def custom_loss_func(X_train_scaled, Y_train_scaled):
error, M = 0, 0
for i in range(0, len(Y_train_scaled)):
z = (Y_train_scaled[i] - M)
if X_train_scaled[i] > M and Y_train_scaled[i] > M and (X_train_scaled[i] - Y_train_scaled[i]) > 0:
error_i = (abs(Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(z))
if X_train_scaled[i] > M and Y_train_scaled[i] > M and (X_train_scaled[i] - Y_train_scaled[i]) < 0:
error_i = -(abs((Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(z)))
if X_train_scaled[i] > M and Y_train_scaled[i] < M:
error_i = -(abs(Y_train_scaled[i] - X_train_scaled[i]))**(2*np.exp(-z))
error += error_i
return error
custom_scorer = make_scorer(custom_loss_func, greater_is_better=True)
puis passer custom_scorer
en GridSearchCV
comme vous le feriez avec toute autre fonction de notation: clf = GridSearchCV(scoring=custom_scorer)
.