jpmml / jpmml-lightgbm

Java library and command-line application for converting LightGBM models to PMML
GNU Affero General Public License v3.0
174 stars 58 forks source link

Support for custom objective functions #55

Closed burakisiklidh closed 2 years ago

burakisiklidh commented 2 years ago

Hi, When I tried to convert lightgbm model into pmml format, it throws this exception. I used a custom objective function. Can't we convert it when we use a custom objective?

java -jar jpmml-lightgbm-executable-1.3.5.jar --lgbm-input "model.lgb" --pmml-output "model.lgb.pmml"

converting model to PMML
Jan 13, 2022 11:30:50 AM org.jpmml.lightgbm.Main run
INFO: Loading GBDT..
Jan 13, 2022 11:30:50 AM org.jpmml.lightgbm.Main run
SEVERE: Failed to load GBDT
java.lang.IllegalArgumentException: objective
    at org.jpmml.lightgbm.Section.get(Section.java:106)
    at org.jpmml.lightgbm.Section.get(Section.java:100)
    at org.jpmml.lightgbm.Section.getStringArray(Section.java:90)
    at org.jpmml.lightgbm.GBDT.loadObjectiveFunction(GBDT.java:482)
    at org.jpmml.lightgbm.GBDT.load(GBDT.java:102)
    at org.jpmml.lightgbm.LightGBMUtil.loadGBDT(LightGBMUtil.java:53)
    at org.jpmml.lightgbm.LightGBMUtil.loadGBDT(LightGBMUtil.java:45)
    at org.jpmml.lightgbm.Main.run(Main.java:146)
    at org.jpmml.lightgbm.Main.main(Main.java:136)

Thanks Best

vruusmann commented 2 years ago

Can't we convert it when we use a custom objective?

Sure you can. Simply create a subclass of org.jpmml.lightgbm.ObjectiveFunction that represents your custom OF business logic, and register it with the JPMML-LightGBM library.

If you provide me with a toy example (what is the mining function - classification or regression? Create something based on standard Iris or Housing datasets, respectively), I can show you how it's done.

burakisiklidh commented 2 years ago

Sure, here is repo that I'm using. You can follow the example notebook on Section 2. It's a ranking function based on lambdarank.

burakisiklidh commented 2 years ago

Hi, I found the reason and fixed it using a workaround solution (a bit dirty one).

As you can see objective=lambdarank is added for only lambdarank output. Since it couldn't find the objective function using text parser, this is causing to throw the exception in this code. In order to fix, I modified the getStringArray method:

https://github.com/burakisiklidh/jpmml-lightgbm/blob/ce54676b743145f864409e17c5fa3d3a635ee7b0/pmml-lightgbm/src/main/java/org/jpmml/lightgbm/Section.java#L91

This is the workaround but we can discuss in detail a permanent one.

vruusmann commented 2 years ago

From the PMML conversion perspective, the lambdarank objective is functionally equivalent to the regression objective: https://github.com/jpmml/jpmml-lightgbm/blob/1.4.1/pmml-lightgbm/src/main/java/org/jpmml/lightgbm/Lambdarank.java#L21-L26

Now, since your custom objective is a subclass of the lambdarank objective, you can "fix" your LigthGBM model text file by replacing [objective: custom] with [objective: lambdarank] or [objective: regression]. This way there is no need to modify JPMML-LightGBM library in any way.

I expect to work on this issue in about ~1 week time.