toad评分卡构建与改写问题

我用toad包构建了一个评分卡模型,我想对他进行改造,我把里面用的逻辑回归模型换成了别的模型,但是我发现不管我运不运行这个a模型,toad都可以直接出一个评分卡结果,难道我这个改写是错误的吗?toad是内置的逻辑回归,我是没法简单改写吗?



import pandas as pd
train=pd.read_csv("训练集.csv",index_col=0)
test=pd.read_csv("测试集.csv",index_col=0)

Xtr=train.loc[:,"ficoRangeLow":"n14"]
Ytr=train.loc[:,"isDefault"]

Xts=test.loc[:,"ficoRangeLow":"n14"]
Yts=test.loc[:,"isDefault"]


data_tr = pd.concat([Xtr,Ytr],axis=1)
data_tr['type'] = 'train'

data_ts = pd.concat([Xts,Yts],axis=1)
data_ts['type'] = 'test'
import toad
toad.detector.detect(data_tr).columns
toad.detector.detect(data_tr)

quality = toad.quality(data_tr,'isDefault',iv_only=True)
quality.sort_values('iv',ascending=False)


selected_data, dropped = toad.selection.select(data_tr,target = 'isDefault', empty = 0.5, iv = 0.02, corr = 0.9, return_drop=True,exclude=['type'])
print(dropped)
print(selected_data.shape)



quality = toad.quality(selected_data,'isDefault',iv_only=True)
quality.sort_values('iv',ascending=False)



ivzhi=quality.sort_values('iv',ascending=False)
ivzhi.to_csv("iv值排序.csv")


combiner = toad.transform.Combiner()
combiner.fit(selected_data, y = 'isDefault', method = 'chi', min_samples = 0.05) #empty_separate = False


from toad.plot import bin_plot
for i in range(0,14,1):
    col = selected_data.columns[i]
    bin_plot(combiner.transform(selected_data[[col,'isDefault']], labels=True), x=col, target='isDefault')


bins = combiner.export()
selected_test = data_ts[selected_data.columns]
combiner.set_rules(bins)
binned_data = combiner.transform(selected_data)
transer = toad.transform.WOETransformer()
data_tr_woe = transer.fit_transform(binned_data, binned_data['isDefault'], exclude=['isDefault','type'])
data_ts_woe = transer.transform(combiner.transform(selected_test))
Xtr_woe = data_tr_woe.drop(['isDefault','type'],axis=1)
Ytr_woe = data_tr_woe['isDefault']
Xts_woe = data_ts_woe.drop(['isDefault','type'],axis=1)
Yts_woe = data_ts_woe['isDefault']

import autogluon
from autogluon.tabular import TabularDataset,TabularPredictor  
import pandas as pd
import numpy as np
label='isDefault'
train_data=TabularDataset(data_tr_woe.drop(["type"],axis=1)  )
metric = 'roc_auc'
time_limit=60
predictor=TabularPredictor(label=label,eval_metric=metric).fit(train_data,presets='best_quality',time_limit=time_limit,auto_stack=True)

test_data=TabularDataset(data_ts_woe.drop(['isDefault','type'],axis=1))

predictor.predict_proba(train_data)
train_proba=predictor.predict_proba(train_data)
train_proba=train_proba.values[:,1]
train_proba = np.array(train_proba).flatten() 

predictor.predict_proba(test_data)
auto_proba=predictor.predict_proba(test_data)
auto_proba=auto_proba.values[:,1]
auto_proba = np.array(auto_proba).flatten() 

psi = toad.metrics.PSI(data_tr_woe,data_ts_woe)
psi.sort_values(0,ascending=False)

psizhi=psi.sort_values(0,ascending=False)
psizhi.to_csv("psi值.csv")


tr_bucket = toad.metrics.KS_bucket(train_proba,Ytr,bucket=10,method='quantile')
tr_bucket


selected_data
x_card=selected_data.loc[:,"ficoRangeLow":"n14"]
y_card=selected_data.loc[:,"isDefault"]

card = ScoreCard(combiner=combiner, 
                 transer=transer, 
                 C=0.1, 
                 class_weight='balanced', 
                 base_score=600,
                 base_odds=1,
                 pdo=50,
                 rate=2)
 
# 使用评分卡模型进行拟合
card.fit(x_card,y_card)


最后评分卡生成的这一步和我上面调试的模型没有任何关系,请问该如何改写才能让评分卡的构建基于我的模型。

toad对于模型的改造收不容易的,因为逻辑回归模型才带.coef_,你必须得根据线性模型才能应用于评分卡。你可以结合以下逻辑回归模型与自动机器学习,这样容易改。

“Devil组”引证GPT后的撰写:

  • 评分卡的构建过程中使用了 toad.scorecard.ScoreCard 类,其中 combiner 和 transer 分别指定了变量筛选和转换的函数,而 C、class_weight、base_score、base_odds、pdo 和 rate 则是评分卡模型的超参数。该类内置了逻辑回归模型进行评分卡的构建。
  • 如果想将评分卡的构建基于自己的模型,则需要定义一个评分卡类并重写其中的方法。评分卡通常包含三个主要部分:变量筛选、变量转换和分数分配。,要根据自己的模型重写分数分配的方法。例如,如果模型是随机森林分类器,则可以根据随机森林分类器的预测结果分配分数。

以下是一个简单的示例代码,展示如何重写 ScoreCard 类的 score 方法,以便基于自己的模型生成评分卡。

from toad.scorecard import ScoreCard
import numpy as np

class CustomScoreCard(ScoreCard):
    
    def __init__(self, combiner, transer, model, **kwargs):
        super().__init__(combiner=combiner, transer=transer, **kwargs)
        self.model = model
        
    def score(self, x):
        p = self.model.predict_proba(x)[:, 1]
        odds = p / (1 - p)
        score = self.base_score - self.pdo / np.log(2) * np.log(odds / self.base_odds)
        return score


定义了一个名为 CustomScoreCard 的评分卡类,该类继承自 ScoreCard 类。通过 init 方法添加了一个新的参数 model,该参数用于传入我们自己的模型。然后,重写了 score 方法,将其基于模型生成分数。

使用这个新的类,可以像这样创建一个评分卡对象:

from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(n_estimators=100, max_depth=5)
model.fit(x_train, y_train)

card = CustomScoreCard(combiner=combiner, 
                       transer=transer, 
                       model=model, 
                       base_score=600,
                       base_odds=1,
                       pdo=200,
                       rate=2)
card.fit(x_card, y_card)


使用了随机森林分类器作为我们的模型,并将其传递给了自定义的评分卡类。然后,用这个新的评分卡对象 card 进行评分卡的构建。

参考chatGPT的回答内容和自己的思路,以下是一个示例代码,用于使用一个自定义模型(这里以随机森林为例)来构建评分卡。代码中使用的数据集是一个虚构的信用评分数据集,其中包含一些关于客户信用评分的特征和目标变量。评分卡基于模型预测概率和基础分、PDO、比率和分数区间等参数进行计算。

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from toad.scorecard import ScoreCard, Binning
from toad.metrics import KS, F1_score

# 读取数据集
data = pd.read_csv('credit_score.csv')

# 将数据集划分为训练集和测试集
train = data.sample(frac=0.7, random_state=123)
test = data.drop(train.index)

# 定义用于评分卡构建的变量
var_list = ['age', 'income', 'debt_ratio', 'revolving_utilization', 'dependents']

# 使用随机森林模型训练数据集
rf_model = RandomForestClassifier(n_estimators=50, random_state=123)
rf_model.fit(train[var_list], train['target'])

# 在测试集上进行预测
test['prob'] = rf_model.predict_proba(test[var_list])[:, 1]

# 使用分箱将连续变量离散化
binning = Binning()
binning.fit(train[var_list], train['target'])
train_binned = binning.transform(train[var_list])
test_binned = binning.transform(test[var_list])

# 构建评分卡
combiner = lambda x: sum(x)
transer = lambda x: np.log(x)
card = ScoreCard(combiner=combiner, 
                 transer=transer, 
                 C=0.1, 
                 class_weight='balanced', 
                 base_score=600,
                 base_odds=1,
                 pdo=50,
                 rate=2)
card.fit(train_binned, train['target'])

# 计算评分卡的表现
train['score'] = card.predict(train_binned)
test['score'] = card.predict(test_binned)
print('Train KS:', KS(train['target'], train['score']))
print('Test KS:', KS(test['target'], test['score']))
print('Train F1:', F1_score(train['target'], train['score']))
print('Test F1:', F1_score(test['target'], test['score']))

在上述代码中,我们首先使用随机森林模型对训练数据集进行训练,并在测试集上进行预测。然后,我们使用分箱将连续变量离散化,并使用 ScoreCard 函数构建评分卡。最后,我们计算评分卡的表现,并输出结果。

该回答引用ChatGPT

Toad包提供了一个方便的方法来构建评分卡,但是默认情况下使用逻辑回归模型。如果你想使用其他的模型来构建评分卡,你需要提供一些额外的参数来指定你想要使用的模型,以及如何进行转换和组合。

假设你已经训练了一个分类器,比如随机森林或者XGBoost,现在你想使用这个模型来构建评分卡,你需要按照以下步骤来进行修改:

创建一个函数,用来将模型的预测概率转换为分数。这个函数应该接受一个numpy数组作为输入,返回一个numpy数组作为输出。这个函数的目的是将模型的预测概率映射到一个分数上,这个分数可以用来评估一个客户的信用风险等级。

创建一个函数,用来将特征转换为模型可以处理的格式。这个函数应该接受一个pandas DataFrame作为输入,返回一个numpy数组作为输出。这个函数的目的是将输入数据转换为模型可以接受的格式,通常是将分类变量进行独热编码,将数值变量进行缩放等操作。

创建一个函数,用来组合模型的预测结果。这个函数应该接受一个numpy数组作为输入,返回一个numpy数组作为输出。这个函数的目的是将多个模型的预测结果组合起来,形成最终的预测结果。

使用上面的函数,创建一个ScoreCard对象,并指定你想要使用的模型、转换函数和组合函数。例如:


from toad.scorecard import ScoreCard 
from sklearn.ensemble import RandomForestClassifier

# Create conversion function and combiner function
def convert(X):
    # Your conversion code here
    return X

def combine(X):
    # Your combination code here
    return X

# Create scorecard object
card = ScoreCard(
    model=RandomForestClassifier(), 
    combiner=combine, 
    transer=convert, 
    C=0.1, 
    class_weight='balanced', 
    base_score=600,
    base_odds=1,
    pdo=200,
    rate=2
)

# Fit scorecard object to data
card.fit(X, y)

在上面的代码中,我们指定了一个随机森林模型作为评分卡的模型,并创建了两个函数来处理数据的转换和组合。然后我们将这些函数作为参数传递给ScoreCard对象,并使用fit方法来拟合评分卡模型。注意,在这个例子中,我们没有指定任何的评分卡分数转换函数,因为我们使用的是随机森林模型,其输出已经是一个概率,可以直接用来计算分数。

参考GPT和自己的思路,Toad中的评分卡模型是基于逻辑回归模型的,但是你可以通过重写Toad中的转换函数,将模型转换为其他模型,例如支持向量机模型或决策树模型。

以下是一个示例代码,它将逻辑回归模型替换为支持向量机模型:

from sklearn.svm import SVC
from toad.transform import WOETransformer
from toad.combiner import ModelCombiner
from toad.scorecard import ScoreCard

# 假设你的模型是支持向量机模型
model = SVC(probability=True)

# 假设你已经训练好了你的模型,并可以使用它进行预测
X_test = ...
y_pred = model.predict(X_test)
y_pred_prob = model.predict_proba(X_test)[:, 1]

# 定义转换函数
transer = WOETransformer()

# 定义组合器
combiner = ModelCombiner(model=model)

# 定义评分卡模型
card = ScoreCard(combiner=combiner, 
                 transer=transer, 
                 C=0.1, 
                 class_weight='balanced', 
                 base_score=600,
                 base_odds=1,
                 pdo=200,
                 rate=2)

# 使用评分卡模型进行拟合
card.fit(X_train, y_train)

# 使用评分卡模型进行预测
y_score = card.predict(X_test)



在此示例中,我们使用支持向量机模型替换了逻辑回归模型。我们还定义了适当的转换器和组合器,并使用评分卡模型进行拟合和预测。请注意,评分卡模型是一种解释性模型,它使用WOE(权重分箱)进行转换。因此,在使用其他模型时,您可能需要重新定义转换器,以便它使用适当的转换方法,例如分位数分箱或自适应分箱等。

你把源码发给我看一下

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先需要注意的是,评分卡的构建不仅仅依赖于机器学习/统计模型,还包括变量筛选、特征工程、WOE转换等环节。因此,只是将逻辑回归模型替换成别的模型是无法保证评分卡的准确性的。建议你先了解评分卡的基本构建流程和要点。

针对你的问题,如果想要基于自己训练的模型构建评分卡,可以考虑以下步骤:

  1. 定义分箱方法、分箱后的分数映射关系,比如定义一个存放每个分箱内部相对于基础分数的得分偏移量的字典。

  2. 对测试数据进行分箱,并按照第一步定义的分数映射关系将每个分箱的得分映射成总分。

下面是一个示例代码,假设我们有一个自定义的分类器clf:


# 假设x_test是测试数据集
y_pred = clf.predict(x_test) # 预测分类结果

# 假设`bins`, `woe_map`是第一步定义的分箱方法和分数映射关系
binning_info = toad.transform.Bins(x_test, y_pred, method=bins)

# 计算每个分箱的得分偏移量
score_card = {}
for i, col in enumerate(x_test.columns):
    bins, labels = binning_info[i]
    for j, label in enumerate(labels):
        if label in woe_map['group']:
            score = woe_map[woe_map['group']==label]['score'].iloc[0]
        else:
            score = 0
        score_card[(col, j)] = score

# 对每行数据按照每个变量的分箱结果计算总分
total_score = []
for i in range(len(x_test)):
    score = 0
    for j, col in enumerate(x_test.columns):
        bins, labels = binning_info[j]
        label = labels[np.searchsorted(bins, x_test[col].iloc[i])-1]
        score += score_card[(col, label)]
    total_score.append(score)

# total_score 就是每行数据的评分结果

需要注意的是,以上代码与评分卡相关的一些细节没有涉及到,仅仅是提供了一个思路。如果想要更准确地构建评分卡,建议参考相关资料或者借助第三方工具库。
如果我的回答解决了您的问题,请采纳!

该回答引用GPTᴼᴾᴱᴺᴬᴵ
Toad是一个功能强大的数据分析工具,其中的评分卡功能可以使用不同的机器学习模型进行评分卡构建,包括逻辑回归、决策树等。
-
如果您想要将逻辑回归模型替换为其他模型,需要修改combiner和transer参数。combiner参数定义了如何将模型的特征系数转换为评分卡得分,而transer参数定义了如何将原始数据进行转换以适应模型。具体地说,您需要将这两个参数调整为与您新模型兼容的函数。
-
举个例子,如果您使用的是支持向量机模型,可以使用如下代码进行评分卡构建:

from sklearn.svm import SVC
from toad.scorecard import ScoreCard 

svm = SVC(kernel='linear')
svm.fit(X_train, y_train)

combiner = lambda x: x * 10
transer = lambda x: x
card = ScoreCard(combiner=combiner, 
                 transer=transer, 
                 C=0.1, 
                 class_weight='balanced', 
                 base_score=600,
                 base_odds=1,
                 pdo=200,
                 rate=2)  
card.fit(X_train, y_train)


在这个例子中,我们使用支持向量机模型来构建评分卡,而combiner和transer参数分别被设置为常数函数和恒等函数。这样,即可生成一个基于SVM模型的评分卡。

需要注意的是,评分卡的生成过程中,模型的选择和参数的调整都会影响最终的评分卡结果,因此需要谨慎选择合适的模型和参数。同时,评分卡的生成过程也需要参考具体的业务场景和需求,才能得出有效的评分卡。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^