N10 au reste d'entre eux. Et au-dessus de ces sous-ensembles, vous voulez trouver ceux pareto-optimaux, c'est-à-dire ceux qui maximisent le vrai taux positif étant donné un nombre fixe de prédictions positives (cela équivaut à fixer PPV). Est-ce correct?
Cela ressemble beaucoup à un problème de sac à dos ! Les tailles de grappe sont des "poids" et le nombre d'échantillons positifs dans une grappe sont des "valeurs", et vous souhaitez remplir votre sac à dos de capacité fixe avec autant de valeur que possible.
v a l u ew e i gh tkk0N
1k - 1p ∈ [ 0 , 1 ]k du problème du sac à dos. Avec cela, vous pouvez dessiner la limite supérieure de votre courbe ROC.
Voici un exemple de 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();
Ce code dessinera une belle image pour vous:
2dix
Et maintenant, le peu de sel: vous n'avez pas du tout à vous soucier des sous-ensembles ! Ce que j'ai fait, c'est trier les feuilles des arbres en fonction de la fraction d'échantillons positifs dans chacune. Mais ce que j'ai obtenu est exactement la courbe ROC pour la prédiction probabiliste de l'arbre. Cela signifie que vous ne pouvez pas surpasser l'arbre en cueillant à la main ses feuilles en fonction des fréquences cibles dans l'ensemble d'entraînement.
Vous pouvez vous détendre et continuer à utiliser la prédiction probabiliste ordinaire :)