如何在Python中构建提升图(又称收益图)?

我刚刚使用scikit-learn创建了一个模型,该模型估计客户对某项优惠做出响应的概率。现在我想评估我的模型。为此,我想绘制提升图。我理解提升的概念,但我在Python中实际实现它时遇到了困难。


回答:

提升/累积收益图并不是评估模型的好方法(因为它不能用于模型之间的比较),而是评估结果的一种方式,特别是在资源有限的情况下。无论是因为每个结果的行动成本(在市场营销场景中),还是因为你想忽略一定数量的确定选民,只对那些犹豫不决的人采取行动。当你的模型非常好,并且对所有结果都有很高的分类准确性时,通过按置信度排序结果,你不会获得太多的提升。

import sklearn.metricsimport pandas as pddef calc_cumulative_gains(df: pd.DataFrame, actual_col: str, predicted_col:str, probability_col:str):    df.sort_values(by=probability_col, ascending=False, inplace=True)    subset = df[df[predicted_col] == True]    rows = []    for group in np.array_split(subset, 10):        score = sklearn.metrics.accuracy_score(group[actual_col].tolist(),                                                   group[predicted_col].tolist(),                                                   normalize=False)        rows.append({'NumCases': len(group), 'NumCorrectPredictions': score})    lift = pd.DataFrame(rows)    #Cumulative Gains Calculation    lift['RunningCorrect'] = lift['NumCorrectPredictions'].cumsum()    lift['PercentCorrect'] = lift.apply(        lambda x: (100 / lift['NumCorrectPredictions'].sum()) * x['RunningCorrect'], axis=1)    lift['CumulativeCorrectBestCase'] = lift['NumCases'].cumsum()    lift['PercentCorrectBestCase'] = lift['CumulativeCorrectBestCase'].apply(        lambda x: 100 if (100 / lift['NumCorrectPredictions'].sum()) * x > 100 else (100 / lift[            'NumCorrectPredictions'].sum()) * x)    lift['AvgCase'] = lift['NumCorrectPredictions'].sum() / len(lift)    lift['CumulativeAvgCase'] = lift['AvgCase'].cumsum()    lift['PercentAvgCase'] = lift['CumulativeAvgCase'].apply(        lambda x: (100 / lift['NumCorrectPredictions'].sum()) * x)    #Lift Chart    lift['NormalisedPercentAvg'] = 1    lift['NormalisedPercentWithModel'] = lift['PercentCorrect'] / lift['PercentAvgCase']    return lift

要绘制累积收益图,你可以使用下面的代码。

    import matplotlib.pyplot as plt    def plot_cumulative_gains(lift: pd.DataFrame):        fig, ax = plt.subplots()        fig.canvas.draw()            handles = []        handles.append(ax.plot(lift['PercentCorrect'], 'r-', label='Percent Correct Predictions'))        handles.append(ax.plot(lift['PercentCorrectBestCase'], 'g-', label='Best Case (for current model)'))        handles.append(ax.plot(lift['PercentAvgCase'], 'b-', label='Average Case (for current model)'))        ax.set_xlabel('Total Population (%)')        ax.set_ylabel('Number of Respondents (%)')            ax.set_xlim([0, 9])        ax.set_ylim([10, 100])            labels = [int((label+1)*10) for label in [float(item.get_text()) for item in ax.get_xticklabels()]]            ax.set_xticklabels(labels)            fig.legend(handles, labels=[h[0].get_label() for h in handles])        fig.show()

要可视化提升图:

    def plot_lift_chart(lift: pd.DataFrame):        plt.figure()        plt.plot(lift['NormalisedPercentAvg'], 'r-', label='Normalised \'response rate\' with no model')        plt.plot(lift['NormalisedPercentWithModel'], 'g-', label='Normalised \'response rate\' with using model')        plt.legend()        plt.show()

结果看起来像这样:

Cumulative Gains Chart

我发现这些网站对参考很有用:

编辑:

我发现微软链接的描述有些误导,但Paul Te Braak的链接非常有信息量。为了回答评论;

对于上面的累积收益图,所有的计算都是基于该特定模型的准确性。正如Paul Te Braak链接所指出的,我的模型的预测准确性如何达到100%(图表中的红线)?最佳情况(绿线)是我们能多快达到红线在整个总体中实现的相同准确性(例如,我们的最佳累积收益情景)。蓝色是如果我们只是随机选择总体中每个样本的分类。所以累积收益和提升图完全是用来理解该模型(仅该模型)在不与整个总体互动的情况下如何给我带来更多影响的工具。

我使用累积收益图的一个场景是欺诈案例,我想要知道我们可以忽略或优先处理多少申请(因为我知道模型对它们的预测尽可能准确)对于前X百分比。在这种情况下,对于“平均模型”,我反而从真实的无序数据集中选择分类(以显示现有申请是如何被处理的,以及如何使用模型,我们可以优先处理某些类型的申请)。

因此,对于比较模型,只需使用ROC/AUC,一旦你对选择的模型满意,就使用累积收益/提升图来查看它对数据的反应。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注