将连续模型概率分数转换为分类评级

时间:2018-03-11 08:24:52

标签: machine-learning probability xgboost

我有一个标准的xgboost分类模型已经过训练,现在可以预测概率分数。但是,为了使用户界面更简单,我想将此分数转换为5星评级方案。即离散得分。

什么是获得此量化阈值的智能方法,以便高评级代表具有高置信度的高概率分数?

例如,我正在考虑生成置信区间以及预测,并将高可信度高分组分为5星。高信心低分为1星。高信心中高分为4星等。

3 个答案:

答案 0 :(得分:1)

我为此研究了多种解决方案并制作了V0解决方案的原型。解决方案的主要要求如下:

  • 随着评级水平的提高(5星优于1星),误报的数量必须减少。

  • 用户不必手动定义分数概率的阈值,并自动导出阈值。

  • 阈值来自某些更高级别的业务要求。

  • 阈值来自标记数据,可以在找到新信息时重新获得。

考虑的其他解决方案:

  • 基于置信区间的评级。例如,您可以具有高预测分数0.9但低置信度(即大置信区间)和高预测分数0.9但高置信度(即小间隔)。我怀疑我们可能希望后者成为一个五星级的候选人,而前者可能是4 *?
  • 识别ROC曲线的凸度和凹度以识别最大值点
  • 使用Youden索引识别最佳点

最终解决方案 - 具有一组给定业务要求的样本ROC曲线(与每个星级相关联的FPR集合)然后转换为阈值。 注意:这有效,但假设有些单调的精度曲线,并非总是如此。我通过将问题制定为优化问题来改进解决方案,其中评级阈值是自由度,而目标函数是每个评级桶之间的转换率的线性。我相信你可以尝试不同的目标函数,但为了我的目的,这非常有效。

参考文献:

原型解决方案:

import numpy as np
import pandas as pd
# The probas and fpr/tpr/thresholds come from the roc curve.
probas_ = xgb_model_copy.fit(features.values[train], label.values[train]).predict_proba(features.values[test])
# Compute ROC curve and area the curve
fpr, tpr, thresholds = roc_curve(label.values[test], probas_[:, 1])

fpr_req = [0.01, 0.3, 0.5,0.9]
def find_nearest(array,value):
    idx = (np.abs(array-value)).argmin()
    return idx

fpr_indexes = [find_nearest(fpr, fpr_req_val) for fpr_req_val in fpr_req]
star_rating_thresholds = thresholds[fpr_indexes]
star_rating_thresholds = np.append(np.append([1],star_rating_thresholds),[0])
candidate_ratings = pd.cut(probas_,
star_rating_thresholds[::-1], labels=[5,4,3,2,1],right=False,include_lowest=True)

star_rating_thresolds
array([1. , 0.5073538 , 0.50184137, 0.5011086 , 0.4984425 ,
0. ])
candidate_ratings
[5, 5, 5, 5, 5, ..., 2, 2, 2, 2, 1]
Length: 564
Categories (5, int64): [5 < 4 < 3 < 2 < 1]

答案 1 :(得分:0)

您可以使用Pandas.cut()方法:

In [62]: np.random.seed(0)

In [63]: a = np.random.rand(10)

In [64]: a
Out[64]: array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 , 0.64589411, 0.43758721, 0.891773  , 0.96366276, 0.38344152])

In [65]: pd.cut(a, bins=np.linspace(0, 1, 6), labels=[1,2,3,4,5])
Out[65]:
[3, 4, 4, 3, 3, 4, 3, 5, 5, 2]
Categories (5, int64): [1 < 2 < 3 < 4 < 5]

更新: @EranMoshe has added an important point - "you might want to normalize your output before cutting it into categorical values"

演示:

In [117]: a
Out[117]: array([0.6 , 0.8 , 0.85, 0.9 , 0.95, 0.97])

In [118]: pd.cut(a, bins=np.linspace(a.min(), a.max(), 6),
                 labels=[1,2,3,4,5], include_lowest=True)
Out[118]:
[1, 3, 4, 5, 5, 5]
Categories (5, int64): [1 < 2 < 3 < 4 < 5]

答案 2 :(得分:0)

假设存在分类问题:either 1's or 0's

在计算ROC曲线的AUC时,您可以对&#34;事件&#34;进行排序。通过您的模型预测。因此,在顶部,您很可能会有很多1,并且您在该排序列表中走得更远,更多的是0。

现在让我们假设您尝试确定得分"5"的阈值。 您可以计算您愿意承受的数据中0的相对百分比。

鉴于下表:

item   A    score
1      1    0.99
2      1    0.92
3      0    0.89
4      1    0.88
5      1    0.74
6      0    0.66
7      0    0.64
8      0    0.59
9      1    0.55

如果我希望"user score" "5"有0%误报,我会确定&#34; 5&#34;高于0.89

如果我可以容忍10%的误报,我会确定阈值高于0.66

您可以针对每个阈值执行相同的操作。

在我看来,这是一个100%的商业决策,选择这些门槛的最明智的方法是根据您对用户的了解。

如果用户希望"5"能够完美地预测班级(生死攸关的情况),请使用0%误报。