RFC SLEP006: verbose vs non-verbose declaration in meta-estimator

As the proposal and the implementation of meta-estimator routing (SLEP006) stands, if the user wants to use `sample_weight`, they need to be quite verbose in how they declare the estimators. Taking `AdaBoostClassifier` as an example, and imagining if `AdaBoostClassifier` would use the sub-estimator's `score` method, the user would have to write:

``` python
est = (
    AdaBoostClassifier(LogisticRegression().set_fit_request(sample_weight=True)
    .set_score_request(sample_weight=True))
    .fit(X, y, sample_weight=sw)
)
```

which is quite more verbose than the current code users need to write:

``` python
est = AdaBoostClassifier(LogisticRegression()).fit(X, y, sample_weight=sw)
```

There have been concerns about making users write quite verbose code in cases where the current pattern seems quite reasonable.

Without changing everything related to SLEP006, there are three paths we can take:

#### Option 1: Helper function
We can introduce helper functions to make the above code simpler. For instance, a `weighted` function could request `sample_weight` on all methods which accept `sample_weight` for a given estimator. Then the above code would look like:

``` python
est = AdaBoostClassifier(weighted(LogisticRegression())).fit(X, y, sample_weight=sw)
```

and if the sub-estimator is a pipeline:

``` python
est = AdaBoostClassifier(
    make_pipeline(weighted(StandardScaler()), weighted(LogisticRegression())))
).fit(X, y, sample_weight=sw)
```

Implementing `weighted` for a `Pipeline` (or other meta-estimators) would be tricky since `set_fit_request` is only available for consumers and not non-consumer routers; therefore the user needs to repeat the `weighted` call for all sub-estimators.

#### Option 2: Different meta-estimators
Have two classes of meta-estimators (or routers to be specific).

In this scenario, we divide meta-estimators into two classes, _simple_ and _complex_. Simple routers are the ones which simply forward `**kwargs` to sub-estimators, and by default the assume sub-estimators have requested those metadata. This simplifies the users' code and makes the existing code for simple meta-estimators to keep working, but it raises a few issues.

First is that there will be two classes of meta-estimators, and the user would need to know which estimator is of which class. It's also not clear what we should do if the user explicitly sets request values for metadata (we can probably respect those if present).

Another issue is that if a meta-estimator changes behavior, it needs to become a _complex_ meta-estimator if we want to keep backward compatibility for it. This doesn't seem like a good pattern.

#### Option 3: Keep as is
Do nothing, things are as is.

I'm in favor or option 1 because:
- with the helper function the user code doesn't look too verbose
- using metadata is not a beginner kinda thing and therefore this API is not hampering beginners' experience with the library
- it keeps consistency among meta-estimators/consumers

xref: https://github.com/scikit-learn/scikit-learn/pull/22986#pullrequestreview-1005144559

COMMENT:
I'm coming at this from the perspective of a user or someone having to explain things to users. This is because I've not dug into the code related to SLEP6, this means my comments don't take into account what would be easier or harder to implement/maintain.

I'm not sure I understand why a user has to say more than:
```python
est = AdaBoostClassifier(LogisticRegression()).fit(X, y, sample_weight=sw)
```
It seems like with this line I've already expressed all there is to say: I want to use Ada boosting, with a logistic regression classifier and my samples have weights. Now please do your thing scikit-learn.

My assumption is that the vast majority of users do not know and do not want to have to know the subtleties involved in using ada boost with sample weights. This means they can't make an educated choice which in turns means they are likely to make a choice that is worse/wrong than if they delegate to an expert.

I think there should be an accepted way of dealing with sample weights when doing ada boosting. This should be the default behaviour. There might be a small percentage of experts who want to do something different, and for those it would be good to expose an "escape hatch" where they can override the default behaviour. And this escape hatch machinery could even be what `AdaBoostClassifier` uses to set things up the mainstream way.

Another example that came up recently is #25906. For me it is clear that it is a bug. The user passed sample weights but the scoring did not use them. There are two outcomes I'd expect: (1) it works and weights are used everywhere (where they can be used). (2) I get an error telling me that I requested something that is impossible (e.g. I'm using a metric for which sample weights are not supported), ideally with a pointer to an escape hatch with a big warning on it "here be dragons, by using this you void your warranty".

TIL: simple things should be simple for the not-expert, with an option for experts to do expert things would be my dream scenario.

Labels: API, RFC