XGBoost模型支持自定义评价函数和损失函数。只要保证损失函数二阶可导,通过评价函数的最大化既可以对模型参数进行求解。实际使用中,可以考虑根据业务目标对这两者进行调整。
举个例子,假设现在有一个提额模型,用处是将分数最高的20%客户给与更高的额度。也就是期望分数最高的20%的客群正样本捕获率最大化。可能在保证上述前提,同时保证模型对正负样本有一定的区分能力。所以可以改写一个保证模型区分度,同时又能优化局部正样本捕获率的评价函数。
自定义XGBoost模型损失函数与评价函数。
# 自定义对数损失函数
def loglikelood(preds, dtrain):
labels = dtrain.get_label()
preds = 1.0 / (1.0 + np.exp(-preds))
grad = preds - labels
hess = preds * (1.0-preds)
return grad, hess
# 评价函数:前20%正样本占比最大化
def binary_error(preds, train_data):
labels = train_data.get_label()
dct = pd.DataFrame({'pred':preds,'percent':preds,'labels':labels})
#取百分位点对应的阈值
key = dct['percent'].quantile(0.2)
#按照阈值处理成二分类任务
dct['percent']= dct['percent'].map(lambda x :1 if x <= key else 0)
#计算评价函数,权重默认0.5,可以根据情况调整
result = np.mean(dct[dct.percent== 1]['labels'] == 1)*0.5
+ np.mean((dct.labels - dct.pred)**2)*0.5
return 'error',result
watchlist = [(dtest,'eval'), (dtrain,'train')]
param = {'max_depth':3, 'eta':0.1, 'silent':1}
num_round = 100
# 自定义损失函数训练
bst = xgb.train(param, dtrain, num_round, watchlist, loglikelood, binary_error)
可以看到评价函数由两部分组成,第一部分权重默认为0.5,目的是使得前20%样本中的正样本占比最大。因为正样本的标签为0,因此pandas.quantile()函数分位点参数0.2,表示预估为正样本概率最大的前20%分位点。第二部分权重同样默认设置为0.5,目的是让模型对正负样本的识别能力得到保障。
实际使用中,可以根据,对模型表现的侧重点,进行权重选择。比如当更希望模型关注于捕获率时,可以调整第一部分权重为0.8,将第二部分权重调整为0.2。本书给出的是一种启发性的思路,读者还可以根据实际情况改写更贴合业务的损失函数。
LightGBM中也同样支持自定义损失函数和评价函数。代码上有一些细微差别。评价函数需要返回三部分,用False代替。
# 自定义二分类对数损失函数
def loglikelood(preds, train_data):
labels = train_data.get_label()
preds = 1. / (1. + np.exp(-preds))
grad = preds - labels
hess = preds * (1. - preds)
return grad, hess
# 自定义前20%正样本占比最大化的评价函数
def binary_error(preds, train_data):
labels = train_data.get_label()
dct = pd.DataFrame({'pred':preds,'percent':preds,'labels':labels})
#取百分位点对应的阈值
key = dct['percent'].quantile(0.2)
#按照阈值处理成二分类任务
dct['percent']= dct['percent'].map(lambda x :1 if x <= key else 0)
#计算评价函数,权重默认0.5,可以根据情况调整
result = np.mean(dct[dct.percent== 1]['labels'] == 1)*0.9 + np.mean((dct.labels - dct.pred)**2)*0.5
return 'error',result, False
gbm = lgb.train(params,
lgb_train,
num_boost_round=100,
init_model=gbm,
fobj=loglikelood,
feval=binary_error,
valid_sets=lgb_eval)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。