Useful or not, from you.
LightGBM AttributeError: Can\'t pickle local object \'_objective_function_wrapper.<locals>.inner

LightGBM models are normally picklable, but when using a custom objective (and I assume eval_function etc.) they are not picklable.

import lightgbm as lgb
import _pickle as pickle
import numpy as np

def custom_asymmetric_objective(y_true, y_pred):
    residual = (y_true - y_pred).astype("float")
    grad = np.where(residual < 0, -2 * 10.0 * residual, -2 * residual)
    hess = np.where(residual < 0, 2 * 10.0, 2.0)
    return grad, hess

params = {}
params['objective'] = custom_asymmetric_objective
model = lgb.LGBMRegressor(**params)
X = np.array([[1,2,3,4], [2,3,4,5]]).transpose()
y = np.array([1,2,3,3])
model.fit(X, y)
preds = model.predict(X)
pickle.dump(model, open("model.pkl", "wb"))
print("Done")

Leads to:

Traceback (most recent call last):
  File "lgbm.py", line 22, in <module>
    pickle.dump(model, open("model.pkl", "wb"))
AttributeError: Can't pickle local object '_objective_function_wrapper.<locals>.inner'
jon@pseudotensor:~$ 

The problem is the def inside def way of defining the function: https://github.com/microsoft/LightGBM/blob/master/python-package/lightgbm/sklearn.py#L18-L78

The solution is to either:

  1. remove such def inside def uses and just directly make the function.
  2. If using a decorator, then you need to use the standard way that allows them to be pickleable via functools.wraps

http://gael-varoquaux.info/programming/decoration-in-python-done-right-decorating-and-pickling.html

That's a useful answer
Without any help
import _pickle as pickle
import numpy as np

def custom_asymmetric_objective(y_true, y_pred):
    residual = (y_true - y_pred).astype("float")
    grad = np.where(residual < 0, -2 * 10.0 * residual, -2 * residual)
    hess = np.where(residual < 0, 2 * 10.0, 2.0)
    return grad, hess



pickle.dump(custom_asymmetric_objective, open("func.pkl", "wb"))
print("Done")

But this still works, so it's still some kind of problem inside LightGBM.