amphibian-dev / toad

ESC Team's credit scorecard tools.
https://toad.readthedocs.io
MIT License
474 stars 173 forks source link

分箱边界inf的可能bug #109

Closed FrankDataAnalystPython closed 1 year ago

FrankDataAnalystPython commented 1 year ago

在使用toad的combiner的过程中,需要尝试对某个特征来做单调性的检验。看下分出的bins的badrate是否可以呈现出单调的趋势。

在某些业务中,期望bins的结果不仅仅单调,且是正向单调,比如,业务中期望引入哑变量的信息,期望哑变量所在的bins一直是风险最低的。所以在设置bins的range的时候,需要反过来设置。

比如说,原来的combiner给出的结果是[14, 16, 22, 28], 图中从左到右看是下降的单调趋势。为了尝试变成上升的趋势,最简单的一个做法是反过来设置[28, 22, 16, 14]。效果也是差不多的,代码如下(此部分代码是基于toad的pipeline分支)

import os
import numpy as np
import pytest
import pandas as pd
from os.path import join
from toad.pipeline import Toad_Pipeline
from sklearn.model_selection import train_test_split, KFold, GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer

lb  = load_breast_cancer()
X = pd.DataFrame(lb['data'], columns=lb['feature_names'])
Y = lb['target']
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.3, random_state=42)

toad_pipe = Toad_Pipeline()
update_dict = {
    'mean texture' : [28, 22, 16, 14]
}
params = {
    'combiner__update_rules' : update_dict,
}
toad_pipe = toad_pipe.set_params(**params)
toad_pipe = toad_pipe.fit(Xtrain, Ytrain)
Xtrain_ = toad_pipe.transform(Xtrain)

toad_pipe.combiner.export()['mean texture']

但是在ScoreCard或者画图的过程中,给出了比较奇怪的结果

from toad import ScoreCard

card = ScoreCard(
    combiner=toad_pipe.combiner,
    transer=toad_pipe.woe
)

card = card.fit(Xtrain_, Ytrain)
card.export()['mean texture']
{'[-inf ~ 28)': 11.13,
 '[28 ~ 22)': 114.55,
 '[22 ~ 16)': 30.44,
 '[16 ~ 14)': -60.49,
 '[14 ~ inf)': -136.98}

可以看到,代码好像默认了第一个bins的最左边是-inf,最后一个bins的最右边是inf。

所以这里可能有两种解决方案。

  1. combiner在重制dict的时候,强行的只允许,单调递增的数组
  2. 在最后的bins输出的结果中,大致判断一下数组的如果单调递减, -inf和inf的位置做互换
Secbone commented 1 year ago

@FrankDataAnalystPython 这里在最初设计的时候就是定义切割点数组是递增序列,不过可能当时没有加这个检查,后续我补一下。 至于分箱的排序问题,我个人建议还是保持原有数据的排序,即 X轴都是从小到大,这样不太容易引起歧义

FrankDataAnalystPython commented 1 year ago

@FrankDataAnalystPython 这里在最初设计的时候就是定义切割点数组是递增序列,不过可能当时没有加这个检查,后续我补一下。 至于分箱的排序问题,我个人建议还是保持原有数据的排序,即 X轴都是从小到大,这样不太容易引起歧义

赞同赞同,估计后续加一个检查即可