Allow boosting of estimators in scikit-learn pipelines using residuals

### Describe the workflow you want to enable

I want to be able to use multiple estimators in one pipeline.  E.g.

```python
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.datasets import make_regression

X, y = make_regression(n_samples=100, n_features=10, noise=0.1)

pipeline = Pipeline([
    ('linear', LinearRegression()),
    ('gbm', GradientBoostingRegressor())
])

pipeline.fit(X, y)
```

This currently doesn't work: 
```python
TypeError: All intermediate steps should be transformers and implement fit and transform or be the string 'passthrough' 'LinearRegression()' (type <class 'sklearn.linear_model._base.LinearRegression'>) doesn't
```

This is for good reason: naively passing predict from the linear model to the fit for the gbm will lead to overfitting!

### Describe your proposed solution

Allow boosting estimators in scikit learn pipeline by subtracting the predict output from y at `fit` time and then adding the predict outputs at transform time. This enhancement would allow multiple regression estimators to be used consecutively, where each subsequent estimator fits on the residuals of the previous ones.

In my example above, at fit time the linear step proceeds as normal.  Then the gbm step detects 2 chained estimators, and subtracts the prediction from the linear step from y, and then fits to the residual.

At transform time, the predictions from the linear model would be added to the predictions from the gbm model.

To simplify things, I think you still wouldn't be allowed to connect an estimator to a transformer.

### Describe alternatives you've considered, if relevant

Vecstack is a good alternative, but its slow.  You have to cross-validate each estimator, which gets expensive if you chain more than 2 in a row.

```python
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.datasets import make_regression
from vecstack import StackingTransformer

X, y = make_regression(n_samples=100, n_features=10, noise=0.1)

pipeline = Pipeline([
    ('linear', StackingTransformer([('lr', LinearRegression())], regression=True, shuffle=True)),
    ('gbm', GradientBoostingRegressor())
])

pipeline.fit(X, y)
y_pred = pipeline.predict(X)
```

### Additional context

I love being able to use stacking inside sklearn pipelines.  It would be very cool to be able to use boosting too.  I haven't been able to figure out how to make a boosting class that adjusts y as it moves through the pipeline, which is why I think this feature would need to be implemented in the core library.

COMMENT:
@a-wozniakowski That works if I want to only boost one estimator, and use the same preprocessing for each one.  It does not work if I want to boost *different* estimators, with varied preprocessing.

For example, I would like to have a pipeline that starts with a linear regression model that uses one-hot encoding.  I would then like to git to add a Decision Tree that uses ordinal encoding, fit on the residuals of the linear model.

Labels: New Feature, Needs Decision