在scikit learn中实现自定义损失函数

13

我想在scikit learn中实现自定义的损失函数。我使用以下代码片段:

def my_custom_loss_func(y_true,y_pred):
   diff3=max((abs(y_true-y_pred))*y_true)
   return diff3

score=make_scorer(my_custom_loss_func,greater_ is_better=False)
clf=RandomForestRegressor()
mnn= GridSearchCV(clf,score)
knn = mnn.fit(feam,labm) 
什么参数应传递到my_custom_loss_func中?我的标签矩阵名为labm。我想计算实际输出和(由模型预测的)预测输出之间的差异乘以真实输出。如果我使用labm代替y_true,那么我应该用什么代替y_pred
3个回答

26

好的,这里有三个要点:

1)在训练过程中使用的损失函数用于调整模型参数

2)评分函数用于判断您的模型质量

3)超参数调整使用评分函数来优化您的超参数。

所以...如果你正在尝试调整超参数,那么制定“损失函数”是一个正确的方向。然而,如果你试图调整整个模型以在召回测试(recall test)等方面表现良好,那么你需要将召回率优化器作为训练过程的一部分。这很棘手,但你可以做到...

1)打开你的分类器,我们举个例子: https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html

2)点击 [source]

3)看看它是如何从ForestClassifier继承的?就在类定义中。单击该词跳转到其父级定义。

4)看看这个新对象是如何从ClassifierMixin继承的?点击那个。

5)看看ClassifierMixin类底部说的是什么?

from .metrics import accuracy_score
return accuracy_score(y, self.predict(X), sample_weight=sample_weight)

那是您的模型在训练时基于准确性。如果您想将您的模型训练成“召回模型”、“精确度模型”或任何其他模型,此时需要进行注入。这个准确性指标已经集成在SKlearn中。总有一天,比我更优秀的人会将其变成参数,供模型接受使用。但与此同时,您需要进入SKlearn安装程序,并调整accuracy_score以使其达到所需的效果。

祝您好运!


4
今天这个还是真的吗? - John Arrowwood
ClassifierMixin 中的那行代码定义了 score 方法,该方法用于您排名列表的第2和第3部分,但不用于第1部分,即模型本身的 fit 方法中发生的实际优化。该优化取决于模型类型,但通常会使用比准确度更好且更微妙的损失函数。 - Ben Reiniger

4

make_scorer的文档如下:

sklearn.metrics.make_scorer(score_func, greater_is_better=True, needs_proba=False, 
needs_threshold=False, **kwargs)

所以,在调用函数时不需要传递参数。这就是您所问的吗?

我是说在定义函数my_custom_func_loss时(我的代码的第一行),我需要传递参数,对吧?没有参数,我怎么编写函数体呢?我是在询问那些参数。这里我传递了y_true和y_pred。 - Moonzarin Esha
是的!你只需要这两个参数。但是,如果你想传递一些额外的参数,你可以像这样做:score_func(y, y_pred, **kwargs),其中 **kwargs 是你想要传递的额外参数。 - Abhishek
默认情况下,y将被分配为标签矩阵,y_pred将是模型的预测值。我不需要在代码中定义这些值吗?我看到有人写truths、preds。那么我们可以写任何参数,scikit learn就能理解吗?这似乎有点奇怪。 - Moonzarin Esha
如果按照定义函数时的顺序传递参数,那么它们将按照你定义的顺序进行传递。例如:假设我们有一个像这样的函数 costFunc(y, y_pred)。现在,如果你传递类似于 costFunc(labels, predictions) 的值,那么 labels 将被传递给 y,predictions 将被传递给 y_pred。然而,你也可以采用另一种方式:costFunc(y_pred=predictions, y=labels)。正如你所看到的,如果你提供名称并传递参数,则不再需要按顺序传递。 - Abhishek
默认情况下,scikit learn 会假设第一个参数是真实标签,第二个参数对应于预测模型输出。如果我只写 y 和 y_pred,而没有明确指出 y 和 y_pred 是什么,它仍然可以正常工作吗? - Moonzarin Esha
是的,但顺序不应更改,即应与您的函数相同。 - Abhishek

0

你的 my_custom_func_loss 函数的参数与真实标签没有任何关联,真实标签是labm。您可以保持现有的方式。

在内部,GridSearchCV 将调用评分函数,因此您的真实标签不会与其冲突。y_pred 是从模型输出生成的预测值。y_true 将分配为labm的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接