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:
Hello @Andrew-Wang-IB45, the first test I would implement would be similar to the code I gave [here](https://github.com/scikit-learn/scikit-learn/issues/25210#issuecomment-1385850267). I don't know if I was clear, but you can, for instance, assert that the number you get calculating the sum of the `sample_weights` in the leaf is equal to the "attribute" `weighted_n_node_samples` you implemented. For it, you can do a calculation "outside" (using the code I wrote earlier, for example):

```python
sample_weight[X[:, feat_idx] >= num_tresh].sum(), sample_weight[X[:, feat_idx] < num_tresh].sum()
>>> (456.6039224516335, 897.213567789653)
```

In this example, one leaf should have `456` as `weighted_n_node_samples`, and the other should have `897`. This logic can be executed for multiple datasets and randomly picked `sample_weight`.

Another interesting test might be having only two unique values for `X` (and then we know which sample went where), for instance, `X = np.array(10*[0] + 10*[1])` (and `y = X`) with `sample_weight = 10*[3] + 10*[7]`. All your trees should have `30` and `70` for their leafs' `weighted_n_node_samples` and `100` `weighted_n_node_samples` for their root. Also, when `sample_weight = 20*[1]`, then you can `assert weighted_n_node_samples == 20` for each leaf. When `sample_weight = 20*[0.5]`, then you can `assert weighted_n_node_samples == 10` for each leaf etc.

Once you are comfortable with the code, even if you think you still need extra tests, ask a core contributor to review the PR, and they will suggest additional tests! :D

Labels: New Feature, module:ensemble