Algoritmo efficiente per calcolare la curva ROC per un classificatore costituito da un insieme di classificatori disgiunti


13

Supponiamo che io abbia i classificatori C_1 ... C_n che sono disgiunti, nel senso che nessuno due restituirà true sullo stesso input (ad esempio i nodi in un albero decisionale). Voglio costruire un nuovo classificatore che è l'unione di alcuni sottogruppi di questi (ad esempio, voglio decidere su quali foglie di un albero decisionale dare una classificazione positiva). Naturalmente, così facendo ci sarà un compromesso tra sensibilità e valore predittivo positivo. Quindi vorrei vedere una curva ROC. In linea di principio, potrei farlo elencando tutti i sottoinsiemi dei classificatori e calcolando la sensibilità e il PPV risultanti. Tuttavia, questo è proibitivamente costoso se n è più di 30 o giù di lì. D'altra parte, ci sono quasi certamente alcune combinazioni che non sono ottimali di Pareto, quindi potrebbero esserci delle strategie di branch e bound, o qualcosa del genere,

Vorrei un consiglio se è probabile che questo approccio sia proficuo e se c'è qualche lavoro o se avete idee su come calcolare in modo efficiente la curva ROC nella situazione sopra.


Stai classificando ogni caso di input come vero o falso?
image_doctor,

@image_doctor: si
Josh Brown Kramer,

"Non sono chiaro", ... che sono disgiunti nel senso che nessuno due tornerà vero sullo stesso input ... "e stai classificando su un output binario, come puoi avere più di due classificatori nel tuo insieme, probabilmente mi manchi qualcosa?
image_doctor

@image_doctor: potresti pensare che sto dicendo che non ci sono due classificatori che restituiscono lo stesso output sullo stesso input. Sto dicendo che nessuno tornerà vero. Entrambi possono restituire false.
Josh Brown Kramer,

1
Forse questo articolo su un modo teoricamente ottimale di combinare classificatori per ROC (o documenti che lo citano) può aiutarti a capire lo stato dell'arte: M. Barreno, A. Cardenas, JD Tygar, Optimal ROC Curve per una combinazione di classificatori, Progressi nei sistemi di elaborazione delle informazioni neurali, 2008.
Valentas

Risposte:


1

Se ho capito correttamente la domanda, hai addestrato un algoritmo che divide i tuoi dati in cluster disgiunti. Ora si desidera assegnare la previsione 1 ad alcuni sottogruppi dei cluster e 0 al resto di essi. E tra quei sottoinsiemi, vuoi trovare quelli pareto-ottimali, cioè quelli che massimizzano il vero tasso positivo dato il numero fisso di previsioni positive (questo equivale a fissare il PPV). È corretto?N10

Sembra molto un problema con lo zaino ! Le dimensioni del cluster sono "pesi" e il numero di campioni positivi in ​​un cluster sono "valori" e si desidera riempire lo zaino di capacità fissa con il maggior valore possibile.

vun'lueweioghtKK0N

1K-1p[0,1]K

Ecco un esempio di Python:

import numpy as np
from itertools import combinations, chain
import matplotlib.pyplot as plt
np.random.seed(1)
n_obs = 1000
n = 10

# generate clusters as indices of tree leaves
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_predict
X, target = make_classification(n_samples=n_obs)
raw_clusters = DecisionTreeClassifier(max_leaf_nodes=n).fit(X, target).apply(X)
recoding = {x:i for i, x in enumerate(np.unique(raw_clusters))}
clusters = np.array([recoding[x] for x in raw_clusters])

def powerset(xs):
    """ Get set of all subsets """
    return chain.from_iterable(combinations(xs,n) for n in range(len(xs)+1))

def subset_to_metrics(subset, clusters, target):
    """ Calculate TPR and FPR for a subset of clusters """
    prediction = np.zeros(n_obs)
    prediction[np.isin(clusters, subset)] = 1
    tpr = sum(target*prediction) / sum(target) if sum(target) > 0 else 1
    fpr = sum((1-target)*prediction) / sum(1-target) if sum(1-target) > 0 else 1
    return fpr, tpr

# evaluate all subsets
all_tpr = []
all_fpr = []
for subset in powerset(range(n)):
    tpr, fpr = subset_to_metrics(subset, clusters, target)
    all_tpr.append(tpr)
    all_fpr.append(fpr)

# evaluate only the upper bound, using knapsack greedy solution
ratios = [target[clusters==i].mean() for i in range(n)]
order = np.argsort(ratios)[::-1]
new_tpr = []
new_fpr = []
for i in range(n):
    subset = order[0:(i+1)]
    tpr, fpr = subset_to_metrics(subset, clusters, target)
    new_tpr.append(tpr)
    new_fpr.append(fpr)

plt.figure(figsize=(5,5))
plt.scatter(all_tpr, all_fpr, s=3)
plt.plot(new_tpr, new_fpr, c='red', lw=1)
plt.xlabel('TPR')
plt.ylabel('FPR')
plt.title('All and Pareto-optimal subsets')
plt.show();

Questo codice disegnerà una bella foto per te:

TPR, FPR e curva ottimale

210

E ora un po 'di sale: non dovevi preoccuparti affatto dei sottoinsiemi ! Quello che ho fatto è stato ordinato le foglie degli alberi in base alla frazione di campioni positivi in ​​ciascuno. Ma quello che ho ottenuto è esattamente la curva ROC per la previsione probabilistica dell'albero. Ciò significa che non è possibile sovraperformare l'albero selezionando a mano le sue foglie in base alle frequenze target nel set di allenamento.

Puoi rilassarti e continuare a usare la normale previsione probabilistica :)


Grande idea. In teoria potrebbe esserci ancora un numero esponenzialmente possibile di "chiamate positive", ma in pratica probabilmente non è un problema.
Valentas,

Perché numero esponenziale di chiamate? Calcolo il valore / peso per ciascun cluster (richiede tempo lineare), li ordina (N * log (N)) e valuto TPR e FPR per ogni primo cluster K (può anche essere reso lineare).
David Dale,

Risolvi lo zaino per ogni possibile valore di previsioni positive e c'è un numero esponenziale di sottoinsiemi. Ma questo è un tecnicismo teorico se chiedi specificamente i punti all'interno dello scafo convesso, il che non è interessante - questa dovrebbe essere la risposta accettata.
Valentas,

@Valentas, OK, vedo il tuo punto. Tuttavia, se dai una previsione casuale in alcune foglie, puoi arrivare a qualsiasi punto dello scafo convesso. Quindi in questo caso lo scafo è lo stesso ROC.
David Dale,

@DavidDale, per riassumere: 1) Ogni strategia che è pareto ottimale rispetto a (sensibilità, PPV) massimizza il numero di veri positivi tra le strategie con quel numero di previsioni positive. 2) Questo è il problema dello zaino. 3) La scelta dei nodi in ordine di numero di esempi positivi / numero di esempi è nota per essere una buona soluzione approssimativa al problema dello zaino. 4) Ma è lo stesso che scegliere una soglia per le probabilità.
Josh Brown Kramer,

0

Potrei suggerire che usi metodi avidi. Dai un classificatore per iniziare, includerai il classificatore che farà sì che l'ensemble ottenga il miglior miglioramento delle prestazioni. Se non è possibile ottenere alcun miglioramento, includere più classificatori, quindi interrompere. Inizierai con tutti i classificatori. La complessità sarà al massimo N * N.

Ho un'altra domanda, cosa intendi con "Pareto ottimale", specialmente nel tuo contesto? Ho trovato dal wiki questa spiegazione, https://en.wikipedia.org/wiki/Pareto_efficiency

attraverso la riallocazione, è possibile apportare miglioramenti al benessere di almeno un partecipante senza ridurre il benessere di nessun altro partecipante.

Il miglioramento dell'efficienza di Pareto è per ciascun partecipante, che potrebbe corrispondere a ciascun classificatore. Come si definisce il miglioramento rispetto a un classificatore?


1
Quello che voglio dire è questo: se ho gli ensemble 1 e 2, con (sensibilità, valore predittivo positivo) = (.90, .80) e (.97, .93) rispettivamente, allora 1 non è Pareto ottimale, perché c'è un altro ensemble, vale a dire 2, che lo batte in ogni modo. Per quanto riguarda l'algoritmo proposto: esiste un compromesso tra sensibilità e PPV, quindi "l'ensemble ottiene il miglior miglioramento delle prestazioni" non è ben definito.
Josh Brown Kramer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.