我想在模型训练过程中以不同的方式处理高估和低估带来的错误(例如“价格是正确的”)。我不想仅仅为了实现我的自定义成本函数和相关导数而重写sklearn中的整个MLP、回归、决策树等算法。有没有办法让我定义一个任何分类器都可以用来覆盖默认值的函数?这是我正在寻找的示例:
def myCustomError(y_preds,y_actuals):
#Calculate The price is right style error
return #not MSE
from sklearn import #Classifier
c = #Classifier(loss=myCustomError)
如果我不能在 sklearn 中做到这一点,但我必须使用tensorflow或其他一些库,请告诉我。
如果您需要定义自定义损失函数,通常会使用神经网络框架而不是
sklearn
。通常无法为 sklearn
算法提供自定义优化函数。如果您想坚持使用 sklearn
,某些算法允许您配置样本重要性或类别平衡,但从您的问题来看,这似乎不是所需的解决方案。
我不想重写整个MLP、回归、决策树等。 sklearn 中的算法只是为了实现我的自定义成本函数并且 相关衍生品。
不确定决策树,但 MLP 和回归很容易在 PyTorch 中实现。此外,当您定义自定义损失函数时,系统会为您处理导数。这是一个使用自定义损失函数的简单回归模型,它对高估的惩罚比对低估的惩罚更强烈:
此示例的一些模拟数据:
#Test data
import numpy as np
np.random.seed(0)
X0 = np.random.randn(128, 2) + 5
X1 = np.random.randn(128, 2)
X = np.concatenate([X0, X1], axis=0)
y = np.concatenate([np.linspace(0, 3, 128), np.linspace(-10, -5, 128)]).reshape(-1, 1)
PyTorch 中具有自定义损失函数的简单回归网络:
import torch
from torch import nn
from torch import optim
#Example of a custom loss function
#Treats overestimates differently to underestimates
def custom_loss(predictions, target):
errors = predictions - target
overestimates = errors[errors > 0]
underestimates = errors[errors < 0]
#penalise the square error of the overestimates more
loss = (overestimates ** 2).sum() + (0.5 * underestimates ** 2).sum()
return loss / len(target)
#Define a simple regression neural net
torch.manual_seed(0)
model = nn.Sequential(
nn.Linear(2, 4),
nn.ReLU(),
nn.Linear(4, 4),
nn.ReLU(),
nn.Linear(4, 1)
)
#Data to tensors
X_tensor = torch.tensor(X).to(torch.float32)
y_tensor = torch.tensor(y).to(torch.float32)
#Choose an optimiser and start training
optimiser = torch.optim.RMSprop(model.parameters())
n_epochs = 5
model.train()
for epoch in range(n_epochs):
predictions = model(X_tensor)
loss = custom_loss(predictions, y_tensor)
print('epoch', epoch, loss)
#Backpropagation and optimisation step
optimiser.zero_grad()
loss.backward()
optimiser.step()
为了简洁起见,此示例省略了缩放和批处理数据(以及保留验证集)等细节。