我正在使用(并喜欢)TPOT,但是在实现自定义P @ K计分器时遇到了麻烦。假设我想在100个预测(或任意数量的K)中拥有尽可能多的真实肯定,那么如何编码呢?我已经尝试使用下面的代码,但是尽管标准记分器没有错误,但仍然出现错误,指出尚未安装管道。
def pak(actual, predicted):
k = 100
if len(predicted) > k:
predicted = predicted[:k]
score = 0.0
num_hits = 0.0
for i, p in enumerate(predicted):
if p in actual and p not in predicted[:i]:
num_hits += 1.0
score += num_hits / (i + 1.0)
if not actual:
return 0.0
return score / min(len(actual), k)
my_custom_scorer = make_scorer(pak, greater_is_better=True)
答案 0 :(得分:2)
我不建议您这样做(请参阅最后的讨论),但是基于我的理解,您想最大化真实阳性的数量。因此,您要创建一个自定义计分器并使用TPOT优化真实的阳性率。我优化了您的函数,因为它取决于给定的数字k
。如果您仅计算真实的阳性率,就可以避免这种情况。我使用了sklearn的示例数据集,当然可以将其替换为任何其他数据集。
import numpy as np
import sklearn
from sklearn.metrics import make_scorer
import tpot
from tpot import TPOTClassifier
from sklearn.model_selection import train_test_split
def maximize_true_pos(y, y_pred):
# true positives are marked with ones, all others with zeros
true_pos = np.where((y==1) & (y_pred == 1), 1, 0)
# sum true positives
num_true_pos = np.sum(true_pos)
# determine the true positive rate, how many of the positives were found?
true_pos_div_total_tp = num_true_pos/np.sum(y)
return true_pos_div_total_tp
iris = sklearn.datasets.load_breast_cancer()
# create the custom scorer
max_true_pos_scorer = make_scorer(maximize_true_pos)
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target,
train_size=0.75, test_size=0.25)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
tpot = TPOTClassifier(verbosity=2, max_time_mins=2, scoring=max_true_pos_scorer)
tpot.fit(X_train, y_train)
y_pred = tpot.predict(X_test)
现在,通过查看y_pred
,我们来了解优化的地方。
y_pred
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
由于我们只想优化真实阳性的数量,因此该算法了解到不会误判阳性,因此将所有内容都设置为1
类(尽管y_true
并不总是1
,因此准确性<1)。取决于您的用例召回(找到了多少个带有正标记的案例)或精度(有多少个带有正标记的案例是相关的)比简单地让算法学习它应该将所有内容标记为肯定的更好。
要使用精度或召回率(您可能知道,但出于完整性考虑,我还是将其放在此处),可以按以下方式简单地将"precision"
或"recall"
用作评分参数:
TPOTClassifier(scoring='recall')