Training XGBoost with PyScript and Panel

Hi Guys,

Would like to thank Marc for inviting me to this Discord.

Last week I’ve created a simple example of training an XGBoost model in HTML using PyScript and Panel. You can see the example here:

www.trainxgb.com

I am new to Panel, and really don’t have much experience with front-end web development, so the example I created was very rudimentary. Two main things that I’d like to add to my script would be:

  1. Additional sliders for more hyperparameters.

  2. A dedicated train button that trains the model when pressed - I believe rn all models are trained at once.

If any of you have any good suggestions on how to accomplish that within the example above, I’d greatly appreciate it.

Best,

Bojan

1 Like

Hi @tunguz, sorry for the delay.

I’ve added your example to the gallery here with some additional parameters:

To add a button you could rewrite it like this:

import panel as pn

from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier

pn.extension(sizing_mode="stretch_width", template="fast")

pn.state.template.param.update(title="XGBoost Example")

iris_df = load_iris(as_frame=True)

n_trees = pn.widgets.IntSlider(start=2, end=30, name="Number of trees")
max_depth = pn.widgets.IntSlider(start=1, end=10, value=2, name="Maximum Depth") 
booster = pn.widgets.Select(options=['gbtree', 'gblinear', 'dart'], name="Booster")
train = pn.widgets.Button(name='Train')

def pipeline(_):
    model = XGBClassifier(max_depth=max_depth.value, n_estimators=n_trees.value, booster=booster.value)
    model.fit(iris_df.data, iris_df.target)
    accuracy = round(accuracy_score(iris_df.target, model.predict(iris_df.data)) * 100, 1)
    return pn.indicators.Number(
        name="Test score",
        value=accuracy,
        format="{value}%",
        colors=[(97.5, "red"), (99.0, "orange"), (100, "green")],
        align='center'
    )

pn.Row(
    pn.Column(booster, n_trees, max_depth, train, width=320).servable(area='sidebar'),
    pn.Column(
        "Simple example of training an XGBoost classification model on the small Iris dataset.",
        iris_df.data.head(),
        "Adjust the hyperparameters to re-run the XGBoost classifier. The training accuracy score will adjust accordingly:",
        pn.bind(pipeline, button.param.clicks)
    ).servable(),
)
3 Likes

Interesting, that visiting the website, I get the following error:

PythonError: Traceback (most recent call last): File "/lib/python3.10/asyncio/futures.py", line 201, in result raise self._exception File "/lib/python3.10/asyncio/tasks.py", line 232, in __step result = coro.send(None) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 506, in eval_code_async await CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 357, in run_async coroutine = eval(self.code, globals, locals) File "", line 1, in ModuleNotFoundError: No module named 'panel'
1 Like

Good catch, this is because the website uses:

  <link rel="stylesheet" href="https://pyscript.net/unstable/pyscript.css" />
  <script defer src="https://pyscript.net/unstable/pyscript.js"></script>

That should be swapped out for:

  <link rel="stylesheet" href="https://pyscript.net/releases/2022.09.1/pyscript.css" />
  <script defer src="https://pyscript.net/releases/2022.09.1/pyscript.js"></script>
2 Likes

Thanks @philippjfr so much for your help! I have been able to implement all of your suggestions from above, and the site (www.trainxgb.com) works as well (minus some style issues! :sweat_smile: )

However, I am now getting the following error messages. They don’t affect the functionality, but are annoying nonetheless.

WARNING:param.Row00145: Displaying Panel objects in the notebook requires the panel extension to be loaded. Ensure you run pn.extension() before displaying objects in the notebook.
PythonError: Traceback (most recent call last): File "", line 154, in write File "", line 82, in format_mime TypeError: argument of type 'NoneType' is not iterable

I am now also getting the following warnings:

/lib/python3.10/site-packages/pyodide/__init__.py:74: FutureWarning: pyodide.create_proxy has been moved to pyodide.ffi.create_proxy Accessing it through the pyodide module is deprecated. warn(
/lib/python3.10/site-packages/pyodide/__init__.py:74: FutureWarning: pyodide.to_js has been moved to pyodide.ffi.to_js Accessing it through the pyodide module is deprecated. warn(

@tunguz Now that Panel 0.14.0 is released I’d recommend you just drop the app in a .py file and run:

panel convert script.py --runtime pyodide-worker --out out

Then copy the contents of out to your website. If you want to preserve readability of the HTML file you can also use --runtime pyscript and not configure a template.

1 Like