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:
Hi Zach,

Does the following modification work, namely:

    from sklearn.base import BaseEstimator
    from sklearn.datasets import make_regression
    from sklearn.ensemble import GradientBoostingRegressor
    from sklearn.linear_model import LinearRegression
    from sklearn.pipeline import Pipeline

    X, y = make_regression(n_samples=100, n_features=10, noise=0.1)

    class InitRegressor(BaseEstimator):
        def __init__(self):
            super().__init__()
            self.reg = LinearRegression()

        def fit(self, X, y):
            self.reg.fit(X=X, y=y)
            return self

        def predict(self, X):
            y_pred = self.reg.predict(X=X)
            return y_pred

    init = InitRegressor()
    pipe = Pipeline(
        steps=[("reg", GradientBoostingRegressor(init=init, random_state=42))]
    )
    pipe.fit(X=X, y=y)
    print(pipe.named_steps["reg"].init_)

 where the latter results in `InitRegressor()`? In contrast, removal of `init=init`, which defaults to `init=None`, results in `DummyRegressor()`.

This is an implementation of a formulation of gradient boosting, which Buhlmann and Yu put forth in [Boosting with the L2-Loss: Regression and Classification](https://stat.ethz.ch/Manuscripts/buhlmann/boosting.rev5.pdf).

Labels: New Feature, Needs Decision