ENH partial_dependece plot for HistGradientBoosting estimator fitted with `sample_weight`

### Describe the workflow you want to enable

As partial dependence of a model at a point [is defined as an expectation](https://scikit-learn.org/stable/modules/partial_dependence.html#mathematical-definition), it should respect `sample_weight` if someone wishes to use it (for instance, when you know your `X` does not follow the distribution you are interested in).

#25209 tries to solve this for `method='brute'` when you have new `X`. For older tree-based models trained with sample_weights, [`method='recursion'`](https://nicolas-hug.com/blog/pdps) keeps track of the training `sample_weight` and calculates the `partial_dependece` with that into consideration.

But, as discussed during the implementation of `sample_weight` on the HistGradientBoosting estimators (https://github.com/scikit-learn/scikit-learn/pull/14696#issuecomment-548295813), these models stores an attribute `_fitted_with_sw` and when `partial_dependece` with recursion is asked, it throws an error:

https://github.com/scikit-learn/scikit-learn/blob/205f3b76ef8500c90c346c6c6fb6f4e589368278/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py#L1142-L1148


### Describe your proposed solution

As discussed in https://github.com/scikit-learn/scikit-learn/issues/24872#issuecomment-1352354690, the big difference between other tree-based algorithms and HistGradientBoosting is that HistGradientBoosting does not save the `weighted_n_node_samples` when building the tree.

### Describe alternatives you've considered, if relevant

_No response_

### Additional context

_No response_

COMMENT:
Hi @vitaliset, I thought about an approach to implement your solution and would like some clarifications.

I noticed for the BaseDecisionTree class, `sample_weight` is used when constructing the inner trees, as follows:
https://github.com/scikit-learn/scikit-learn/blob/9e08ed2279c80407f1d4c92a27279f73a2d08bb2/sklearn/tree/_classes.py#L379

My understanding is that for the BaseHistGradientBoosting class, `sample_weight` is correctly used in the loss function and in the sampling processes for the training and validation data, so we just need to add the sample weight as a parameter to the following instantiation of the TreeGrower: https://github.com/scikit-learn/scikit-learn/blob/0a36bd889289d5ff520ac6ed5f789f71a5ca56ca/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py#L673-L689

Within the TreeGrower, we should be using `sample_weight` to compute `weighted_n_node_samples`, storing that as an attribute for each TreeNode. Currently, the only reference I have to computing `weighted_n_node_samples` is for the TreeBuilder class used in the BaseDecisionTree, where `self.weighted_n_node_samples` is used in the PDP calculations: https://github.com/scikit-learn/scikit-learn/blob/0a36bd889289d5ff520ac6ed5f789f71a5ca56ca/sklearn/tree/_criterion.pyx#L286-L316

The above calculation should be the one used to compute `weighted_n_node_samples` for BaseHistGradientBoosting instances that are fitted with `sample_weight`, correct? If so, I would incorporate this calculation in `_intilialize_root` and `split_next`, specifically after the instantiation of each TreeNode, and save that value as an attribute.

Once this is done, then we can simply change all references of `count` to `weighted_n_node_samples` in https://github.com/scikit-learn/scikit-learn/blob/0a36bd889289d5ff520ac6ed5f789f71a5ca56ca/sklearn/ensemble/_hist_gradient_boosting/_predictor.pyx#L238-L240 and then remove the `NotImplementedError` from the recursive version of `compute_partial_dependence` since this is now supported.

What are your thoughts on my approach? If this works, I was thinking we should split this into two pull requests, where the first one is changing the underlying TreeNode to incorporate `sample_weight` and the second one is changing the PDP calculations and public interface. Clearly, we should benchmarking performance and memory footprint upon updating the BaseHistGradientBoostingClass. What tools would you recommend for this?

Thanks for your time!

Labels: New Feature, module:ensemble