jpmml / jpmml-lightgbm

Java library and command-line application for converting LightGBM models to PMML

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for custom objective functions

burakisiklidh opened this issue · comments

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

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.

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.

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

  • In the lgb file if a custom objective is used, the output of lgb files are slightly different:
    ➜ ~ cat custom_objective.lgb | grep objective
    [objective: custom]
    [objective_seed: 5]
    ➜ ~ cat lambdarank.lgb | grep objective
    objective=lambdarank
    [objective: lambdarank]
    [objective_seed: 5]

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.

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.