LightGBMRegressor 自定义评估损失函数 return 作为单个输出的列表错误
LightGBMRegressor Custom eval loss fuction return as list error for single output
我想在我的 lightGBM 模型中使用自定义 eval 函数。我的代码如下:
X = df.loc[:, "VALUE_1":"TVALUE_33"]
y_true = df.loc[:, "VALUE_34"]
X_train, X_test, y_train, y_test = train_test_split(X, y_true, test_size= 0.30, random_state = 333)
def mle_loss(y_true, y_pred):
y_true = tf.cast(y_true, dtype= tf.float32)
# get params for probability distributions
mu = y_pred.mean()
sigma = y_pred.std()
mu = tf.cast(mu, tf.float32)
sigma = tf.cast(sigma, tf.float32)
total_dist = tfp.distributions.Normal(loc=mu, scale=sigma)
total_log_prob = total_dist.log_prob(y_true)[0]
return ["mle_loss", total_log_prob.numpy(), True]
hyper_params_11 = {
'task': 'train',
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': "custom",
'subsample_freq': 250,
'subsample': 0.8,
'num_leaves': 16,
'min_split_gain': 50,
'min_child_samples': 25,
'max_depth': 5,
'max_bin': 1024,
'learning_rate': 0.001,
'colsample_bytree': 0.5,
"num_iterations": 10000,
"lambda_l1" : 1,
"lambda_l2" : 1
}
gbm_model_1 = lgb.LGBMRegressor(**hyper_params_1)
gbm_model_1.fit(X_train, y_train,
eval_set=[(X_test, y_test), (X_train,y_train)],
eval_metric = mle_loss,
early_stopping_rounds=100
)
不幸的是 运行我在这段代码中遇到了错误 ValueError:要解压的值太多(预期为 3)。当我 运行 它没有 eval_set 和 early_stopping_rounds 时,它工作正常。你能帮帮我吗?
谢谢
只需将您的 return 值更改为元组
def mle_loss(y_true, y_pred):
....
return ("mle_loss", total_log_prob.numpy(), True)
以列表形式返回会引发错误,例如,
feval_ret = ['mle_loss', -1.4523773, True]
if isinstance(feval_ret, list):
for eval_name, val, is_higher_better in feval_ret:
pass
会抛出您提到的错误
ValueError: too many values to unpack (expected 3)
根据 docs 发生这种情况是因为它期望单个元素的元组或多个元素的元组列表
returns (eval_name, eval_result, is_higher_better) or list of (eval_name, eval_result, is_higher_better)
我想在我的 lightGBM 模型中使用自定义 eval 函数。我的代码如下:
X = df.loc[:, "VALUE_1":"TVALUE_33"]
y_true = df.loc[:, "VALUE_34"]
X_train, X_test, y_train, y_test = train_test_split(X, y_true, test_size= 0.30, random_state = 333)
def mle_loss(y_true, y_pred):
y_true = tf.cast(y_true, dtype= tf.float32)
# get params for probability distributions
mu = y_pred.mean()
sigma = y_pred.std()
mu = tf.cast(mu, tf.float32)
sigma = tf.cast(sigma, tf.float32)
total_dist = tfp.distributions.Normal(loc=mu, scale=sigma)
total_log_prob = total_dist.log_prob(y_true)[0]
return ["mle_loss", total_log_prob.numpy(), True]
hyper_params_11 = {
'task': 'train',
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': "custom",
'subsample_freq': 250,
'subsample': 0.8,
'num_leaves': 16,
'min_split_gain': 50,
'min_child_samples': 25,
'max_depth': 5,
'max_bin': 1024,
'learning_rate': 0.001,
'colsample_bytree': 0.5,
"num_iterations": 10000,
"lambda_l1" : 1,
"lambda_l2" : 1
}
gbm_model_1 = lgb.LGBMRegressor(**hyper_params_1)
gbm_model_1.fit(X_train, y_train,
eval_set=[(X_test, y_test), (X_train,y_train)],
eval_metric = mle_loss,
early_stopping_rounds=100
)
不幸的是 运行我在这段代码中遇到了错误 ValueError:要解压的值太多(预期为 3)。当我 运行 它没有 eval_set 和 early_stopping_rounds 时,它工作正常。你能帮帮我吗?
谢谢
只需将您的 return 值更改为元组
def mle_loss(y_true, y_pred):
....
return ("mle_loss", total_log_prob.numpy(), True)
以列表形式返回会引发错误,例如,
feval_ret = ['mle_loss', -1.4523773, True]
if isinstance(feval_ret, list):
for eval_name, val, is_higher_better in feval_ret:
pass
会抛出您提到的错误
ValueError: too many values to unpack (expected 3)
根据 docs 发生这种情况是因为它期望单个元素的元组或多个元素的元组列表
returns (eval_name, eval_result, is_higher_better) or list of (eval_name, eval_result, is_higher_better)