Repository: onnx/sklearn-onnx (python)

Issue:
RuntimeError when converting GaussianProcessRegressor with WhiteKernel and return_std option
### Description
When attempting to convert a scikit-learn GaussianProcessRegressor model with WhiteKernel to ONNX format using the `return_std=True` option, the conversion fails with a RuntimeError. The error occurs specifically when using the WhiteKernel, while the conversion works fine when the option is removed.

### Error Message
```
RuntimeError: Unable to convert diag method for class <class 'sklearn.gaussian_process.kernels.WhiteKernel'>.
```

Here is an example code to reproduce the error:

```python
import numpy as np
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import WhiteKernel
import onnx
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType

# Generate sample data
X = np.array([[1], [3], [5], [6], [7], [8], [10], [12], [14], [15]])
y = np.array([3, 2, 7, 8, 7, 6, 9, 11, 10, 12])

# Define the kernel
kernel = WhiteKernel()

# Create and train the Gaussian Process Regressor
gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10, alpha=1e-2)
gpr.fit(X, y)

# Convert the trained model to ONNX format
initial_type = [("float_input", FloatTensorType([None, 1]))]
onnx_model = convert_sklearn(
    gpr,
    initial_types=initial_type,
    options={GaussianProcessRegressor: {"return_std": True}},
)
```

### Environment Information
- Operating System: MacOS 15.2
- Python Version: 3.10.14
- scikit-learn Version: 1.5.0
- skl2onnx Version: 1.18.0
- onnx Version: 1.17.0

Thank you in advance for any feedback or solution!

Pull request description:
Fixes missing WhiteKernel with return_std=True
Fixes #1161.

Patch:
diff --git a/CHANGELOGS.md b/CHANGELOGS.md
index 807b224..f64a0b0 100644
--- a/CHANGELOGS.md
+++ b/CHANGELOGS.md
@@ -2,10 +2,14 @@
 
 ## 1.19.0
 
-In progress.
-
-## 1.18.1
-
+* Fixes missing WhiteKernel with return_std=True #1163
+  [#1163](https://github.com/onnx/sklearn-onnx/issues/1163)
+* Fix empty column selector
+  [#1159](https://github.com/onnx/sklearn-onnx/issues/1159)
+* Fix conversion for XGBClassifier and XGBRegressor
+  [#1157](https://github.com/onnx/sklearn-onnx/issues/1157)
+* Test SelectKBest + StandardScaler pipeline
+  [#1156](https://github.com/onnx/sklearn-onnx/issues/1156)
 * Fix np.NAN into np.nan,
   [#1148](https://github.com/onnx/sklearn-onnx/issues/1148)
 
diff --git a/skl2onnx/operator_converters/_gp_kernels.py b/skl2onnx/operator_converters/_gp_kernels.py
index 50ef3da..baeee8a 100644
--- a/skl2onnx/operator_converters/_gp_kernels.py
+++ b/skl2onnx/operator_converters/_gp_kernels.py
@@ -83,6 +83,17 @@ def convert_kernel_diag(
             op_version=op_version,
         )
 
+    if type(kernel) is WhiteKernel:
+        onnx_zeros = _zero_vector_of_size(
+            X, keepdims=0, dtype=dtype, op_version=op_version
+        )
+        return OnnxAdd(
+            onnx_zeros,
+            np.array([kernel.noise_level], dtype=dtype),
+            output_names=output_names,
+            op_version=op_version,
+        )
+
     if type(kernel) in {RBF, ExpSineSquared, RationalQuadratic, Matern}:
         onnx_zeros = _zero_vector_of_size(
             X, keepdims=0, dtype=dtype, op_version=op_version
@@ -114,9 +125,7 @@ def convert_kernel_diag(
             op_version=op_version,
         )
 
-    raise RuntimeError(
-        "Unable to convert diag method for class {}.".format(type(kernel))
-    )
+    raise RuntimeError(f"Unable to convert diag method for class {type(kernel)}")
 
 
 def py_make_float_array(cst, dtype, as_tensor=False):


Test patch:
diff --git a/tests/test_issues_2025.py b/tests/test_issues_2025.py
new file mode 100644
index 0000000..752da1f
--- /dev/null
+++ b/tests/test_issues_2025.py
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: Apache-2.0
+import unittest
+from sklearn.utils._testing import ignore_warnings
+from sklearn.exceptions import ConvergenceWarning
+
+
+class TestInvestigate2025(unittest.TestCase):
+    @ignore_warnings(category=(ConvergenceWarning, FutureWarning))
+    def test_issue_1161_gaussian(self):
+        # https://github.com/onnx/sklearn-onnx/issues/1161
+        import numpy as np
+        from sklearn.gaussian_process import GaussianProcessRegressor
+        from sklearn.gaussian_process.kernels import WhiteKernel
+        from skl2onnx import convert_sklearn
+        from skl2onnx.common.data_types import FloatTensorType
+
+        # Generate sample data
+        X = np.array([[1], [3], [5], [6], [7], [8], [10], [12], [14], [15]])
+        y = np.array([3, 2, 7, 8, 7, 6, 9, 11, 10, 12])
+
+        # Define the kernel
+        kernel = WhiteKernel()
+
+        # Create and train the Gaussian Process Regressor
+        gpr = GaussianProcessRegressor(
+            kernel=kernel, n_restarts_optimizer=10, alpha=1e-2
+        )
+        gpr.fit(X, y)
+
+        # Convert the trained model to ONNX format
+        initial_type = [("float_input", FloatTensorType([None, 1]))]
+        onnx_model = convert_sklearn(
+            gpr,
+            initial_types=initial_type,
+            options={GaussianProcessRegressor: {"return_std": True}},
+        )
+        self.assertTrue(onnx_model is not None)
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
diff --git a/tests/test_sklearn_gaussian_process_regressor.py b/tests/test_sklearn_gaussian_process_regressor.py
index a6c102b..7c46db6 100644
--- a/tests/test_sklearn_gaussian_process_regressor.py
+++ b/tests/test_sklearn_gaussian_process_regressor.py
@@ -1621,6 +1621,28 @@ class TestSklearnGaussianProcessRegressor(unittest.TestCase):
             model.predict(vx1.astype(np.float64)).ravel(), pred[0].ravel()
         )
 
+    @ignore_warnings(category=(ConvergenceWarning, FutureWarning))
+    def test_white_kernel_return_std(self):
+        X = np.array([[1], [3], [5], [6], [7], [8], [10], [12], [14], [15]])
+        y = np.array([3, 2, 7, 8, 7, 6, 9, 11, 10, 12])
+        kernel = WhiteKernel()
+        gpr = GaussianProcessRegressor(
+            kernel=kernel, n_restarts_optimizer=10, alpha=1e-2
+        )
+        gpr.fit(X, y)
+        initial_type = [("X", FloatTensorType([None, 1]))]
+        onnx_model = to_onnx(
+            gpr,
+            initial_types=initial_type,
+            options={GaussianProcessRegressor: {"return_std": True}},
+        )
+        self.check_outputs(
+            gpr,
+            onnx_model,
+            X.astype(np.float32),
+            predict_attributes={"return_std": True},
+        )
+
 
 if __name__ == "__main__":
     # import logging