如果我正确理解了这个问题,那么您已经训练了一种算法,可以将您的数据拆分为ñ不相交的集群。现在您要分配预测1到集群的某个子集,以及0对他们其余的人。在这些子集中,您希望找到帕累托最优的子集,即在给定固定数量的阳性预测的情况下最大化真阳性率的那些(这相当于固定 PPV)。这是正确的吗?
这听起来很像背包问题!集群大小是“权重”,集群中正样本的数量是“值”,您希望用尽可能多的值填充固定容量的背包。
背包问题有几种寻找精确解的算法(例如通过动态规划)。但是一个有用的贪婪解决方案是按降序对集群进行排序价值_ _ _ _我们_ _ _ht _ (即正样本的份额),取第一个 ķ. 如果你拿ķ 从 0 到 ñ,您可以非常便宜地绘制您的 ROC 曲线。
如果你分配 1 到第一个 k - 1 簇和随机分数 p ∈ [ 0 , 1 ] 样本中的 ķth cluster,你得到了背包问题的上限。有了这个,您可以绘制 ROC 曲线的上限。
这是一个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();
此代码将为您绘制一张漂亮的图片:

蓝点是所有的 (FPR, TPR) 元组 210 子集,红线连接(FPR,TPR)的帕累托最优子集。
现在有点盐:您根本不必为子集而烦恼!我所做的是按每个树叶中正样本的比例对树叶进行排序。但我得到的正是树概率预测的 ROC 曲线。这意味着,您不能通过根据训练集中的目标频率手动挑选叶子来超越树。
您可以放松并继续使用普通的概率预测:)