加了权重样本的AUC如何计算?对理解roc_auc_score函数里sample_weight参数以及xgb模型赋予样本权重再评估都有帮助哦~
一、
roc_auc_score函数中有个参数是sample_weight,可以给样本设置权重。一直不太理解加上weight怎么来计算AUC,先放个可选参数插图康康。
二、
直到有一天,我不得不面对这个问题。起因竟然是比较熟悉的xgboost(其实是硬往自己脸上贴金了额)。
在训练xgboost的时候,xgb.DMatrix()函数里有个weight的参数,可以给样本设置权重,这样xgb就可以在设置了权重的样本集上训练啦。可是打印出来的logloss和auc是在加权了的数据集上计算出来的吗?怎么计算出来的?
只要DMatrix()函数里设置了weight参数,打印出来的metric都是在加了权重的数据集上计算出来的。先放个代码,放个打印出来的logloss和auc康康:
params = {
'booster': 'gbtree',
'objective': 'binary:logistic',
'metric':['auc','logloss'],
'eval_metric':['auc','logloss'],
'max_depth':5,
'min_child_weight':500,
'gamma':0.1,
'eta':0.02
}
weights_train=[1]*20000+[3]*5755#瞎设置的哈哈哈
weights_valid=[1]*4000+[3]*2440#瞎设置的哈哈哈
dtrain=xgb.DMatrix(data=X_train,label=y_train,weight=weights_train)#训练集加上权重训练了,在这个实验中训练集加不加权重其实无所谓的
dvalid=xgb.DMatrix(data=X_valid,label=y_valid) #dvalid是没有加权重的
dvalid_weight=xgb.DMatrix(data=X_valid,label=y_valid,weight=weights_valid) #dvalid_weight是加上权重的
xgbM = xgb.train(params=params, dtrain=dtrain, num_boost_round=200,evals=[(dtrain, 'train'),(dvalid,'valid'),(dvalid_weight,'dvalid_weight')],verbose_eval=10)
# 打印出来的结果,和上边的代码放到一起了
[0] train-auc:0.641996 train-logloss:0.691894 valid-auc:0.630333 valid-logloss:0.692002 dvalid_weight-auc:0.627448 dvalid_weight-logloss:0.69202
[10] train-auc:0.66727 train-logloss:0.681568 valid-auc:0.64835 valid-logloss:0.682969 dvalid_weight-auc:0.648128 dvalid_weight-logloss:0.682991
[20] train-auc:0.675196 train-logloss:0.673523 valid-auc:0.655988 valid-logloss:0.676026 dvalid_weight-auc:0.656417 dvalid_weight-logloss:0.675993
[30] train-auc:0.684573 train-logloss:0.666594 valid-auc:0.662995 valid-logloss:0.670258 dvalid_weight-auc:0.66354 dvalid_weight-logloss:0.670276
[40] train-auc:0.690524 train-logloss:0.660946 valid-auc:0.668417 valid-logloss:0.665506 dvalid_weight-auc:0.669053 dvalid_weight-logloss:0.66552
[50] train-auc:0.694543 train-logloss:0.65606 valid-auc:0.67176 valid-logloss:0.661508 dvalid_weight-auc:0.672228 dvalid_weight-logloss:0.66154
[60] train-auc:0.69787 train-logloss:0.651922 valid-auc:0.674329 valid-logloss:0.658201 dvalid_weight-auc:0.674648 dvalid_weight-logloss:0.658267
[70] train-auc:0.701215 train-logloss:0.648284 valid-auc:0.678037 valid-logloss:0.655034 dvalid_weight-auc:0.678326 dvalid_weight-logloss:0.6551
[80] train-auc:0.70408 train-logloss:0.64509 valid-auc:0.680634 valid-logloss:0.652396 dvalid_weight-auc:0.681254 dvalid_weight-logloss:0.652361
[90] train-auc:0.707093 train-logloss:0.642096 valid-auc:0.682555 valid-logloss:0.650213 dvalid_weight-auc:0.683379 dvalid_weight-logloss:0.650129
[100] train-auc:0.70977 train-logloss:0.639381 valid-auc:0.68519 valid-logloss:0.647905 dvalid_weight-auc:0.686108 dvalid_weight-logloss:0.647798
[110] train-auc:0.712686 train-logloss:0.63678 valid-auc:0.687197 valid-logloss:0.64602 dvalid_weight-auc:0.688147 dvalid_weight-logloss:0.645902
[120] train-auc:0.71508 train-logloss:0.634466 valid-auc:0.689243 valid-logloss:0.644191 dvalid_weight-auc:0.690372 dvalid_weight-logloss:0.643994
[130] train-auc:0.717253 train-logloss:0.632345 valid-auc:0.690666 valid-logloss:0.642691 dvalid_weight-auc:0.691654 dvalid_weight-logloss:0.642531
[140] train-auc:0.719445 train-logloss:0.630243 valid-auc:0.691928 valid-logloss:0.641264 dvalid_weight-auc:0.692845 dvalid_weight-logloss:0.6411
[150] train-auc:0.721572 train-logloss:0.628253 valid-auc:0.693036 valid-logloss:0.639989 dvalid_weight-auc:0.693907 dvalid_weight-logloss:0.639838
[160] train-auc:0.723874 train-logloss:0.626385 valid-auc:0.694642 valid-logloss:0.638671 dvalid_weight-auc:0.695757 dvalid_weight-logloss:0.638446
[170] train-auc:0.726103 train-logloss:0.624491 valid-auc:0.695588 valid-logloss:0.637585 dvalid_weight-auc:0.696652 dvalid_weight-logloss:0.637376
[180] train-auc:0.728078 train-logloss:0.622813 valid-auc:0.696803 valid-logloss:0.636476 dvalid_weight-auc:0.698082 dvalid_weight-logloss:0.636165
[190] train-auc:0.729859 train-logloss:0.621344 valid-auc:0.697429 valid-logloss:0.635745 dvalid_weight-auc:0.698875 dvalid_weight-logloss:0.635403
[199] train-auc:0.731724 train-logloss:0.619909 valid-auc:0.698372 valid-logloss:0.634916 dvalid_weight-auc:0.699855 dvalid_weight-logloss:0.634549
模型预测dvalid和dvalid_weight,每次迭代过程中它两的logloss和auc均不相同。
logloss比较容易理解,可以计算所有样本的加权平均logloss。这个auc,怎么计算?
三、
一和二其实可以联系在一起啊。
xgboost计算加了权重的样本的auc,其实和给roc_auc_score函数的sample_weight参数赋予权重计算出来的auc是一样的结果。可以试试自定义一个metric函数试试,就biu一下主要的两行代码吧,这次打印出来的结果dvalid和dvalid_weight的auc就是一样的啦,小伙伴们可以亲自动手试一下。
def auc_weight(preds,dtrain): #preds是结果(概率值),dtrain是个带label的DMatrix
labels=dtrain.get_label() #提取label
return 'auc_weight',float(roc_auc_score(labels,preds,sample_weight=weights_valid))
xgbM = xgb.train(params=params, dtrain=dtrain, num_boost_round=200,evals=[(dvalid,'valid'),(dvalid_weight,'dvalid_weight')],verbose_eval=10,feval=auc_weight)#feval指定自定义评价函数
四、
最重要的部分来啦,给roc_auc_score函数的sample_weight参数赋予权重后,auc是怎么计算出来的呀。
大家还记得AUC的知识嘛?给大家po一篇blog,可以温习一下。https://blog.csdn.net/u013385925/article/details/80385873。
计算赋予权重数据的auc,其实就是把混淆矩阵里的计数改成权重加和,然后算TPR,FPR就好啦。这里举一个比较简单的例子
假设有6个样本,y_true=[1,1,1,0,0,0],y_score=[0.4,0.6,0.8,0.5,0.1,0.2],y_weight=[0.2,0.3,0.4,0.1,0.2,0.3]
(1),先来计算一下数据不加权重时的auc。
分割阈值从小到大来找到多组(FPR,TPR)作为坐标点,score>threshold时预测为1。
当分割阈值为0时:所有的样本都被预测为1,混淆矩阵如下,得到ROC曲线上的一点(1,1)
当阈值为0.1时,倒数第二个样本被预测为0,混淆矩阵如下,得到ROC曲线上的一点(2/3,1)
当阈值为0.2时,倒数第一个样本被预测为0,混淆矩阵如下,得到ROC曲线上的一点(1/3,1)
当阈值为0.4,0.5,0.6,0.8时依次类推,混淆矩阵就放在一起啦,得到ROC曲线上的(1/3,2/3),(0,2/3),(0,1/3),(0,0)点
将得到的七个点绘制出来,计算阴影面积,就是AUC的值啦,1*(2/3)+(2/3)*(1/3)=8/9
(2)、计算加了权重的auc
加了权重时,混淆矩阵中的数字就不是简单的计数啦,而是相应的样本权重的和。
得到了(1,1),(2/3,1),(1/6,1),(1/6,7/9),(0,7/9),(0,1/9),(0,0)这些点,将这些点绘图计算阴影面积得到AUC。1*(5/6)+ (7/9)*(1/6)= 52/54
结束。