2015-09-04 9 views
10

Ich verwende Support Vector Regression als Schätzer in GridSearchCV. Aber ich möchte die Fehlerfunktion ändern: Anstatt den Standard (R-Quadrat: Bestimmtheitsmaß) zu verwenden, möchte ich meine eigene benutzerdefinierte Fehlerfunktion definieren.Wie erstelle ich eine eigene Scorer-Funktion in scikit-learn?

Ich habe versucht, ein mit make_scorer zu machen, aber es hat nicht funktioniert.

Ich habe die Dokumentation gelesen und festgestellt, dass es möglich ist, custom estimators zu erstellen, aber ich brauche nicht den gesamten Schätzer neu zu erstellen - nur die Fehler/Scoring-Funktion.

Ich glaube, ich kann es eine aufrufbare als Scorer durch die Definition, wie es in der docs sagt.

Aber ich weiß nicht, wie einen Schätzer verwenden: in meinem Fall SVR. Müsste ich zu einem Klassifizierer (wie SVC) wechseln? Und wie würde ich es benutzen?

Meine benutzerdefinierte Fehlerfunktion ist wie folgt:

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 

Die Variable M ist nicht null/null. Ich habe es einfach auf Null gestellt.

Würde jemand in der Lage ein Beispiel Anwendung dieser benutzerdefinierten Scoring-Funktion zu zeigen? Danke für Ihre Hilfe!

+0

Beispiel dafür: (Schätzer, X, y) – daniel2014

+0

denken Sie daran, eine der Antworten als die gute zu markieren. Danke :) – astrojuanlu

Antwort

11

Wie Sie gesehen haben, wird dies mithilfe von make_scorer() durchgeführt.

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:]) 
+0

Hallo. Ich kenne make_scorer, aber ich möchte eine neue Funktion definieren, die eine Bedingung enthält (If's da oben). Wie kann ich "if" und "for" innerhalb eines Funktionsfehlers verwenden? Vielen Dank. – daniel2014

+0

Sorry, ich verstehe das Problem dann nicht. Es ist mir nicht klar, was du zu tun versuchst. –

+0

Ich spreche sehr schlecht Englisch, sorry. Ich versuche, "wenn Bedingung" und "für" in "my_custom_loss_function" zu verwenden.Wie
def my_custom_loss_func (X_train_scaled, Y_train_scaled): Fehler, M = 0, 0 for i in range (0, len (Y_train_scaled)): z = (Y_train_scaled [i] - M) wenn X_train_scaled [i]> M und Y_train_skaliert [i]> M und (X_train_skaliert [i] - Y_train_skaliert [i])> 0: ...
Kann ich das tun? Mein Laptop scheint blockiert zu sein. Und ich möchte alle meine Daten in "X_train_scaled" eins nach dem anderen anschauen und dann darauf operieren. Vielen Dank. – daniel2014

12

Jamie hat eine konkretisiert Beispiel, aber hier ist ein Beispiel make_scorer direkt aus mit 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) 

Wenn Sie eine benutzerdefinierte scorer über sklearn.metrics.make_scorer definieren, ist die Konvention, dass benutzerdefinierte Funktionen der Endung _score geben Sie einen Wert zum Maximieren zurück. Und bei Scorern, die auf _loss oder _error enden, wird ein Wert zurückgegeben, der minimiert werden soll. Sie können diese Funktionalität verwenden, indem Sie den Parameter greater_is_better innerhalb von make_scorer setzen. Das heißt, würde dieser Parameter True für scorers geben, wo höhere Werte sind besser, und False für scorers wo niedrigere Werte sind besser. GridSearchCV kann dann in die entsprechende Richtung optimieren.

Sie können dann Ihre Funktion als Torschütze wie folgt konvertieren:

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) 

Und dann custom_scorer gehen in GridSearchCV wie jede andere Bewertungsfunktion: clf = GridSearchCV(scoring=custom_scorer).

+0

Vielen Dank für Ihre Antwort. Ich habe diese Dokumentation in Scikit gelesen und auch über die benutzerdefinierte Funktion gelesen, aber ich habe es nicht verstanden. Danach schrieb Jamie Bull seinen "make_scorer" und ich versuchte es erneut ... Es funktioniert! Ich weiß nicht wie oder warum. Ich habe zu Windows 10 gewechselt und alle meine Programme neu installiert ... Vielleicht war es: Windows 10 plus neue Version von Anaconda (Ich betreibe Python unter Anaconda). Wie auch immer, vielen Dank! (Ich bin kein Programmierer oder Informatiker ... so ist es schwer für mich). – daniel2014

Verwandte Themen