2016-08-26 2 views
0

Ich habe über eine halbe Million Paare von echten Labels und vorhergesagten Scores (die Länge jedes 1d-Arrays variiert und kann zwischen 10.000 und 30.000 liegen), für die ich die AUC berechnen muss. Gerade jetzt, ich habe eine for-Schleife, die ruft:Schnellere AUC in Sklearn oder Python

# Simple Example with two pairs of true/predicted values instead of 500,000 
from sklearn import metrics 
import numpy as np 

pred = [None] * 2 
pred[0] = np.array([3,2,1]) 
pred[1] = np.array([15,12,14,11,13]) 

true = [None] * 2 
true[0] = np.array([1,0,0]) 
true[1] = np.array([1,1,1,0,0]) 

for i in range(2): 
    fpr, tpr, thresholds = metrics.roc_curve(true[i], pred[i]) 
    print metrics.auc(fpr, tpr) 

Aber es etwa 1-1,5 Stunden in Anspruch nimmt den gesamten Datensatz und berechnen Sie die AUC für jedes true/Vorhersage Paar zu verarbeiten. Gibt es einen schnelleren/besseren Weg, dies zu tun?

aktualisieren

Jede der 500K-Einträge können Form (1, 10k +). Ich verstehe, dass ich es parallelisieren könnte, aber ich bin auf einer Maschine mit nur zwei Prozessoren stecken und so kann meine Zeit wirklich nur effektiv reduziert werden, um zu sagen, 30-45, Minuten, die immer noch zu lang ist. Ich habe festgestellt, dass die AUC-Berechnung selbst langsam ist und hoffte, einen schnelleren AUC-Algorithmus zu finden, als in slearn verfügbar ist. Oder finden Sie zumindest einen besseren Weg, die AUC-Berechnung zu vektorisieren, so dass sie über mehrere Zeilen hinweg übertragen werden kann.

+0

so klar sein, Ihre 'pred' und' true' Arrays Länge 500k Einträge haben, von denen jeder ein np.array mit Form (10k, 1)? Wenn ja, möchten Sie den Auc für jede der Kombinationen pred [i |/true [i] berechnen, dh jede Berechnung ist unabhängig? – miraculixx

+0

Wie viel Zeit braucht die AUC-Berechnung für ein Paar? Wie viel Zeit "t" pro Paar wäre zulässig, um auf das zu kommen, was Sie brauchen (dh "t * 0,5e6 miraculixx

Antwort

1

Gibt es eine schnellere/bessere Möglichkeit, dies zu tun?

Da die Berechnung jedes true/pred Paar ist unabhängig (wenn ich Ihre Einrichtung verstanden), sollten Sie in der Lage sein Gesamtverarbeitungszeit zu verringern, indem multiprocessing verwenden, effektiv die Berechnungen parallelisieren:

import multiprocessing as mp 

def roc(v): 
    """ calculate one pair, return (index, auc) """ 
    i, true, pred = v 
    fpr, tpr, thresholds = metrics.roc_curve(true, pred, drop_intermediate=True) 
    auc = metrics.auc(fpr, tpr) 
    return i, auc 

pool = mp.Pool(3) 
result = pool.map_async(roc, ((i, true[i], pred[i]) for i in range(2))) 
pool.close() 
pool.join() 
print result.get() 
=> 
[(0, 1.0), (1, 0.83333333333333326)] 

Hier erstellt Pool(3) einen Pool von 3 Prozessen, .map_async bildet alle True/Pred-Paare ab und ruft die roc-Funktion auf, wobei jeweils ein Paar übergeben wird. Der Index wird gesendet, um die Back-Ergebnisse abzubilden.

Wenn das true/pred Paare zu groß sind, um die Prozesse zu serialisieren und zu senden, müssen Sie die Daten in eine externe Datenstruktur zu schreiben, bevor roc Aufruf, übergeben Sie einfach die Referenz i und die Daten für jedes Paar lesen true[i]/pred[i] von innerhalb roc vor der Verarbeitung.

Ein Pool verwaltet automatisch die Planung von Prozessen. Um das Risiko eines Speicherschwundes zu reduzieren, müssen Sie möglicherweise den Parameter Pool(...., maxtasksperchild=1) übergeben, der für jedes echte/pred-Paar einen neuen Prozess startet (wählen Sie eine beliebige andere Zahl, wie Sie es für richtig halten).

aktualisieren

ich nur mit zwei Prozessoren auf einer Maschine bin stecken

natürlich ist dies ein limitierender Faktor. In Anbetracht der Verfügbarkeit von Cloud-Computing-Ressourcen zu sehr vernünftigen Kosten, die Sie nur für die Zeit bezahlen, die Sie tatsächlich benötigen, sollten Sie Alternativen in Hardware in Betracht ziehen, bevor Sie Stunden damit verbringen, eine Berechnung zu optimieren, die so effektiv parallelisiert werden kann. Das ist wirklich ein Luxus, wirklich.

+0

Bitte beachten Sie das Update – slaw

0

einen besseren Weg finden, die AUC Berechnung vektorisieren, so dass es über mehrere Zeilen

ausgestrahlt werden kann

Wahrscheinlich nicht - sklearn bereits effiziente numpy Operationen für die Berechnung der relevanten Teile verwendet:

# -- calculate tps, fps, thresholds 
# sklearn.metrics.ranking:_binary_clf_curve() 
(...) 
distinct_value_indices = np.where(np.logical_not(isclose(
     np.diff(y_score), 0)))[0] 
threshold_idxs = np.r_[distinct_value_indices, y_true.size - 1] 
# accumulate the true positives with decreasing threshold 
tps = (y_true * weight).cumsum()[threshold_idxs] 
if sample_weight is not None: 
    fps = weight.cumsum()[threshold_idxs] - tps 
else: 
    fps = 1 + threshold_idxs - tps 
return fps, tps, y_score[threshold_idxs] 

# -- calculate auc 
# sklearn.metrics.ranking:auc() 
... 
area = direction * np.trapz(y, x) 
... 

Sie können dies möglicherweise optimieren, indem Sie diese Funktionen profilieren und Vorgänge entfernen, die Sie zuvor effizienter anwenden können. Eine schnelle Profilierung Ihrer Beispiel Eingabe in 5M Zeilen skaliert zeigt einige mögliche Engpässe (markiert >>>):

# your for ... loop wrapped in function roc() 
%prun -s cumulative roc 
722 function calls (718 primitive calls) in 5.005 seconds 
Ordered by: cumulative time 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 5.005 5.005 <string>:1(<module>) 
     1 0.000 0.000 5.005 5.005 <ipython-input-51-27e30c04d997>:1(roc) 
     2 0.050 0.025 5.004 2.502 ranking.py:417(roc_curve) 
     2 0.694 0.347 4.954 2.477 ranking.py:256(_binary_clf_curve) 
    >>>2 0.000 0.000 2.356 1.178 fromnumeric.py:823(argsort) 
    >>>2 2.356 1.178 2.356 1.178 {method 'argsort' of 'numpy.ndarray' objects} 
     6 0.062 0.010 0.961 0.160 arraysetops.py:96(unique) 
    >>>6 0.750 0.125 0.750 0.125 {method 'sort' of 'numpy.ndarray' objects} 
    >>>2 0.181 0.090 0.570 0.285 numeric.py:2281(isclose) 
     2 0.244 0.122 0.386 0.193 numeric.py:2340(within_tol) 
     2 0.214 0.107 0.214 0.107 {method 'cumsum' of 'numpy.ndarray' objects} 
Verwandte Themen