R lightgbm中多类自定义度量函数

R lightgbm中多类自定义度量函数,r,lightgbm,R,Lightgbm,在我的数据中,大约有70个类,我使用lightGBM预测正确的类标签 在R中,我希望有一个定制的“度量”函数,在该函数中我可以评估lightgbm的前3个预测是否覆盖了真实标签 这个链接令人振奋 def lgb_f1_score(y_hat, data): y_true = data.get_label() y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities return 'f1', f1_sco

在我的数据中,大约有70个类,我使用lightGBM预测正确的类标签

在R中,我希望有一个定制的“度量”函数,在该函数中我可以评估lightgbm的前3个预测是否覆盖了真实标签

这个链接令人振奋

def lgb_f1_score(y_hat, data):
    y_true = data.get_label()
    y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities
    return 'f1', f1_score(y_true, y_hat), True

然而,我不知道这些参数将起作用的维度。似乎数据由于某种原因被洗牌。

Scikit学习实现

from sklearn.metrics import f1_score

def lgb_f1_score(y_true, y_pred):
    preds = y_pred.reshape(len(np.unique(y_true)), -1)
    preds = preds.argmax(axis = 0)
    print(preds.shape)
    print(y_true.shape)
    return 'f1', f1_score(y_true, preds,average='weighted'), True

在阅读了和的文档之后,我必须创建一个单独的函数
get_ith_pred
,然后在
lgb_f1_score
中重复调用该函数

函数的docstring解释了它是如何工作的。我使用了与LightGBM文档中相同的参数名称。这可以用于任何数量的类,但不适用于二进制分类。在二进制情况下,
preds
是一个1D数组,包含正类的概率

从sklearn.metrics导入f1\U分数
def get_ith_pred(preds,i,num_数据,num_类):
"""
preds:1D NumPY阵列
包含预测概率的一维numpy数组。具有形状
(num_data*num_class,)。因此,对于具有
训练集中有100行数据,preds是shape(200,),
i、 e.(100*2,)。
i:int
您希望计算的培训数据中的行/示例
对未来的预测。
num_数据:int
训练数据中的行数/样本数
num_类:int
分类任务中的类数。
必须大于2。
LightGBM文档告诉我们,要获得
我们在数据集的第5行执行preds[0*num_data+5]。
对于第7行的1类预测,执行preds[1*num_data+7]。
sklearn的f1_分数(y_true,y_pred)预计y_pred的形式
[0,1,1,1,1,0…]而不是概率。
此函数将preds转换为sklearn的f1_分数形式
理解。
"""
#仅适用于多类分类
断言num_类>2
第i行的preds\u=[preds[类标签*num\u数据+i]
对于范围内的类标签(num\u类)]
#预测概率最高的元素
返回np.argmax(第i行的preds\u)
def lgb_f1_分数(预测、列车数据):
y_true=训练数据。获取标签()
num_data=len(y_true)
num_class=70
y_pred=[]
对于范围内的i(num_数据):
ith_pred=获取ith_pred(preds,i,num_数据,num_类)
y_pred.追加(第i_pred)
返回'f1',f1_分数(y_真,y_pred,average='weighted'),真

y\u true
y\u hat
都是数组,对吗?如果是这样的话,为什么不直接打印这些尺寸呢?除非使用CV,否则不应进行洗牌。免责声明:我不使用R,但我对Python中的lightgbm有一些经验,这会产生:
AttributeError:'Dataset'对象没有属性“重塑”
。而且,第一个参数应该是预测值,第二个参数是真值。你给它们取了相反的名字。