Ich arbeite an einem Klassifizierungsproblem mit unausgeglichenen Klassen (5% 1). Ich möchte die Klasse vorhersagen, nicht die Wahrscheinlichkeit.
classifier.predict()
Verwendet Scikit bei einem binären Klassifizierungsproblem 0.5
standardmäßig? Wenn nicht, wie lautet die Standardmethode? Wenn ja, wie ändere ich es?
In Scikit haben einige Klassifikatoren die class_weight='auto'
Option, aber nicht alle. Mit class_weight='auto'
würde .predict()
der tatsächliche Bevölkerungsanteil als Schwelle verwendet werden?
Was wäre der Weg, dies in einem Klassifikator zu tun MultinomialNB
, der nicht unterstützt wird class_weight
? Anders als predict_proba()
die Klassen selbst zu benutzen und dann zu berechnen.
Der Schwellenwert kann mit eingestellt werden
clf.predict_proba()
zum Beispiel:
from sklearn.tree import DecisionTreeClassifier clf = DecisionTreeClassifier(random_state = 2) clf.fit(X_train,y_train) # y_pred = clf.predict(X_test) # default threshold is 0.5 y_pred = (clf.predict_proba(X_test)[:,1] >= 0.3).astype(bool) # set threshold as 0.3
quelle
clf.predict()
, was Sie nicht tun.Der Schwellenwert beim Scikit-Lernen beträgt 0,5 für die binäre Klassifizierung und die Klasse mit der größten Wahrscheinlichkeit für die Klassifizierung mehrerer Klassen. Bei vielen Problemen kann durch Einstellen des Schwellenwerts ein viel besseres Ergebnis erzielt werden. Dies muss jedoch mit Sorgfalt und NICHT anhand der Holdout-Testdaten erfolgen, sondern durch Kreuzvalidierung der Trainingsdaten. Wenn Sie den Schwellenwert für Ihre Testdaten anpassen, passen Sie die Testdaten nur an.
Die meisten Methoden zum Anpassen des Schwellenwerts basieren auf den Empfängerbetriebseigenschaften (ROC) und der Youden-J-Statistik , können jedoch auch mit anderen Methoden durchgeführt werden, z. B. mit einer Suche mit einem genetischen Algorithmus.
Hier ist ein Artikel in einem Peer-Review-Journal, in dem dies in der Medizin beschrieben wird:
http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2515362/
Soweit ich weiß, gibt es kein Paket dafür in Python, aber es ist relativ einfach (aber ineffizient), es mit einer Brute-Force-Suche in Python zu finden.
Dies ist ein R-Code, der dies tut.
## load data DD73OP <- read.table("/my_probabilites.txt", header=T, quote="\"") library("pROC") # No smoothing roc_OP <- roc(DD73OP$tc, DD73OP$prob) auc_OP <- auc(roc_OP) auc_OP Area under the curve: 0.8909 plot(roc_OP) # Best threshold # Method: Youden #Youden's J statistic (Youden, 1950) is employed. The optimal cut-off is the threshold that maximizes the distance to the identity (diagonal) line. Can be shortened to "y". #The optimality criterion is: #max(sensitivities + specificities) coords(roc_OP, "best", ret=c("threshold", "specificity", "sensitivity"), best.method="youden") #threshold specificity sensitivity #0.7276835 0.9092466 0.7559022
quelle
Sie scheinen hier verwirrende Konzepte zu haben. Der Schwellenwert ist kein Konzept für einen "generischen Klassifikator" - die grundlegendsten Ansätze basieren auf einem einstellbaren Schwellenwert, aber die meisten vorhandenen Methoden erstellen komplexe Regeln für die Klassifizierung, die nicht als Schwellenwert angesehen werden können (oder sollten).
Also zuerst - man kann Ihre Frage nach dem Standardschwellenwert für den Klassifikator von scikit nicht beantworten, weil es so etwas nicht gibt.
Bei der Gewichtung der zweiten Klasse geht es nicht um Schwellenwerte, sondern um die Fähigkeit des Klassifikators, mit unausgeglichenen Klassen umzugehen, und es geht um etwas, das von einem bestimmten Klassifikator abhängt. Zum Beispiel - im SVM-Fall ist dies die Art und Weise, wie die Slack-Variablen im Optimierungsproblem gewichtet werden, oder, wenn Sie es vorziehen - die Obergrenzen für die mit bestimmten Klassen verbundenen Lagrange-Multiplikatorwerte. Wenn Sie dies auf "Auto" setzen, wird eine Standardheuristik verwendet, aber auch dies kann nicht einfach in einen Schwellenwert übersetzt werden.
Naive Bayes hingegen schätzt die Klassenwahrscheinlichkeit direkt aus dem Trainingssatz. Es heißt "class prior" und kann im Konstruktor mit der Variablen "class_prior" festgelegt werden.
Aus der Dokumentation :
quelle
Falls jemand diesen Thread besucht und auf eine gebrauchsfertige Funktion hofft (Python 2.7). In diesem Beispiel soll der Cutoff das Verhältnis von Ereignissen zu Nichtereignissen im Originaldatensatz df widerspiegeln , während y_prob das Ergebnis der .predict_proba-Methode sein könnte (unter der Annahme einer geschichteten Zug- / Testaufteilung).
def predict_with_cutoff(colname, y_prob, df): n_events = df[colname].values event_rate = sum(n_events) / float(df.shape[0]) * 100 threshold = np.percentile(y_prob[:, 1], 100 - event_rate) print "Cutoff/threshold at: " + str(threshold) y_pred = [1 if x >= threshold else 0 for x in y_prob[:, 1]] return y_pred
Fühlen Sie sich frei zu kritisieren / ändern. Ich hoffe, es hilft in seltenen Fällen, wenn ein Klassenausgleich nicht in Frage kommt und der Datensatz selbst stark unausgeglichen ist.
quelle