Repository: sebp/scikit-survival (language: python)

Issue:
Support Scikit-Learn 1.4 (stable version)
**Describe the solution you'd like**
Bump the `scikit-learn` version required to >= 1.3.



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/tox-workflow.yaml b/.github/workflows/tox-workflow.yaml
index 546a2b06..a2ac22a4 100644
--- a/.github/workflows/tox-workflow.yaml
+++ b/.github/workflows/tox-workflow.yaml
@@ -10,11 +10,17 @@ jobs:
         uses: actions/checkout@v4
         with:
           submodules: true
-      - name: Install packages
+      - name: Install third-party tools
         run: |
-          sudo apt-get install cmake libenchant-2-dev tox
+          sudo apt-get install cmake libenchant-2-dev
           eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
           brew install pandoc
+      - name: Setup Python
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: Install Tox
+        run: python -m pip install tox
       - name: Run Tox
         run: |
           eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
diff --git a/README.rst b/README.rst
index 22f2003d..40bd8a30 100644
--- a/README.rst
+++ b/README.rst
@@ -36,11 +36,11 @@ Requirements
 - ecos
 - joblib
 - numexpr
-- numpy 1.17.3 or later
+- numpy
 - osqp
 - pandas 1.0.5 or later
-- scikit-learn 1.3
-- scipy 1.3.2 or later
+- scikit-learn 1.4
+- scipy
 - C/C++ compiler
 
 ============
@@ -123,7 +123,7 @@ Please cite the following paper if you are using **scikit-survival**.
   :alt: codecov
 
 .. |Codacy| image:: https://api.codacy.com/project/badge/Grade/17242004cdf6422c9a1052bf1ec63104
-   :target: https://www.codacy.com/gh/sebp/scikit-survival/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=sebp/scikit-survival&amp;utm_campaign=Badge_Grade
+   :target: https://app.codacy.com/gh/sebp/scikit-survival/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
    :alt: Codacy Badge
 
 .. |Docs| image:: https://readthedocs.org/projects/scikit-survival/badge/?version=latest
diff --git a/appveyor.yml b/appveyor.yml
index 6a4bc06c..fab3959c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -21,12 +21,13 @@ platform:
 
 install:
   - ps: $env:CONDA_INSTALL_LOCN="$env:USERPROFILE\Miniconda3"
-  - ps: Invoke-WebRequest -Uri https://repo.anaconda.com/miniconda/Miniconda3-py311_23.5.2-0-Windows-x86_64.exe -OutFile Miniconda3.exe
-  - ps: ( Get-FileHash -Algorithm SHA256 Miniconda3.exe ).Hash -eq '00e8370542836862d4c790aa8966f1d7344a8addd4b766004febcb23f40e2914'
+  - ps: Invoke-WebRequest -Uri https://repo.anaconda.com/miniconda/Miniconda3-py312_24.1.2-0-Windows-x86_64.exe -OutFile Miniconda3.exe
+  - ps: ( Get-FileHash -Algorithm SHA256 Miniconda3.exe ).Hash -eq 'ff53a36b7024f8398cbfd043020f1f662cd4c5c2095c0007ddb4348aa5459375'
   - ps: Start-Process Miniconda3.exe -Wait -ArgumentList @('/S', '/InstallationType=JustMe', '/RegisterPython=1', '/D="$env:CONDA_INSTALL_LOCN"')
   - ps: $env:Path += ";$env:CONDA_INSTALL_LOCN\Scripts;$env:CONDA_INSTALL_LOCN\Library\bin"
   - ps: conda init powershell
-  - ps: conda config --set always_yes yes --set changeps1 no
+  - ps: conda config --set always_yes yes
+  - ps: conda config --set changeps1 no
   - ps: conda config --set auto_update_conda false
   - ps: conda config --set notify_outdated_conda false
 #  - ps: conda update --yes --quiet conda
diff --git a/ci/appveyor/py310.ps1 b/ci/appveyor/py310.ps1
index 15da48a5..df7f0bfd 100644
--- a/ci/appveyor/py310.ps1
+++ b/ci/appveyor/py310.ps1
@@ -1,4 +1,4 @@
 $env:CI_PYTHON_VERSION="3.10.*"
 $env:CI_PANDAS_VERSION="1.5.*"
-$env:CI_NUMPY_VERSION="1.24.*"
-$env:CI_SKLEARN_VERSION="1.3.*"
+$env:CI_NUMPY_VERSION="1.25.*"
+$env:CI_SKLEARN_VERSION="1.4.*"
diff --git a/ci/appveyor/py311.ps1 b/ci/appveyor/py311.ps1
index b6c0f738..c19644ac 100644
--- a/ci/appveyor/py311.ps1
+++ b/ci/appveyor/py311.ps1
@@ -1,4 +1,4 @@
 $env:CI_PYTHON_VERSION="3.11.*"
 $env:CI_PANDAS_VERSION="2.0.*"
-$env:CI_NUMPY_VERSION="1.24.*"
-$env:CI_SKLEARN_VERSION="1.3.*"
+$env:CI_NUMPY_VERSION="1.25.*"
+$env:CI_SKLEARN_VERSION="1.4.*"
diff --git a/ci/appveyor/py312.ps1 b/ci/appveyor/py312.ps1
index 51b4bf11..d103667b 100644
--- a/ci/appveyor/py312.ps1
+++ b/ci/appveyor/py312.ps1
@@ -1,4 +1,4 @@
 $env:CI_PYTHON_VERSION="3.12.*"
-$env:CI_PANDAS_VERSION="2.1.*"
+$env:CI_PANDAS_VERSION="2.2.*"
 $env:CI_NUMPY_VERSION="1.26.*"
-$env:CI_SKLEARN_VERSION="1.3.*"
+$env:CI_SKLEARN_VERSION="1.4.*"
diff --git a/ci/appveyor/py39.ps1 b/ci/appveyor/py39.ps1
index 71bcba99..068bab57 100644
--- a/ci/appveyor/py39.ps1
+++ b/ci/appveyor/py39.ps1
@@ -1,4 +1,4 @@
 $env:CI_PYTHON_VERSION="3.9.*"
 $env:CI_PANDAS_VERSION="1.4.*"
-$env:CI_NUMPY_VERSION="1.22.*"
-$env:CI_SKLEARN_VERSION="1.3.*"
+$env:CI_NUMPY_VERSION="1.25.*"
+$env:CI_SKLEARN_VERSION="1.4.*"
diff --git a/ci/deps/py310_pandas15_numpy124_sklearn13.sh b/ci/deps/py310.sh
similarity index 62%
rename from ci/deps/py310_pandas15_numpy124_sklearn13.sh
rename to ci/deps/py310.sh
index a6567ab6..6da59955 100644
--- a/ci/deps/py310_pandas15_numpy124_sklearn13.sh
+++ b/ci/deps/py310.sh
@@ -1,6 +1,6 @@
 # shellcheck shell=sh
 export CI_PYTHON_VERSION='3.10.*'
 export CI_PANDAS_VERSION='1.5.*'
-export CI_NUMPY_VERSION='1.24.*'
-export CI_SKLEARN_VERSION='1.3.*'
+export CI_NUMPY_VERSION='1.25.*'
+export CI_SKLEARN_VERSION='1.4.*'
 export CI_NO_SLOW=true
diff --git a/ci/deps/py311_pandas20_numpy124_sklearn13.sh b/ci/deps/py311.sh
similarity index 62%
rename from ci/deps/py311_pandas20_numpy124_sklearn13.sh
rename to ci/deps/py311.sh
index de0231bf..b9a271da 100644
--- a/ci/deps/py311_pandas20_numpy124_sklearn13.sh
+++ b/ci/deps/py311.sh
@@ -1,6 +1,6 @@
 # shellcheck shell=sh
 export CI_PYTHON_VERSION='3.11.*'
 export CI_PANDAS_VERSION='2.0.*'
-export CI_NUMPY_VERSION='1.24.*'
-export CI_SKLEARN_VERSION='1.3.*'
+export CI_NUMPY_VERSION='1.25.*'
+export CI_SKLEARN_VERSION='1.4.*'
 export CI_NO_SLOW=true
diff --git a/ci/deps/py312_pandas21_numpy126_sklearn13.sh b/ci/deps/py312.sh
similarity index 62%
rename from ci/deps/py312_pandas21_numpy126_sklearn13.sh
rename to ci/deps/py312.sh
index ca5c6b2b..fbcfdb0c 100644
--- a/ci/deps/py312_pandas21_numpy126_sklearn13.sh
+++ b/ci/deps/py312.sh
@@ -1,6 +1,6 @@
 # shellcheck shell=sh
 export CI_PYTHON_VERSION='3.12.*'
-export CI_PANDAS_VERSION='2.1.*'
+export CI_PANDAS_VERSION='2.2.*'
 export CI_NUMPY_VERSION='1.26.*'
-export CI_SKLEARN_VERSION='1.3.*'
+export CI_SKLEARN_VERSION='1.4.*'
 export CI_NO_SLOW=false
diff --git a/ci/deps/py39_pandas14_numpy122_sklearn13.sh b/ci/deps/py39.sh
similarity index 62%
rename from ci/deps/py39_pandas14_numpy122_sklearn13.sh
rename to ci/deps/py39.sh
index 329f8325..e74d0df3 100644
--- a/ci/deps/py39_pandas14_numpy122_sklearn13.sh
+++ b/ci/deps/py39.sh
@@ -1,6 +1,6 @@
 # shellcheck shell=sh
 export CI_PYTHON_VERSION='3.9.*'
 export CI_PANDAS_VERSION='1.4.*'
-export CI_NUMPY_VERSION='1.22.*'
-export CI_SKLEARN_VERSION='1.3.*'
+export CI_NUMPY_VERSION='1.25.*'
+export CI_SKLEARN_VERSION='1.4.*'
 export CI_NO_SLOW=false
diff --git a/ci/deps/requirements.yaml.tmpl b/ci/deps/requirements.yaml.tmpl
index cfc9c316..a1186838 100644
--- a/ci/deps/requirements.yaml.tmpl
+++ b/ci/deps/requirements.yaml.tmpl
@@ -16,8 +16,7 @@ dependencies:
   - pip
   - pytest
   - python={CI_PYTHON_VERSION}
-  - scikit-learn={CI_SKLEARN_VERSION}
-  - scipy>=1.3.2
+  - scipy>=1.6.0
   - seaborn>=0.11.2,<0.12
   - setuptools-scm
   - wheel
@@ -26,4 +25,5 @@ dependencies:
     - build
     - importlib-resources>=1.3
     - nbval>=0.10.0
+    - scikit-learn=={CI_SKLEARN_VERSION}
     - tomli
diff --git a/ci/setup_conda.sh b/ci/setup_conda.sh
new file mode 100755
index 00000000..c158d414
--- /dev/null
+++ b/ci/setup_conda.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+RUNNER_OS="${1}"
+RUNNER_ARCH="${2}"
+CONDA_PKGS_DIR="${3}"
+
+run_check_sha() {
+    echo "${1}" | shasum -a 256 --check --strict -
+}
+
+if [[ "${CONDA:-}" = "" ]]; then
+    # download and install conda
+    MINICONDA_VERSION="Miniconda3-py312_24.1.2-0"
+
+    if [[ "${RUNNER_OS}" = "macOS" ]] && [[ "${RUNNER_ARCH}" = "ARM64" ]]; then
+        MINICONDA_VERSION="${MINICONDA_VERSION}-MacOSX-arm64"
+        MINICONDA_HASH="1c277b1ec046fd1b628390994e3fa3dbac0e364f44cd98b915daaa67a326c66a"
+    elif [[ "${RUNNER_OS}" = "macOS" ]] && [[ "${RUNNER_ARCH}" = "X64" ]]; then
+        MINICONDA_VERSION="${MINICONDA_VERSION}-MacOSX-x86_64"
+        MINICONDA_HASH="bc45a2ceea9341579532847cc9f29a9769d60f12e306bba7f0de6ad5acdd73e9"
+    elif [[ "${RUNNER_OS}" = "Linux" ]] && [[ "${RUNNER_ARCH}" = "X64" ]]; then
+        MINICONDA_VERSION="${MINICONDA_VERSION}-Linux-x86_64"
+        MINICONDA_HASH="b978856ec3c826eb495b60e3fffe621f670c101150ebcbdeede4f961f22dc438"
+    else
+        echo "Unsupported OS or ARCH: ${RUNNER_OS} ${RUNNER_ARCH}"
+        exit 1
+    fi
+
+    export CONDA="${GITHUB_WORKSPACE}/miniconda3"
+
+    mkdir -p "${CONDA}" && \
+    curl "https://repo.anaconda.com/miniconda/${MINICONDA_VERSION}.sh" -o "${CONDA}/miniconda.sh" && \
+    run_check_sha "${MINICONDA_HASH}  ${CONDA}/miniconda.sh" && \
+    bash "${CONDA}/miniconda.sh" -b -u -p "${CONDA}" && \
+    rm -rf "${CONDA}/miniconda.sh" || exit 1
+
+    echo "CONDA=${CONDA}" >> "${GITHUB_ENV}"
+fi
+
+"${CONDA}/bin/conda" config --set always_yes yes && \
+"${CONDA}/bin/conda" config --set changeps1 no && \
+"${CONDA}/bin/conda" config --set auto_update_conda false && \
+"${CONDA}/bin/conda" config --set show_channel_urls true || \
+exit 1
+
+# The directory in which packages are located.
+# https://docs.conda.io/projects/conda/en/latest/user-guide/configuration/settings.html#pkgs-dirs-specify-package-directories
+if [[ ! -d "${CONDA_PKGS_DIR}" ]]; then
+    mkdir -p "${CONDA_PKGS_DIR}" || exit 1
+fi
+sudo chown -R "${USER}" "${CONDA_PKGS_DIR}" || \
+exit 1
+
+sudo "${CONDA}/bin/conda" update -q -n base conda && \
+sudo chown -R "${USER}" "${CONDA}" || \
+exit 1
+
+export PATH="${CONDA}/bin:${PATH}"
+echo "${CONDA}/bin" >> "${GITHUB_PATH}"
diff --git a/ci/setup_env.sh b/ci/setup_env.sh
index 2588bf37..a955805a 100755
--- a/ci/setup_env.sh
+++ b/ci/setup_env.sh
@@ -6,21 +6,15 @@ OS="$1"
 if [ "x${OS}" = "xLinux" ]; then
   COMPILER=()
 elif [ "x${OS}" = "xmacOS" ]; then
-  COMPILER=(clang_osx-64 clangxx_osx-64)
+  COMPILER=(clang_osx-arm64 clangxx_osx-arm64)
 else
   echo "OS '${OS}' is unsupported."
   exit 1
 fi
 
-#conda update -q conda
-conda config --set always_yes yes --set changeps1 no
-conda config --add pkgs_dirs "${CONDA_PKGS_DIR:-conda_pkgs_dir}"
-
-conda install -n base conda-libmamba-solver
-
 python ci/render-requirements.py ci/deps/requirements.yaml.tmpl > environment.yaml
 
-conda env create -n sksurv-test --solver=libmamba --file environment.yaml
+conda env create -n sksurv-test --file environment.yaml
 
 echo "numpy ${CI_NUMPY_VERSION:?}" > "${CONDA:?}/envs/sksurv-test/conda-meta/pinned"
 echo "pandas ${CI_PANDAS_VERSION:?}" >> "${CONDA:?}/envs/sksurv-test/conda-meta/pinned"
diff --git a/doc/conf.py b/doc/conf.py
index d0810b0b..69293df2 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -12,7 +12,7 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-from datetime import datetime
+from datetime import datetime, UTC
 from importlib.metadata import version as get_version
 import inspect
 import os
@@ -85,7 +85,7 @@
 
 # General information about the project.
 project = "scikit-survival"
-current_year = datetime.utcnow().year
+current_year = datetime.now(UTC).year
 copyright = f"2015-{current_year}, Sebastian Pölsterl and contributors"
 
 # The version info for the project you're documenting, acts as replacement for
@@ -209,7 +209,7 @@
 }
 
 intersphinx_mapping = {
-    "sklearn": ("https://scikit-learn.org/1.3", None),
+    "sklearn": ("https://scikit-learn.org/1.4", None),
     "cython": ("https://cython.readthedocs.io/en/latest/", None),
 }
 
diff --git a/doc/install.rst b/doc/install.rst
index fd442edd..fdc7fca7 100644
--- a/doc/install.rst
+++ b/doc/install.rst
@@ -88,9 +88,9 @@ The current minimum dependencies to run scikit-survival are:
 - ecos
 - joblib
 - numexpr
-- numpy 1.17.3 or later
+- numpy
 - osqp
 - pandas 1.0.5 or later
-- scikit-learn 1.3
-- scipy 1.3.2 or later
+- scikit-learn 1.4
+- scipy
 - C/C++ compiler
diff --git a/doc/user_guide/boosting.ipynb b/doc/user_guide/boosting.ipynb
index e9e8c27e..9f28ca7c 100644
--- a/doc/user_guide/boosting.ipynb
+++ b/doc/user_guide/boosting.ipynb
@@ -405,8 +405,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Fitted base learners: 119\n",
-      "Performance on test set 0.703\n"
+      "Fitted base learners: 80\n",
+      "Performance on test set 0.715\n"
      ]
     }
    ],
@@ -440,10 +440,10 @@
     "\n",
     "\n",
     "est_early_stopping = GradientBoostingSurvivalAnalysis(\n",
-    "    n_estimators=1000, learning_rate=0.05, subsample=0.5, max_depth=1, random_state=0\n",
+    "    n_estimators=1000, learning_rate=0.1, subsample=0.5, max_depth=1, random_state=0\n",
     ")\n",
     "\n",
-    "monitor = EarlyStoppingMonitor(25, 50)\n",
+    "monitor = EarlyStoppingMonitor(10, 5)\n",
     "\n",
     "est_early_stopping.fit(X_train, y_train, monitor=monitor)\n",
     "\n",
@@ -457,7 +457,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "The monitor looks at the average improvement of the last 25 iterations, and if it was negative for the last 50 iterations, it will abort training. In this case, this occurred after 119 iterations. We can plot the improvement per base learner and the moving average."
+    "The monitor looks at the average improvement of the last 10 iterations, and if it was negative for the last 5 iterations, it will abort training. In this case, this occurred after 80 iterations. We can plot the improvement per base learner and the moving average."
    ]
   },
   {
@@ -467,14 +467,12 @@
    "outputs": [
     {
      "data": {
-      "image/png": "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\n",
+      "image/png": "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",
       "text/plain": [
        "<Figure size 432x288 with 1 Axes>"
       ]
      },
-     "metadata": {
-      "needs_background": "light"
-     },
+     "metadata": {},
      "output_type": "display_data"
     }
    ],
@@ -507,7 +505,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.5"
+   "version": "3.12.1"
   }
  },
  "nbformat": 4,
diff --git a/pyproject.toml b/pyproject.toml
index 0f1cb1d4..599af2a0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,24 +1,14 @@
 [build-system]
 requires = [
-    "setuptools>=61.0.0",
+    "setuptools>=64",
+    "setuptools-scm>=8",
     "packaging",
-    "wheel",
-    "setuptools-scm[toml]>=6.4",
-    "Cython>=0.29.16",
-
-    # arm64 on Darwin supports Python 3.8 and above requires numpy>=1.21.0
-    # (first version with arm64 wheels available)
-    "numpy==1.21.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin'",
-
-    # default numpy requirements
-    "numpy==1.19.3; python_version=='3.9' and platform_machine != 'arm64'",
-    "numpy==1.21.6; python_version=='3.10'",
-    "numpy==1.23.2; python_version=='3.11'",
-    "numpy==1.26.1; python_version=='3.12'",
-    "numpy; python_version>'3.12'",
+    # same as scikit-learn
+    "Cython>=3.0.8",
+    "numpy>=1.25",
 
     # scikit-learn requirements
-    "scikit-learn~=1.3.0; python_version<='3.12'",
+    "scikit-learn~=1.4.0; python_version<='3.12'",
     "scikit-learn; python_version>'3.12'",
 ]
 build-backend = "setuptools.build_meta"
@@ -53,14 +43,13 @@ classifiers = [
 ]
 dependencies = [
     "ecos",
-    "importlib-resources >=1.3; python_version<'3.9'",
     "joblib",
     "numexpr",
     "numpy",
     "osqp !=0.6.0,!=0.6.1",
     "pandas >=1.0.5",
     "scipy >=1.3.2",
-    "scikit-learn >=1.3.0,<1.4",
+    "scikit-learn >=1.4.0,<1.5",
 ]
 dynamic = ["version"]
 
@@ -76,12 +65,12 @@ dev = [
     "black[jupyter]",
     "build",
     "coverage",
-    "cython >=0.29",
+    "Cython >=3.0.8",
     "packaging",
     "pre-commit",
     "pytest",
     "ruff",
-    "setuptools-scm >=6.4",
+    "setuptools-scm >=8",
     "tomli",
     "tox",
 ]
@@ -144,6 +133,8 @@ filterwarnings = [
     "ignore:Attribute n is deprecated and will be removed in Python 3\\.14.*:DeprecationWarning",
     # deprecated since Python 2.2.0
     "ignore:\\nPyarrow will become a required dependency of pandas in the next major release of pandas.*:DeprecationWarning",
+    # deprecated since NumPy 1.25
+    "ignore:np\\.find_common_type is deprecated.  Please use `np\\.result_type` or `np\\.promote_types`:DeprecationWarning"
 ]
 
 [tool.coverage.run]
diff --git a/sksurv/base.py b/sksurv/base.py
index 9de386da..1c608723 100644
--- a/sksurv/base.py
+++ b/sksurv/base.py
@@ -98,3 +98,6 @@ def score(self, X, y):
 
         result = concordance_index_censored(y[name_event], y[name_time], risk_score)
         return result[0]
+
+    def _more_tags(self):
+        return {"requires_y": True}
diff --git a/sksurv/ensemble/boosting.py b/sksurv/ensemble/boosting.py
index 1ac5f48c..5e1700c9 100644
--- a/sksurv/ensemble/boosting.py
+++ b/sksurv/ensemble/boosting.py
@@ -21,10 +21,10 @@
 from sklearn.model_selection import train_test_split
 from sklearn.tree import DecisionTreeRegressor
 from sklearn.tree._tree import DTYPE
-from sklearn.utils import check_consistent_length, check_random_state, column_or_1d
+from sklearn.utils import check_random_state
 from sklearn.utils._param_validation import Interval, StrOptions
 from sklearn.utils.extmath import squared_norm
-from sklearn.utils.validation import check_is_fitted
+from sklearn.utils.validation import _check_sample_weight, check_array, check_is_fitted
 
 from ..base import SurvivalAnalysisMixin
 from ..linear_model.coxph import BreslowEstimator
@@ -113,6 +113,11 @@ class ComponentwiseGradientBoostingSurvivalAnalysis(BaseEnsemble, SurvivalAnalys
         and an increase in bias.
         Values must be in the range `(0.0, 1.0]`.
 
+    warm_start : bool, default: False
+        When set to ``True``, reuse the solution of the previous call to fit
+        and add more estimators to the ensemble, otherwise, just erase the
+        previous solution.
+
     dropout_rate : float, optional, default: 0.0
         If larger than zero, the residuals at each iteration are only computed
         from a random subset of base learners. The value corresponds to the
@@ -139,16 +144,25 @@ class ComponentwiseGradientBoostingSurvivalAnalysis(BaseEnsemble, SurvivalAnalys
     estimators_ : list of base learners
         The collection of fitted sub-estimators.
 
-    train_score_ : array, shape = (n_estimators,)
-        The i-th score ``train_score_[i]`` is the deviance (= loss) of the
+    train_score_ : ndarray, shape = (n_estimators,)
+        The i-th score ``train_score_[i]`` is the loss of the
         model at iteration ``i`` on the in-bag sample.
-        If ``subsample == 1`` this is the deviance on the training data.
+        If ``subsample == 1`` this is the loss on the training data.
 
-    oob_improvement_ : array, shape = (n_estimators,)
-        The improvement in loss (= deviance) on the out-of-bag samples
+    oob_improvement_ : ndarray, shape = (n_estimators,)
+        The improvement in loss on the out-of-bag samples
         relative to the previous iteration.
         ``oob_improvement_[0]`` is the improvement in
         loss of the first stage over the ``init`` estimator.
+        Only available if ``subsample < 1.0``.
+
+    oob_scores_ : ndarray of shape (n_estimators,)
+        The full history of the loss values on the out-of-bag
+        samples. Only available if ``subsample < 1.0``.
+
+    oob_score_ : float
+        The last value of the loss on the out-of-bag samples. It is
+        the same as ``oob_scores_[-1]``. Only available if ``subsample < 1.0``.
 
     n_features_in_ : int
         Number of features seen during ``fit``.
@@ -171,6 +185,7 @@ class ComponentwiseGradientBoostingSurvivalAnalysis(BaseEnsemble, SurvivalAnalys
         "learning_rate": [Interval(numbers.Real, 0.0, None, closed="left")],
         "n_estimators": [Interval(numbers.Integral, 1, None, closed="left")],
         "subsample": [Interval(numbers.Real, 0.0, 1.0, closed="right")],
+        "warm_start": ["boolean"],
         "dropout_rate": [Interval(numbers.Real, 0.0, 1.0, closed="left")],
         "random_state": ["random_state"],
         "verbose": ["verbose"],
@@ -183,6 +198,7 @@ def __init__(
         learning_rate=0.1,
         n_estimators=100,
         subsample=1.0,
+        warm_start=False,
         dropout_rate=0,
         random_state=None,
         verbose=0,
@@ -191,6 +207,7 @@ def __init__(
         self.n_estimators = n_estimators
         self.learning_rate = learning_rate
         self.subsample = subsample
+        self.warm_start = warm_start
         self.dropout_rate = dropout_rate
         self.random_state = random_state
         self.verbose = verbose
@@ -199,12 +216,87 @@ def __init__(
     def _predict_risk_score(self):
         return isinstance(self._loss, CoxPH)
 
-    def _fit(self, X, event, time, sample_weight, random_state):  # noqa: C901
+    def _is_fitted(self):
+        return len(getattr(self, "estimators_", [])) > 0
+
+    def _init_state(self):
+        self.estimators_ = np.empty(self.n_estimators, dtype=object)
+
+        self.train_score_ = np.zeros(self.n_estimators, dtype=np.float64)
+        # do oob?
+        if self.subsample < 1.0:
+            self.oob_improvement_ = np.zeros(self.n_estimators, dtype=np.float64)
+            self.oob_scores_ = np.zeros(self.n_estimators, dtype=np.float64)
+            self.oob_score_ = np.nan
+
+        if self.dropout_rate > 0:
+            self._scale = np.ones(int(self.n_estimators), dtype=float)
+
+    def _resize_state(self):
+        """Add additional ``n_estimators`` entries to all attributes."""
+        # self.n_estimators is the number of additional est to fit
+        total_n_estimators = self.n_estimators
+
+        self.estimators_ = np.resize(self.estimators_, total_n_estimators)
+        self.train_score_ = np.resize(self.train_score_, total_n_estimators)
+        if self.subsample < 1 or hasattr(self, "oob_improvement_"):
+            # if do oob resize arrays or create new if not available
+            if hasattr(self, "oob_improvement_"):
+                self.oob_improvement_ = np.resize(self.oob_improvement_, total_n_estimators)
+                self.oob_scores_ = np.resize(self.oob_scores_, total_n_estimators)
+                self.oob_score_ = np.nan
+            else:
+                self.oob_improvement_ = np.zeros(total_n_estimators, dtype=np.float64)
+                self.oob_scores_ = np.zeros((total_n_estimators,), dtype=np.float64)
+                self.oob_score_ = np.nan
+
+        if self.dropout_rate > 0:
+            if not hasattr(self, "_scale"):
+                raise ValueError(
+                    "fitting with warm_start=True and dropout_rate > 0 is only "
+                    "supported if the previous fit used dropout_rate > 0 too"
+                )
+
+            self._scale = np.resize(self._scale, total_n_estimators)
+            self._scale[self.n_estimators_ :] = 1
+
+    def _clear_state(self):
+        """Clear the state of the gradient boosting model."""
+        if hasattr(self, "estimators_"):
+            self.estimators_ = np.empty(0, dtype=object)
+        if hasattr(self, "train_score_"):
+            del self.train_score_
+        if hasattr(self, "oob_improvement_"):
+            del self.oob_improvement_
+        if hasattr(self, "oob_scores_"):
+            del self.oob_scores_
+        if hasattr(self, "oob_score_"):
+            del self.oob_score_
+        if hasattr(self, "_rng"):
+            del self._rng
+        if hasattr(self, "_scale"):
+            del self._scale
+
+    def _update_with_dropout(self, i, X, raw_predictions, scale, random_state):
+        # select base learners to be dropped for next iteration
+        drop_model, n_dropped = _sample_binomial_plus_one(self.dropout_rate, i + 1, random_state)
+
+        # adjust scaling factor of tree that is going to be trained in next iteration
+        scale[i + 1] = 1.0 / (n_dropped + 1.0)
+
+        raw_predictions[:] = 0
+        for m in range(i + 1):
+            if drop_model[m] == 1:
+                # adjust scaling factor of dropped trees
+                scale[m] *= n_dropped / (n_dropped + 1.0)
+            else:
+                # pseudoresponse of next iteration (without contribution of dropped trees)
+                raw_predictions += self.learning_rate * scale[m] * self.estimators_[m].predict(X)
+
+    def _fit(self, X, event, time, y_pred, sample_weight, random_state, begin_at_stage=0):  # noqa: C901
         n_samples = X.shape[0]
         # account for intercept
-        Xi = np.column_stack((np.ones(n_samples), X))
         y = np.fromiter(zip(event, time), dtype=[("event", bool), ("time", np.float64)])
-        y_pred = np.zeros(n_samples)
 
         do_oob = self.subsample < 1.0
         if do_oob:
@@ -212,55 +304,65 @@ def _fit(self, X, event, time, sample_weight, random_state):  # noqa: C901
 
         do_dropout = self.dropout_rate > 0
         if do_dropout:
-            scale = np.ones(int(self.n_estimators), dtype=float)
+            scale = self._scale
 
         if self.verbose:
             verbose_reporter = VerboseReporter(verbose=self.verbose)
             verbose_reporter.init(self, 0)
 
-        for num_iter in range(int(self.n_estimators)):
+        # perform boosting iterations
+        i = begin_at_stage
+        for i in range(begin_at_stage, int(self.n_estimators)):
+            # subsampling
             if do_oob:
                 sample_mask = _random_sample_mask(n_samples, n_inbag, random_state)
                 subsample_weight = sample_weight * sample_mask.astype(np.float64)
 
                 # OOB score before adding this stage
-                old_oob_score = self._loss(y[~sample_mask], y_pred[~sample_mask], sample_weight[~sample_mask])
+                y_oob_masked = y[~sample_mask]
+                sample_weight_oob_masked = sample_weight[~sample_mask]
+                if i == 0:  # store the initial loss to compute the OOB score
+                    initial_loss = self._loss(
+                        y_true=y_oob_masked,
+                        raw_prediction=y_pred[~sample_mask],
+                        sample_weight=sample_weight_oob_masked,
+                    )
             else:
                 subsample_weight = sample_weight
 
-            residuals = self._loss.negative_gradient(y, y_pred, sample_weight=sample_weight)
-
-            best_learner = _fit_stage_componentwise(Xi, residuals, subsample_weight)
-            self.estimators_.append(best_learner)
-
-            if do_dropout:
-                drop_model, n_dropped = _sample_binomial_plus_one(self.dropout_rate, num_iter + 1, random_state)
+            residuals = self._loss.gradient(y, y_pred, sample_weight=sample_weight)
 
-                scale[num_iter] = 1.0 / (n_dropped + 1.0)
+            best_learner = _fit_stage_componentwise(X, residuals, subsample_weight)
+            self.estimators_[i] = best_learner
 
-                y_pred[:] = 0
-                for m in range(num_iter + 1):
-                    if drop_model[m] == 1:
-                        scale[m] *= n_dropped / (n_dropped + 1.0)
-                    else:
-                        y_pred += self.learning_rate * scale[m] * self.estimators_[m].predict(Xi)
+            if do_dropout and i < len(scale) - 1:
+                self._update_with_dropout(i, X, y_pred, scale, random_state)
             else:
-                y_pred += self.learning_rate * best_learner.predict(Xi)
+                y_pred += self.learning_rate * best_learner.predict(X)
 
-            # track deviance (= loss)
+            # track loss
             if do_oob:
-                self.train_score_[num_iter] = self._loss(
-                    y[sample_mask], y_pred[sample_mask], sample_weight[sample_mask]
+                self.train_score_[i] = self._loss(
+                    y_true=y[sample_mask],
+                    raw_prediction=y_pred[sample_mask],
+                    sample_weight=sample_weight[sample_mask],
                 )
-                self.oob_improvement_[num_iter] = old_oob_score - self._loss(
-                    y[~sample_mask], y_pred[~sample_mask], sample_weight[~sample_mask]
+                self.oob_scores_[i] = self._loss(
+                    y_true=y_oob_masked,
+                    raw_prediction=y_pred[~sample_mask],
+                    sample_weight=sample_weight_oob_masked,
                 )
+                previous_loss = initial_loss if i == 0 else self.oob_scores_[i - 1]
+                self.oob_improvement_[i] = previous_loss - self.oob_scores_[i]
+                self.oob_score_ = self.oob_scores_[-1]
             else:
                 # no need to fancy index w/ no subsampling
-                self.train_score_[num_iter] = self._loss(y, y_pred, sample_weight)
+                self.train_score_[i] = self._loss(y_true=y, raw_prediction=y_pred, sample_weight=sample_weight)
 
             if self.verbose > 0:
-                verbose_reporter.update(num_iter, self)
+                verbose_reporter.update(i, self)
+
+        return i + 1
 
     def fit(self, X, y, sample_weight=None):
         """Fit estimator.
@@ -282,49 +384,71 @@ def fit(self, X, y, sample_weight=None):
         -------
         self
         """
-        X = self._validate_data(X, ensure_min_samples=2)
-        event, time = check_array_survival(X, y)
+        self._validate_params()
 
-        n_samples = X.shape[0]
+        if not self.warm_start:
+            self._clear_state()
 
-        if sample_weight is None:
-            sample_weight = np.ones(n_samples, dtype=np.float32)
-        else:
-            sample_weight = column_or_1d(sample_weight, warn=True)
-            check_consistent_length(X, sample_weight)
+        X = self._validate_data(X, ensure_min_samples=2)
+        event, time = check_array_survival(X, y)
 
-        random_state = check_random_state(self.random_state)
+        sample_weight = _check_sample_weight(sample_weight, X)
 
-        self._validate_params()
+        n_samples = X.shape[0]
+        Xi = np.column_stack((np.ones(n_samples), X))
 
-        self.estimators_ = []
         self._loss = LOSS_FUNCTIONS[self.loss]()
         if isinstance(self._loss, (CensoredSquaredLoss, IPCWLeastSquaresError)):
             time = np.log(time)
 
-        self.train_score_ = np.zeros((self.n_estimators,), dtype=np.float64)
-        # do oob?
-        if self.subsample < 1.0:
-            self.oob_improvement_ = np.zeros(self.n_estimators, dtype=np.float64)
+        if not self._is_fitted():
+            self._init_state()
+
+            y_pred = np.zeros(n_samples, dtype=np.float64)
 
-        self._fit(X, event, time, sample_weight, random_state)
+            begin_at_stage = 0
 
+            self._rng = check_random_state(self.random_state)
+        else:
+            # add more estimators to fitted model
+            # invariant: warm_start = True
+            if self.n_estimators < self.estimators_.shape[0]:
+                raise ValueError(
+                    "n_estimators=%d must be larger or equal to "
+                    "estimators_.shape[0]=%d when "
+                    "warm_start==True" % (self.n_estimators, self.estimators_.shape[0])
+                )
+            begin_at_stage = self.estimators_.shape[0]
+            y_pred = self._raw_predict(Xi)
+            self._resize_state()
+
+            # apply dropout to last stage of previous fit
+            if hasattr(self, "_scale") and self.dropout_rate > 0:
+                # pylint: disable-next=access-member-before-definition
+                self._update_with_dropout(self.n_estimators_ - 1, Xi, y_pred, self._scale, self._rng)
+
+        self.n_estimators_ = self._fit(Xi, event, time, y_pred, sample_weight, self._rng, begin_at_stage)
+
+        self._set_baseline_model(X, event, time)
+        return self
+
+    def _set_baseline_model(self, X, event, time):
         if isinstance(self._loss, CoxPH):
             risk_scores = self._predict(X)
             self._baseline_model = BreslowEstimator().fit(risk_scores, event, time)
         else:
             self._baseline_model = None
 
-        return self
-
-    def _predict(self, X):
-        n_samples = X.shape[0]
-        Xi = np.column_stack((np.ones(n_samples), X))
-        pred = np.zeros(n_samples, dtype=float)
-
+    def _raw_predict(self, X):
+        pred = np.zeros(X.shape[0], dtype=float)
         for estimator in self.estimators_:
-            pred += self.learning_rate * estimator.predict(Xi)
+            pred += self.learning_rate * estimator.predict(X)
+        return pred
 
+    def _predict(self, X):
+        # account for intercept
+        Xi = np.column_stack((np.ones(X.shape[0]), X))
+        pred = self._raw_predict(Xi)
         return self._loss._scale_raw_prediction(pred)
 
     def predict(self, X):
@@ -647,6 +771,11 @@ class GradientBoostingSurvivalAnalysis(BaseGradientBoosting, SurvivalAnalysisMix
         Values must be in the range `[2, inf)`.
         If `None`, then unlimited number of leaf nodes.
 
+    warm_start : bool, default: False
+        When set to ``True``, reuse the solution of the previous call to fit
+        and add more estimators to the ensemble, otherwise, just erase the
+        previous solution.
+
     validation_fraction : float, default: 0.1
         The proportion of training data to set aside as validation set for
         early stopping. Values must be in the range `(0.0, 1.0)`.
@@ -702,15 +831,24 @@ class GradientBoostingSurvivalAnalysis(BaseGradientBoosting, SurvivalAnalysisMix
         The collection of fitted sub-estimators.
 
     train_score_ : ndarray, shape = (n_estimators,)
-        The i-th score ``train_score_[i]`` is the deviance (= loss) of the
+        The i-th score ``train_score_[i]`` is the loss of the
         model at iteration ``i`` on the in-bag sample.
-        If ``subsample == 1`` this is the deviance on the training data.
+        If ``subsample == 1`` this is the loss on the training data.
 
     oob_improvement_ : ndarray, shape = (n_estimators,)
-        The improvement in loss (= deviance) on the out-of-bag samples
+        The improvement in loss on the out-of-bag samples
         relative to the previous iteration.
         ``oob_improvement_[0]`` is the improvement in
         loss of the first stage over the ``init`` estimator.
+        Only available if ``subsample < 1.0``.
+
+    oob_scores_ : ndarray of shape (n_estimators,)
+        The full history of the loss values on the out-of-bag
+        samples. Only available if ``subsample < 1.0``.
+
+    oob_score_ : float
+        The last value of the loss on the out-of-bag samples. It is
+        the same as ``oob_scores_[-1]``. Only available if ``subsample < 1.0``.
 
     n_features_in_ : int
         Number of features seen during ``fit``.
@@ -719,9 +857,17 @@ class GradientBoostingSurvivalAnalysis(BaseGradientBoosting, SurvivalAnalysisMix
         Names of features seen during ``fit``. Defined only when `X`
         has feature names that are all strings.
 
+    max_features_ : int
+        The inferred value of max_features.
+
     unique_times_ : array of shape = (n_unique_times,)
         Unique time points.
 
+    See also
+    --------
+    sksurv.ensemble.ComponentwiseGradientBoostingSurvivalAnalysis
+        Gradient boosting with component-wise least squares as base learner.
+
     References
     ----------
     .. [1] J. H. Friedman, "Greedy function approximation: A gradient boosting machine,"
@@ -760,6 +906,7 @@ def __init__(
         random_state=None,
         max_features=None,
         max_leaf_nodes=None,
+        warm_start=False,
         validation_fraction=0.1,
         n_iter_no_change=None,
         tol=1e-4,
@@ -776,12 +923,13 @@ def __init__(
             min_samples_leaf=min_samples_leaf,
             min_weight_fraction_leaf=min_weight_fraction_leaf,
             max_depth=max_depth,
-            init=None,
+            init="zero",
             subsample=subsample,
             max_features=max_features,
             random_state=random_state,
             verbose=verbose,
             max_leaf_nodes=max_leaf_nodes,
+            warm_start=warm_start,
             min_impurity_decrease=min_impurity_decrease,
             validation_fraction=validation_fraction,
             n_iter_no_change=n_iter_no_change,
@@ -790,27 +938,19 @@ def __init__(
         )
         self.dropout_rate = dropout_rate
 
-    def _warn_mae_for_criterion(self):
-        pass
+    def _encode_y(self, y, sample_weight):
+        self.n_trees_per_iteration_ = 1
+        return y
 
-    def _validate_y(self, y, sample_weight):
-        pass
+    def _get_loss(self, sample_weight):
+        return LOSS_FUNCTIONS[self.loss]()
 
     @property
     def _predict_risk_score(self):
         return isinstance(self._loss, CoxPH)
 
-    def _check_params(self):
-        """Check validity of parameters and raise ValueError if not valid."""
-        self._validate_params()
-
-        max_features = self._check_max_features()
-
-        self.max_features_ = max_features
-
-        self._loss = LOSS_FUNCTIONS[self.loss]()
-
-    def _check_max_features(self):
+    def _set_max_features(self):
+        """Set self.max_features_."""
         if isinstance(self.max_features, str):
             if self.max_features == "sqrt":
                 max_features = max(1, int(np.sqrt(self.n_features_in_)))
@@ -821,10 +961,25 @@ def _check_max_features(self):
         elif isinstance(self.max_features, (numbers.Integral, np.integer)):
             max_features = self.max_features
         else:  # float
-            if 0.0 < self.max_features <= 1.0:
-                max_features = max(int(self.max_features * self.n_features_in_), 1)
+            max_features = max(1, int(self.max_features * self.n_features_in_))
 
-        return max_features
+        self.max_features_ = max_features
+
+    def _update_with_dropout(self, i, X, raw_predictions, k, scale, random_state):
+        # select base learners to be dropped for next iteration
+        drop_model, n_dropped = _sample_binomial_plus_one(self.dropout_rate, i + 1, random_state)
+
+        # adjust scaling factor of tree that is going to be trained in next iteration
+        scale[i + 1] = 1.0 / (n_dropped + 1.0)
+
+        raw_predictions[:, k] = 0
+        for m in range(i + 1):
+            if drop_model[m] == 1:
+                # adjust scaling factor of dropped trees
+                scale[m] *= n_dropped / (n_dropped + 1.0)
+            else:
+                # pseudoresponse of next iteration (without contribution of dropped trees)
+                raw_predictions[:, k] += self.learning_rate * scale[m] * self.estimators_[m, k].predict(X).ravel()
 
     def _fit_stage(
         self,
@@ -842,10 +997,9 @@ def _fit_stage(
         """Fit another stage of ``n_classes_`` trees to the boosting model."""
 
         assert sample_mask.dtype == bool
-        loss = self._loss
 
         # whether to use dropout in next iteration
-        do_dropout = self.dropout_rate > 0.0 and 0 < i < len(scale) - 1
+        do_dropout = self.dropout_rate > 0.0 and i < len(scale) - 1
 
         # Need to pass a copy of raw_predictions to negative_gradient()
         # because raw_predictions is partially updated at the end of the loop
@@ -853,10 +1007,14 @@ def _fit_stage(
         # iteration i - 1.
         raw_predictions_copy = raw_predictions.copy()
 
-        for k in range(loss.K):
-            residual = loss.negative_gradient(y, raw_predictions_copy, k=k, sample_weight=sample_weight)
+        neg_gradient = self._loss.gradient(
+            y_true=y,
+            raw_prediction=raw_predictions_copy,
+            sample_weight=None,  # We pass sample_weights to the tree directly.
+        )
 
-            # induce regression tree on residuals
+        for k in range(self.n_trees_per_iteration_):
+            # induce regression tree on the negative gradient
             tree = DecisionTreeRegressor(
                 criterion=self.criterion,
                 splitter="best",
@@ -875,37 +1033,23 @@ def _fit_stage(
                 # no inplace multiplication!
                 sample_weight = sample_weight * sample_mask.astype(np.float64)
 
-            X = X_csr if X_csr is not None else X
-            tree.fit(X, residual, sample_weight=sample_weight, check_input=False)
+            X = X_csc if X_csc is not None else X
+            tree.fit(X, neg_gradient, sample_weight=sample_weight, check_input=False)
 
             # add tree to ensemble
             self.estimators_[i, k] = tree
 
             # update tree leaves
             if do_dropout:
-                # select base learners to be dropped for next iteration
-                drop_model, n_dropped = _sample_binomial_plus_one(self.dropout_rate, i + 1, random_state)
-
-                # adjust scaling factor of tree that is going to be trained in next iteration
-                scale[i + 1] = 1.0 / (n_dropped + 1.0)
-
-                raw_predictions[:, k] = 0
-                for m in range(i + 1):
-                    if drop_model[m] == 1:
-                        # adjust scaling factor of dropped trees
-                        scale[m] *= n_dropped / (n_dropped + 1.0)
-                    else:
-                        # pseudoresponse of next iteration (without contribution of dropped trees)
-                        raw_predictions[:, k] += (
-                            self.learning_rate * scale[m] * self.estimators_[m, k].predict(X).ravel()
-                        )
+                self._update_with_dropout(i, X, raw_predictions, k, scale, random_state)
             else:
                 # update tree leaves
-                loss.update_terminal_regions(
+                X_for_tree_update = X_csr if X_csr is not None else X
+                self._loss.update_terminal_regions(
                     tree.tree_,
-                    X,
+                    X_for_tree_update,
                     y,
-                    residual,
+                    neg_gradient,
                     raw_predictions,
                     sample_weight,
                     sample_mask,
@@ -925,6 +1069,7 @@ def _fit_stages(  # noqa: C901
         X_val,
         y_val,
         sample_weight_val,
+        scale,
         begin_at_stage=0,
         monitor=None,
     ):
@@ -939,7 +1084,6 @@ def _fit_stages(  # noqa: C901
         do_oob = self.subsample < 1.0
         sample_mask = np.ones((n_samples,), dtype=bool)
         n_inbag = max(1, int(self.subsample * n_samples))
-        loss_ = self._loss
 
         if self.verbose:
             verbose_reporter = VerboseReporter(verbose=self.verbose)
@@ -948,11 +1092,6 @@ def _fit_stages(  # noqa: C901
         X_csc = csc_matrix(X) if issparse(X) else None
         X_csr = csr_matrix(X) if issparse(X) else None
 
-        if self.dropout_rate > 0.0:
-            scale = np.ones(self.n_estimators, dtype=float)
-        else:
-            scale = None
-
         if self.n_iter_no_change is not None:
             loss_history = np.full(self.n_iter_no_change, np.inf)
             # We create a generator to get the predictions for X_val after
@@ -966,12 +1105,14 @@ def _fit_stages(  # noqa: C901
             if do_oob:
                 sample_mask = _random_sample_mask(n_samples, n_inbag, random_state)
                 # OOB score before adding this stage
-                y_oob_sample = y[~sample_mask]
-                old_oob_score = loss_(
-                    y_oob_sample,
-                    raw_predictions[~sample_mask],
-                    sample_weight[~sample_mask],
-                )
+                y_oob_masked = y[~sample_mask]
+                sample_weight_oob_masked = sample_weight[~sample_mask]
+                if i == 0:  # store the initial loss to compute the OOB score
+                    initial_loss = self._loss(
+                        y_true=y_oob_masked,
+                        raw_prediction=raw_predictions[~sample_mask],
+                        sample_weight=sample_weight_oob_masked,
+                    )
 
             # fit next stage of trees
             raw_predictions = self._fit_stage(
@@ -983,25 +1124,28 @@ def _fit_stages(  # noqa: C901
                 sample_mask,
                 random_state,
                 scale,
-                X_csc,
-                X_csr,
+                X_csc=X_csc,
+                X_csr=X_csr,
             )
 
-            # track deviance (= loss)
+            # track loss
             if do_oob:
-                self.train_score_[i] = loss_(
-                    y[sample_mask],
-                    raw_predictions[sample_mask],
-                    sample_weight[sample_mask],
+                self.train_score_[i] = self._loss(
+                    y_true=y[sample_mask],
+                    raw_prediction=raw_predictions[sample_mask],
+                    sample_weight=sample_weight[sample_mask],
                 )
-                self.oob_improvement_[i] = old_oob_score - loss_(
-                    y_oob_sample,
-                    raw_predictions[~sample_mask],
-                    sample_weight[~sample_mask],
+                self.oob_scores_[i] = self._loss(
+                    y_true=y_oob_masked,
+                    raw_prediction=raw_predictions[~sample_mask],
+                    sample_weight=sample_weight_oob_masked,
                 )
+                previous_loss = initial_loss if i == 0 else self.oob_scores_[i - 1]
+                self.oob_improvement_[i] = previous_loss - self.oob_scores_[i]
+                self.oob_score_ = self.oob_scores_[-1]
             else:
                 # no need to fancy index w/ no subsampling
-                self.train_score_[i] = loss_(y, raw_predictions, sample_weight)
+                self.train_score_[i] = self._loss(y_true=y, raw_prediction=raw_predictions, sample_weight=sample_weight)
 
             if self.verbose > 0:
                 verbose_reporter.update(i, self)
@@ -1016,7 +1160,7 @@ def _fit_stages(  # noqa: C901
             if self.n_iter_no_change is not None:
                 # By calling next(y_val_pred_iter), we get the predictions
                 # for X_val after the addition of the current stage
-                validation_loss = loss_(y_val, next(y_val_pred_iter), sample_weight_val)
+                validation_loss = self._loss(y_val, next(y_val_pred_iter), sample_weight_val)
 
                 # Require validation_score to be better (less) than at least
                 # one of the last n_iter_no_change evaluations
@@ -1025,10 +1169,36 @@ def _fit_stages(  # noqa: C901
                 else:
                     break
 
+        return i + 1
+
+    def _init_state(self):
+        super()._init_state()
+
         if self.dropout_rate > 0.0:
-            self.scale_ = scale
+            self._scale = np.ones(self.n_estimators, dtype=float)
 
-        return i + 1
+    def _resize_state(self):
+        super()._resize_state()
+
+        if self.dropout_rate > 0:
+            if not hasattr(self, "_scale"):
+                raise ValueError(
+                    "fitting with warm_start=True and dropout_rate > 0 is only "
+                    "supported if the previous fit used dropout_rate > 0 too"
+                )
+
+            self._scale = np.resize(self._scale, self.n_estimators)
+            self._scale[self.n_estimators_ :] = 1
+
+    def _shrink_state(self, n_stages):
+        self.estimators_ = self.estimators_[:n_stages]
+        self.train_score_ = self.train_score_[:n_stages]
+        if hasattr(self, "oob_improvement_"):
+            self.oob_improvement_ = self.oob_improvement_[:n_stages]
+            self.oob_scores_ = self.oob_scores_[:n_stages]
+            self.oob_score_ = self.oob_scores_[-1]
+        if hasattr(self, "_scale"):
+            self._scale = self._scale[:n_stages]
 
     def fit(self, X, y, sample_weight=None, monitor=None):
         """Fit the gradient boosting model.
@@ -1060,6 +1230,11 @@ def fit(self, X, y, sample_weight=None, monitor=None):
         self : object
             Returns self.
         """
+        self._validate_params()
+
+        if not self.warm_start:
+            self._clear_state()
+
         X = self._validate_data(
             X,
             ensure_min_samples=2,
@@ -1068,23 +1243,34 @@ def fit(self, X, y, sample_weight=None, monitor=None):
             dtype=DTYPE,
         )
         event, time = check_array_survival(X, y)
-        n_samples = X.shape[0]
 
         sample_weight_is_none = sample_weight is None
+        sample_weight = _check_sample_weight(sample_weight, X)
+
         if sample_weight_is_none:
-            sample_weight = np.ones(n_samples, dtype=np.float32)
+            y = self._encode_y(y=y, sample_weight=None)
         else:
-            sample_weight = column_or_1d(sample_weight, warn=True)
+            y = self._encode_y(y=y, sample_weight=sample_weight)
 
-        check_consistent_length(X, sample_weight)
+        self._set_max_features()
 
-        self._check_params()
+        # self.loss is guaranteed to be a string
+        self._loss = self._get_loss(sample_weight=sample_weight)
 
         if isinstance(self._loss, (CensoredSquaredLoss, IPCWLeastSquaresError)):
             time = np.log(time)
 
         if self.n_iter_no_change is not None:
-            X, X_val, event, event_val, time, time_val, sample_weight, sample_weight_val = train_test_split(
+            (
+                X_train,
+                X_val,
+                event_train,
+                event_val,
+                time_train,
+                time_val,
+                sample_weight_train,
+                sample_weight_val,
+            ) = train_test_split(
                 X,
                 event,
                 time,
@@ -1095,43 +1281,91 @@ def fit(self, X, y, sample_weight=None, monitor=None):
             )
             y_val = np.fromiter(zip(event_val, time_val), dtype=[("event", bool), ("time", np.float64)])
         else:
+            X_train, sample_weight_train = X, sample_weight
+            event_train, time_train = event, time
             X_val = y_val = sample_weight_val = None
 
-        self._init_state()
-        if sample_weight_is_none:
-            self.init_.fit(X, (event, time))
-        else:
-            self.init_.fit(X, (event, time), sample_weight)
+        y_train = np.fromiter(zip(event_train, time_train), dtype=[("event", bool), ("time", np.float64)])
+        n_samples = X_train.shape[0]
+
+        # First time calling fit.
+        if not self._is_fitted():
+            # init state
+            self._init_state()
+
+            raw_predictions = np.zeros(
+                shape=(n_samples, self.n_trees_per_iteration_),
+                dtype=np.float64,
+            )
 
-        raw_predictions = self._loss.get_init_raw_predictions(X, self.init_)
-        begin_at_stage = 0
+            begin_at_stage = 0
 
-        # The rng state must be preserved if warm_start is True
-        self._rng = check_random_state(self.random_state)
+            # The rng state must be preserved if warm_start is True
+            self._rng = check_random_state(self.random_state)
+
+        # warm start: this is not the first time fit was called
+        else:
+            # add more estimators to fitted model
+            # invariant: warm_start = True
+            if self.n_estimators < self.estimators_.shape[0]:
+                raise ValueError(
+                    "n_estimators=%d must be larger or equal to "
+                    "estimators_.shape[0]=%d when "
+                    "warm_start==True" % (self.n_estimators, self.estimators_.shape[0])
+                )
+            begin_at_stage = self.estimators_.shape[0]
+            # The requirements of _raw_predict
+            # are more constrained than fit. It accepts only CSR
+            # matrices. Finite values have already been checked in _validate_data.
+            X_train = check_array(
+                X_train,
+                dtype=DTYPE,
+                order="C",
+                accept_sparse="csr",
+                force_all_finite=False,
+            )
+            raw_predictions = self._raw_predict(X_train)
+            self._resize_state()
+
+            # apply dropout to last stage of previous fit
+            if hasattr(self, "_scale") and self.dropout_rate > 0:
+                for k in range(self.n_trees_per_iteration_):
+                    self._update_with_dropout(
+                        # pylint: disable-next=access-member-before-definition
+                        self.n_estimators_ - 1,
+                        X_train,
+                        raw_predictions,
+                        k,
+                        self._scale,
+                        self._rng,
+                    )
+
+        scale = getattr(self, "_scale", None)
 
         # fit the boosting stages
-        y = np.fromiter(zip(event, time), dtype=[("event", bool), ("time", np.float64)])
         n_stages = self._fit_stages(
-            X,
-            y,
+            X_train,
+            y_train,
             raw_predictions,
-            sample_weight,
+            sample_weight_train,
             self._rng,
             X_val,
             y_val,
             sample_weight_val,
+            scale,
             begin_at_stage,
             monitor,
         )
         # change shape of arrays after fit (early-stopping or additional tests)
         if n_stages != self.estimators_.shape[0]:
-            self.estimators_ = self.estimators_[:n_stages]
-            self.train_score_ = self.train_score_[:n_stages]
-            if hasattr(self, "oob_improvement_"):
-                self.oob_improvement_ = self.oob_improvement_[:n_stages]
-
+            self._shrink_state(n_stages)
         self.n_estimators_ = n_stages
 
+        self._set_baseline_model(X_train, event_train, time_train)
+
+        return self
+
+    def _set_baseline_model(self, X, event, time):
         if isinstance(self._loss, CoxPH):
             X_pred = X
             if issparse(X):
@@ -1141,12 +1375,10 @@ def fit(self, X, y, sample_weight=None, monitor=None):
         else:
             self._baseline_model = None
 
-        return self
-
     def _dropout_predict_stage(self, X, i, K, score):
         for k in range(K):
             tree = self.estimators_[i, k].tree_
-            score += self.learning_rate * self.scale_[i] * tree.predict(X).reshape((-1, 1))
+            score += self.learning_rate * self._scale[i] * tree.predict(X).reshape((-1, 1))
         return score
 
     def _dropout_raw_predict(self, X):
@@ -1170,7 +1402,7 @@ def _dropout_staged_raw_predict(self, X):
     def _raw_predict(self, X):
         # if dropout wasn't used during training, proceed as usual,
         # otherwise consider scaling factor of individual trees
-        if not hasattr(self, "scale_"):
+        if not hasattr(self, "_scale"):
             return super()._raw_predict(X)
         return self._dropout_raw_predict(X)
 
@@ -1235,7 +1467,7 @@ def staged_predict(self, X):
 
         # if dropout wasn't used during training, proceed as usual,
         # otherwise consider scaling factor of individual trees
-        if not hasattr(self, "scale_"):
+        if not hasattr(self, "_scale"):
             predictions_iter = self._staged_raw_predict(X)
         else:
             predictions_iter = self._dropout_staged_raw_predict(X)
diff --git a/sksurv/ensemble/forest.py b/sksurv/ensemble/forest.py
index 5deba39a..ef9acd18 100644
--- a/sksurv/ensemble/forest.py
+++ b/sksurv/ensemble/forest.py
@@ -14,11 +14,12 @@
     _parallel_build_trees,
 )
 from sklearn.tree._tree import DTYPE
+from sklearn.utils._tags import _safe_tags
 from sklearn.utils.validation import check_is_fitted, check_random_state
 
 from ..base import SurvivalAnalysisMixin
 from ..metrics import concordance_index_censored
-from ..tree import SurvivalTree
+from ..tree import ExtraSurvivalTree, SurvivalTree
 from ..tree._criterion import get_unique_times
 from ..tree.tree import _array_to_step_function
 from ..util import check_array_survival
@@ -28,7 +29,21 @@
 MAX_INT = np.iinfo(np.int32).max
 
 
-class _BaseSurvivalForest(BaseForest, SurvivalAnalysisMixin, metaclass=ABCMeta):
+def _more_tags_patch(self):
+    # BaseForest._more_tags calls
+    # type(self.estimator)(criterion=self.criterions),
+    # which is incompatible with LogrankCriterion
+    if isinstance(self, _BaseSurvivalForest):
+        estimator = type(self.estimator)()
+    else:
+        estimator = type(self.estimator)(criterion=self.criterion)
+    return {"allow_nan": _safe_tags(estimator, key="allow_nan")}
+
+
+BaseForest._more_tags = _more_tags_patch
+
+
+class _BaseSurvivalForest(BaseForest, metaclass=ABCMeta):
     """
     Base class for forest-based estimators for survival analysis.
 
@@ -89,9 +104,17 @@ def fit(self, X, y, sample_weight=None):
         """
         self._validate_params()
 
-        X = self._validate_data(X, dtype=DTYPE, accept_sparse="csc", ensure_min_samples=2)
+        X = self._validate_data(X, dtype=DTYPE, accept_sparse="csc", ensure_min_samples=2, force_all_finite=False)
         event, time = check_array_survival(X, y)
 
+        # _compute_missing_values_in_feature_mask checks if X has missing values and
+        # will raise an error if the underlying tree base estimator can't handle missing
+        # values.
+        estimator = type(self.estimator)()
+        missing_values_in_feature_mask = estimator._compute_missing_values_in_feature_mask(
+            X, estimator_name=self.__class__.__name__
+        )
+
         self.n_features_in_ = X.shape[1]
         time = time.astype(np.float64)
         self.unique_times_, self.is_event_time_ = get_unique_times(time, event)
@@ -156,6 +179,7 @@ def fit(self, X, y, sample_weight=None):
                     len(trees),
                     verbose=self.verbose,
                     n_samples_bootstrap=n_samples_bootstrap,
+                    missing_values_in_feature_mask=missing_values_in_feature_mask,
                 )
                 for i, t in enumerate(trees)
             )
@@ -268,7 +292,7 @@ def predict_survival_function(self, X, return_array=False):
         return _array_to_step_function(self.unique_times_, arr)
 
 
-class RandomSurvivalForest(_BaseSurvivalForest):
+class RandomSurvivalForest(SurvivalAnalysisMixin, _BaseSurvivalForest):
     """A random survival forest.
 
     A random survival forest is a meta estimator that fits a number of
@@ -776,7 +800,7 @@ def __init__(
         low_memory=False,
     ):
         super().__init__(
-            estimator=SurvivalTree(splitter="random"),
+            estimator=ExtraSurvivalTree(),
             n_estimators=n_estimators,
             estimator_params=(
                 "max_depth",
diff --git a/sksurv/ensemble/survival_loss.py b/sksurv/ensemble/survival_loss.py
index 05792076..2cd41bda 100644
--- a/sksurv/ensemble/survival_loss.py
+++ b/sksurv/ensemble/survival_loss.py
@@ -13,33 +13,19 @@
 from abc import ABCMeta
 
 import numpy as np
-from sklearn.dummy import DummyRegressor
-from sklearn.ensemble._gb_losses import RegressionLossFunction
+from sklearn._loss.link import IdentityLink
+from sklearn._loss.loss import BaseLoss
 from sklearn.utils.extmath import squared_norm
 
 from ..nonparametric import ipc_weights
 from ._coxph_loss import coxph_loss, coxph_negative_gradient
 
 
-class DummySurvivalEstimator(DummyRegressor):
-    def __init__(self, strategy="mean", constant=None, quantile=None):
-        super().__init__(
-            strategy=strategy,
-            constant=constant,
-            quantile=quantile,
-        )
-
-    def fit(self, X, y, sample_weight=None):
-        _, time = y
-        return super().fit(X, time, sample_weight=sample_weight)
-
-
-class SurvivalLossFunction(RegressionLossFunction, metaclass=ABCMeta):  # noqa: B024
+class SurvivalLossFunction(BaseLoss, metaclass=ABCMeta):  # noqa: B024
     """Base class for survival loss functions."""
 
-    # pylint: disable=abstract-method,no-self-use
-    def init_estimator(self):
-        return DummySurvivalEstimator(strategy="constant", constant=0.0)
+    def __init__(self, sample_weight=None):
+        super().__init__(closs=None, link=IdentityLink())
 
 
 class CoxPH(SurvivalLossFunction):
@@ -47,12 +33,12 @@ class CoxPH(SurvivalLossFunction):
 
     # pylint: disable=no-self-use
 
-    def __call__(self, y, raw_predictions, sample_weight=None):  # pylint: disable=unused-argument
+    def __call__(self, y_true, raw_prediction, sample_weight=None):  # pylint: disable=unused-argument
         """Compute the partial likelihood of prediction ``y_pred`` and ``y``."""
         # TODO add support for sample weights
-        return coxph_loss(y["event"].astype(np.uint8), y["time"], raw_predictions.ravel())
+        return coxph_loss(y_true["event"].astype(np.uint8), y_true["time"], raw_prediction.ravel())
 
-    def negative_gradient(self, y, raw_predictions, sample_weight=None, **kwargs):  # pylint: disable=unused-argument
+    def gradient(self, y_true, raw_prediction, sample_weight=None, **kwargs):  # pylint: disable=unused-argument
         """Negative gradient of partial likelihood
 
         Parameters
@@ -62,7 +48,7 @@ def negative_gradient(self, y, raw_predictions, sample_weight=None, **kwargs):
         y_pred : np.ndarray, shape=(n,):
             The predictions.
         """
-        ret = coxph_negative_gradient(y["event"].astype(np.uint8), y["time"], raw_predictions.ravel())
+        ret = coxph_negative_gradient(y_true["event"].astype(np.uint8), y_true["time"], raw_prediction.ravel())
         if sample_weight is not None:
             ret *= sample_weight
         return ret
@@ -93,13 +79,13 @@ class CensoredSquaredLoss(SurvivalLossFunction):
     """
 
     # pylint: disable=no-self-use
-    def __call__(self, y, raw_predictions, sample_weight=None):
+    def __call__(self, y_true, raw_prediction, sample_weight=None):
         """Compute the partial likelihood of prediction ``y_pred`` and ``y``."""
-        pred_time = y["time"] - raw_predictions.ravel()
-        mask = (pred_time > 0) | y["event"]
+        pred_time = y_true["time"] - raw_prediction.ravel()
+        mask = (pred_time > 0) | y_true["event"]
         return 0.5 * squared_norm(pred_time.compress(mask, axis=0))
 
-    def negative_gradient(self, y, raw_predictions, **kwargs):  # pylint: disable=unused-argument
+    def gradient(self, y_true, raw_prediction, **kwargs):  # pylint: disable=unused-argument
         """Negative gradient of partial likelihood
 
         Parameters
@@ -109,9 +95,9 @@ def negative_gradient(self, y, raw_predictions, **kwargs):  # pylint: disable=un
         y_pred : np.ndarray, shape=(n,):
             The predictions.
         """
-        pred_time = y["time"] - raw_predictions.ravel()
-        mask = (pred_time > 0) | y["event"]
-        ret = np.zeros(y["event"].shape[0])
+        pred_time = y_true["time"] - raw_prediction.ravel()
+        mask = (pred_time > 0) | y_true["event"]
+        ret = np.zeros(y_true["event"].shape[0])
         ret[mask] = pred_time.compress(mask, axis=0)
         return ret
 
@@ -138,12 +124,12 @@ class IPCWLeastSquaresError(SurvivalLossFunction):
 
     # pylint: disable=no-self-use
 
-    def __call__(self, y, raw_predictions, sample_weight=None):
-        sample_weight = ipc_weights(y["event"], y["time"])
-        return 1.0 / sample_weight.sum() * np.sum(sample_weight * ((y["time"] - raw_predictions.ravel()) ** 2.0))
+    def __call__(self, y_true, raw_prediction, sample_weight=None):
+        sample_weight = ipc_weights(y_true["event"], y_true["time"])
+        return 1.0 / sample_weight.sum() * np.sum(sample_weight * ((y_true["time"] - raw_prediction.ravel()) ** 2.0))
 
-    def negative_gradient(self, y, raw_predictions, **kwargs):  # pylint: disable=unused-argument
-        return y["time"] - raw_predictions.ravel()
+    def gradient(self, y_true, raw_prediction, **kwargs):  # pylint: disable=unused-argument
+        return y_true["time"] - raw_prediction.ravel()
 
     def update_terminal_regions(self, tree, X, y, residual, y_pred, sample_weight, sample_mask, learning_rate=0.1, k=0):
         y_pred[:, k] += learning_rate * tree.predict(X).ravel()
diff --git a/sksurv/tree/__init__.py b/sksurv/tree/__init__.py
index c66afd5c..5549821e 100644
--- a/sksurv/tree/__init__.py
+++ b/sksurv/tree/__init__.py
@@ -1,1 +1,1 @@
-from .tree import SurvivalTree  # noqa: F401
+from .tree import ExtraSurvivalTree, SurvivalTree  # noqa: F401
diff --git a/sksurv/tree/_criterion.pyx b/sksurv/tree/_criterion.pyx
index 42f471c8..9025cec5 100644
--- a/sksurv/tree/_criterion.pyx
+++ b/sksurv/tree/_criterion.pyx
@@ -13,16 +13,16 @@ cimport numpy as cnp
 cnp.import_array()
 
 from sklearn.tree._criterion cimport Criterion
-from sklearn.tree._tree cimport DOUBLE_t, SIZE_t
+from sklearn.utils._typedefs cimport float64_t, intp_t
 
 
-cpdef get_unique_times(cnp.ndarray[DOUBLE_t, ndim=1] time, cnp.ndarray[cnp.npy_bool, ndim=1] event):
+cpdef get_unique_times(cnp.ndarray[float64_t, ndim=1] time, cnp.ndarray[cnp.npy_bool, ndim=1] event):
     cdef:
-        SIZE_t[:] order = cnp.PyArray_ArgSort(time, 0, cnp.NPY_MERGESORT)
-        DOUBLE_t value
-        DOUBLE_t last_value = NAN
-        SIZE_t i
-        SIZE_t idx
+        intp_t[:] order = cnp.PyArray_ArgSort(time, 0, cnp.NPY_MERGESORT)
+        float64_t value
+        float64_t last_value = NAN
+        intp_t i
+        intp_t idx
         list unique_values = []
         list has_event = []
 
@@ -41,14 +41,14 @@ cpdef get_unique_times(cnp.ndarray[DOUBLE_t, ndim=1] time, cnp.ndarray[cnp.npy_b
 
 cdef class RisksetCounter:
     cdef:
-        const DOUBLE_t[:] unique_times
+        const float64_t[:] unique_times
         cnp.npy_int64 * n_events
         cnp.npy_int64 * n_at_risk
-        const DOUBLE_t[:, ::1] data
-        size_t nbytes
+        const float64_t[:, ::1] data
+        intp_t nbytes
 
-    def __cinit__(self, const DOUBLE_t[:] unique_times):
-        cdef SIZE_t n_unique_times = unique_times.shape[0]
+    def __cinit__(self, const float64_t[:] unique_times):
+        cdef intp_t n_unique_times = unique_times.shape[0]
         self.nbytes = n_unique_times * sizeof(cnp.npy_int64)
         self.n_events = <cnp.npy_int64 *> malloc(self.nbytes)
         self.n_at_risk = <cnp.npy_int64 *> malloc(self.nbytes)
@@ -63,19 +63,19 @@ cdef class RisksetCounter:
         memset(self.n_events, 0, self.nbytes)
         memset(self.n_at_risk, 0, self.nbytes)
 
-    cdef void set_data(self, const DOUBLE_t[:, ::1] data) noexcept nogil:
+    cdef void set_data(self, const float64_t[:, ::1] data) noexcept nogil:
         self.data = data
 
-    cdef void update(self, const SIZE_t[:] samples, SIZE_t start, SIZE_t end) noexcept nogil:
+    cdef void update(self, const intp_t[:] samples, intp_t start, intp_t end) noexcept nogil:
         cdef:
-            SIZE_t i
-            SIZE_t idx
-            SIZE_t ti
-            DOUBLE_t time
-            DOUBLE_t event
-            const DOUBLE_t[:] unique_times = self.unique_times
-            SIZE_t n_times = unique_times.shape[0]
-            const DOUBLE_t[:, ::1] y = self.data
+            intp_t i
+            intp_t idx
+            intp_t ti
+            float64_t time
+            float64_t event
+            const float64_t[:] unique_times = self.unique_times
+            intp_t n_times = unique_times.shape[0]
+            const float64_t[:, ::1] y = self.data
 
         self.reset()
 
@@ -94,20 +94,20 @@ cdef class RisksetCounter:
                 if event != 0.0:
                     self.n_events[ti] += 1
 
-    cdef inline void at(self, SIZE_t index, DOUBLE_t * at_risk, DOUBLE_t * events) noexcept nogil:
+    cdef inline void at(self, intp_t index, float64_t * at_risk, float64_t * events) noexcept nogil:
         if at_risk != NULL:
-            at_risk[0] = <DOUBLE_t> self.n_at_risk[index]
+            at_risk[0] = <float64_t> self.n_at_risk[index]
         if events != NULL:
-            events[0] = <DOUBLE_t> self.n_events[index]
+            events[0] = <float64_t> self.n_events[index]
 
 
-cdef int argbinsearch(const DOUBLE_t[:] arr, DOUBLE_t key_val, SIZE_t * ret) except -1 nogil:
+cdef int argbinsearch(const float64_t[:] arr, float64_t key_val, intp_t * ret) except -1 nogil:
     cdef:
-        SIZE_t arr_len = arr.shape[0]
-        SIZE_t min_idx = 0
-        SIZE_t max_idx = arr_len
-        SIZE_t mid_idx
-        DOUBLE_t mid_val
+        intp_t arr_len = arr.shape[0]
+        intp_t min_idx = 0
+        intp_t max_idx = arr_len
+        intp_t mid_idx
+        float64_t mid_val
 
     while min_idx < max_idx:
         mid_idx = min_idx + ((max_idx - min_idx) >> 1)
@@ -130,17 +130,17 @@ cdef class LogrankCriterion(Criterion):
 
     cdef:
         # unique time points sorted in ascending order
-        const DOUBLE_t[::1] unique_times
+        const float64_t[::1] unique_times
         const cnp.npy_bool[::1] is_event_time
-        SIZE_t n_unique_times
-        size_t nbytes
+        intp_t n_unique_times
+        intp_t nbytes
         RisksetCounter riskset_total
         cnp.npy_int64 * delta_n_at_risk_left
         cnp.npy_int64 * n_events_left
-        SIZE_t * samples_time_idx
-        SIZE_t n_samples_left
+        intp_t * samples_time_idx
+        intp_t n_samples_left
 
-    def __cinit__(self, SIZE_t n_outputs, SIZE_t n_samples, const DOUBLE_t[::1] unique_times, const cnp.npy_bool[::1] is_event_time):
+    def __cinit__(self, intp_t n_outputs, intp_t n_samples, const float64_t[::1] unique_times, const cnp.npy_bool[::1] is_event_time):
         # Default values
         self.start = 0
         self.pos = 0
@@ -160,7 +160,7 @@ cdef class LogrankCriterion(Criterion):
         self.riskset_total = RisksetCounter(unique_times)
         self.delta_n_at_risk_left = <cnp.npy_int64 *> malloc(self.nbytes)
         self.n_events_left = <cnp.npy_int64 *> malloc(self.nbytes)
-        self.samples_time_idx = <SIZE_t *> malloc(n_samples * sizeof(SIZE_t))
+        self.samples_time_idx = <intp_t *> malloc(n_samples * sizeof(intp_t))
 
     def __dealloc__(self):
         """Destructor."""
@@ -171,9 +171,15 @@ cdef class LogrankCriterion(Criterion):
     def __reduce__(self):
         return (type(self), (self.n_outputs, self.n_samples, self.unique_times, self.is_event_time), self.__getstate__())
 
-    cdef int init(self, const DOUBLE_t[:, ::1] y, const DOUBLE_t[:] sample_weight,
-                  double weighted_n_samples, const SIZE_t[:] sample_indices, SIZE_t start,
-                  SIZE_t end) except -1 nogil:
+    cdef int init(
+        self,
+        const float64_t[:, ::1] y,
+        const float64_t[:] sample_weight,
+        float64_t weighted_n_samples,
+        const intp_t[:] sample_indices,
+        intp_t start,
+        intp_t end
+    ) except -1 nogil:
         """Initialize the criterion at node samples[start:end] and
            children samples[start:start] and samples[start:end]."""
         # Initialize fields
@@ -187,11 +193,11 @@ cdef class LogrankCriterion(Criterion):
         self.weighted_n_node_samples = 0.
 
         cdef:
-            SIZE_t i
-            SIZE_t idx
-            DOUBLE_t time
-            DOUBLE_t w = 1.0
-            const DOUBLE_t[::1] unique_times = self.unique_times
+            intp_t i
+            intp_t idx
+            float64_t time
+            float64_t w = 1.0
+            const float64_t[::1] unique_times = self.unique_times
 
         self.riskset_total.set_data(y)
         self.riskset_total.update(sample_indices, start, end)
@@ -224,19 +230,19 @@ cdef class LogrankCriterion(Criterion):
         self.pos = self.end
         return 0
 
-    cdef int update(self, SIZE_t new_pos) except -1 nogil:
+    cdef int update(self, intp_t new_pos) except -1 nogil:
         """Updated statistics by moving samples[pos:new_pos] to the left."""
         cdef:
-            const DOUBLE_t[:] sample_weight = self.sample_weight
-            const SIZE_t[:] samples = self.sample_indices
-            const DOUBLE_t[:, ::1] y = self.y
+            const float64_t[:] sample_weight = self.sample_weight
+            const intp_t[:] samples = self.sample_indices
+            const float64_t[:, ::1] y = self.y
 
-            SIZE_t pos = self.start  # always start from the beginning
-            SIZE_t i
-            SIZE_t idx
-            DOUBLE_t event
-            SIZE_t time_idx
-            DOUBLE_t w = 1.0
+            intp_t pos = self.start  # always start from the beginning
+            intp_t i
+            intp_t idx
+            float64_t event
+            intp_t time_idx
+            float64_t w = 1.0
 
         self.n_samples_left = new_pos - pos
         memset(self.delta_n_at_risk_left, 0, self.nbytes)
@@ -264,28 +270,30 @@ cdef class LogrankCriterion(Criterion):
         self.pos = new_pos
         return 0
 
-    cdef double impurity_improvement(self, double impurity_parent,
-                                     double impurity_left,
-                                     double impurity_right) noexcept nogil:
+    cdef float64_t impurity_improvement(
+        self, float64_t impurity_parent,
+        float64_t impurity_left,
+        float64_t impurity_right
+    ) noexcept nogil:
         """Compute the improvement in impurity"""
         return self.proxy_impurity_improvement()
 
-    cdef double proxy_impurity_improvement(self) noexcept nogil:
+    cdef float64_t proxy_impurity_improvement(self) noexcept nogil:
         """Compute a proxy of the impurity reduction"""
 
         cdef:
-            SIZE_t i
-            DOUBLE_t at_risk = <DOUBLE_t> self.n_samples_left
-            DOUBLE_t events
-            DOUBLE_t total_at_risk
-            DOUBLE_t total_events
-            DOUBLE_t ratio
-            DOUBLE_t v
-            DOUBLE_t denom = 0.0
-            DOUBLE_t numer = 0.0
+            intp_t i
+            float64_t at_risk = <float64_t> self.n_samples_left
+            float64_t events
+            float64_t total_at_risk
+            float64_t total_events
+            float64_t ratio
+            float64_t v
+            float64_t denom = 0.0
+            float64_t numer = 0.0
 
         for i in range(self.n_unique_times):
-            events = <DOUBLE_t> self.n_events_left[i]
+            events = <float64_t> self.n_events_left[i]
             self.riskset_total.at(i, &total_at_risk, &total_events)
 
             if total_at_risk == 0:
@@ -297,7 +305,7 @@ cdef class LogrankCriterion(Criterion):
                 denom += ratio * (1.0 - ratio) * v
 
             # Update number of samples at risk for next bigger timepoint
-            at_risk -= <DOUBLE_t> self.delta_n_at_risk_left[i]
+            at_risk -= <float64_t> self.delta_n_at_risk_left[i]
 
         if denom != 0.0:
             # absolute value is the measure of node separation
@@ -307,30 +315,33 @@ cdef class LogrankCriterion(Criterion):
 
         return v
 
-    cdef double node_impurity(self) noexcept nogil:
+    cdef float64_t node_impurity(self) noexcept nogil:
         """Evaluate the impurity of the current node, i.e. the impurity of
            samples[start:end]."""
         return INFINITY
 
-    cdef void children_impurity(self, double* impurity_left,
-                                double* impurity_right) noexcept nogil:
+    cdef void children_impurity(
+        self,
+        float64_t* impurity_left,
+        float64_t* impurity_right
+    ) noexcept nogil:
         """Evaluate the impurity in children nodes, i.e. the impurity of the
            left child (samples[start:pos]) and the impurity the right child
            (samples[pos:end])."""
         impurity_left[0] = INFINITY
         impurity_right[0] = INFINITY
 
-    cdef void node_value(self, double* dest) noexcept nogil:
+    cdef void node_value(self, float64_t* dest) noexcept nogil:
         """Compute the node value of samples[start:end] into dest."""
         # Estimate cumulative hazard function
         cdef:
             const cnp.npy_bool[::1] is_event_time = self.is_event_time
-            SIZE_t i
-            SIZE_t j
-            DOUBLE_t ratio
-            DOUBLE_t n_events
-            DOUBLE_t n_at_risk
-            DOUBLE_t dest_j0
+            intp_t i
+            intp_t j
+            float64_t ratio
+            float64_t n_events
+            float64_t n_at_risk
+            float64_t dest_j0
 
         # low memory mode
         if  self.n_outputs == 1:
diff --git a/sksurv/tree/tree.py b/sksurv/tree/tree.py
index e55dd2a5..750fb518 100644
--- a/sksurv/tree/tree.py
+++ b/sksurv/tree/tree.py
@@ -22,7 +22,7 @@
 from ..util import check_array_survival
 from ._criterion import LogrankCriterion, get_unique_times
 
-__all__ = ["SurvivalTree"]
+__all__ = ["ExtraSurvivalTree", "SurvivalTree"]
 
 DTYPE = _tree.DTYPE
 
@@ -177,6 +177,8 @@ class SurvivalTree(BaseEstimator, SurvivalAnalysisMixin):
         "low_memory": ["boolean"],
     }
 
+    criterion = "logrank"
+
     def __init__(
         self,
         *,
@@ -207,7 +209,7 @@ def _more_tags(self):
     def _support_missing_values(self, X):
         return not issparse(X) and self._get_tags()["allow_nan"]
 
-    def _compute_missing_values_in_feature_mask(self, X):
+    def _compute_missing_values_in_feature_mask(self, X, estimator_name=None):
         """Return boolean mask denoting if there are missing values for each feature.
 
         This method also ensures that X is finite.
@@ -217,13 +219,17 @@ def _compute_missing_values_in_feature_mask(self, X):
         X : array-like of shape (n_samples, n_features), dtype=DOUBLE
             Input data.
 
+        estimator_name : str or None, default=None
+            Name to use when raising an error. Defaults to the class name.
+
         Returns
         -------
         missing_values_in_feature_mask : ndarray of shape (n_features,), or None
             Missing value mask. If missing values are not supported or there
             are no missing values, return None.
         """
-        common_kwargs = dict(estimator_name=self.__class__.__name__, input_name="X")
+        estimator_name = estimator_name or self.__class__.__name__
+        common_kwargs = dict(estimator_name=estimator_name, input_name="X")
 
         if not self._support_missing_values(X):
             assert_all_finite(X, **common_kwargs)
@@ -270,6 +276,10 @@ def fit(self, X, y, sample_weight=None, check_input=True):
         -------
         self
         """
+        self._fit(X, y, sample_weight, check_input)
+        return self
+
+    def _fit(self, X, y, sample_weight=None, check_input=True, missing_values_in_feature_mask=None):
         random_state = check_random_state(self.random_state)
 
         if check_input:
@@ -286,7 +296,6 @@ def fit(self, X, y, sample_weight=None, check_input=True):
             y_numeric[:, 1] = event.astype(np.float64)
         else:
             y_numeric, self.unique_times_, self.is_event_time_ = y
-            missing_values_in_feature_mask = None
 
         n_samples, self.n_features_in_ = X.shape
         params = self._check_params(n_samples)
@@ -301,7 +310,6 @@ def fit(self, X, y, sample_weight=None, check_input=True):
             self.n_classes_ = np.ones(self.n_outputs_, dtype=np.intp) * 2
 
         # Build tree
-        self.criterion = "logrank"
         criterion = LogrankCriterion(self.n_outputs_, n_samples, self.unique_times_, self.is_event_time_)
 
         SPLITTERS = SPARSE_SPLITTERS if issparse(X) else DENSE_SPLITTERS
@@ -309,7 +317,12 @@ def fit(self, X, y, sample_weight=None, check_input=True):
         splitter = self.splitter
         if not isinstance(self.splitter, Splitter):
             splitter = SPLITTERS[self.splitter](
-                criterion, self.max_features_, params["min_samples_leaf"], params["min_weight_leaf"], random_state
+                criterion,
+                self.max_features_,
+                params["min_samples_leaf"],
+                params["min_weight_leaf"],
+                random_state,
+                None,  # monotonic_cst
             )
 
         self.tree_ = Tree(self.n_features_in_, self.n_classes_, self.n_outputs_)
@@ -661,3 +674,30 @@ def decision_path(self, X, check_input=True):
         """
         X = self._validate_X_predict(X, check_input)
         return self.tree_.decision_path(X)
+
+
+class ExtraSurvivalTree(SurvivalTree):
+    def __init__(
+        self,
+        *,
+        splitter="random",
+        max_depth=None,
+        min_samples_split=6,
+        min_samples_leaf=3,
+        min_weight_fraction_leaf=0.0,
+        max_features=None,
+        random_state=None,
+        max_leaf_nodes=None,
+        low_memory=False,
+    ):
+        super().__init__(
+            splitter=splitter,
+            max_depth=max_depth,
+            min_samples_split=min_samples_split,
+            min_samples_leaf=min_samples_leaf,
+            min_weight_fraction_leaf=min_weight_fraction_leaf,
+            max_features=max_features,
+            random_state=random_state,
+            max_leaf_nodes=max_leaf_nodes,
+            low_memory=low_memory,
+        )


Test patch:
diff --git a/.github/workflows/tests-workflow.yaml b/.github/workflows/tests-workflow.yaml
index 3eb25b9c..1ce44b00 100644
--- a/.github/workflows/tests-workflow.yaml
+++ b/.github/workflows/tests-workflow.yaml
@@ -12,13 +12,13 @@ jobs:
       fail-fast: false
       matrix:
         config:
-          - py39_pandas14_numpy122_sklearn13
-          - py310_pandas15_numpy124_sklearn13
-          - py311_pandas20_numpy124_sklearn13
-          - py312_pandas21_numpy126_sklearn13
+          - py39
+          - py310
+          - py311
+          - py312
         runner:
           - ubuntu-latest
-          - macos-latest
+          - macos-14
     runs-on: ${{ matrix.runner }}
     steps:
       - name: Checkout
@@ -26,8 +26,6 @@ jobs:
         with:
           fetch-depth: 0
           submodules: true
-      - name: Adding conda to PATH
-        run: echo "${CONDA}/bin" >> $GITHUB_PATH
       - name: Set dependencies
         id: dependencies
         run: |
@@ -37,23 +35,23 @@ jobs:
           echo "CI_NUMPY_VERSION=${CI_NUMPY_VERSION}" >> $GITHUB_ENV
           echo "CI_SKLEARN_VERSION=${CI_SKLEARN_VERSION}" >> $GITHUB_ENV
           echo "CI_NO_SLOW=${CI_NO_SLOW}" >> $GITHUB_ENV
-          echo "CONDA_PKGS_DIR=${HOME}/conda_pkgs_dir" >> $GITHUB_ENV
+          echo "CONDA_PKGS_DIRS=${{ runner.temp }}/conda_pkgs_dir" >> $GITHUB_ENV
           echo "py_version=$(cut -d'.' -f 1-2 <<< ${CI_PYTHON_VERSION})" >> $GITHUB_OUTPUT
           echo "requirements=ci/deps/${{ matrix.config }}.sh" >> $GITHUB_OUTPUT
       - name: Cache downloaded packages
         uses: actions/cache@v4
         with:
-          path: ${{ env.CONDA_PKGS_DIR }}
-          key: ${{ runner.os }}-conda-${{ steps.dependencies.outputs.py_version }}-${{ hashFiles(steps.dependencies.outputs.requirements, 'pyproject.toml', 'ci/deps/requirements.yaml.tmpl') }}
+          path: ${{ env.CONDA_PKGS_DIRS }}
+          key: ${{ runner.os }}-${{ runner.arch }}-conda-${{ steps.dependencies.outputs.py_version }}-${{ hashFiles(steps.dependencies.outputs.requirements, 'pyproject.toml', 'ci/deps/requirements.yaml.tmpl') }}
           restore-keys: |
-            ${{ runner.os }}-conda-${{ steps.dependencies.outputs.py_version }}-
+            ${{ runner.os }}-${{ runner.arch }}-conda-${{ steps.dependencies.outputs.py_version }}-
       - name: Create Conda Environment
         run: |
-          sudo chown -R $USER $CONDA
-          ci/setup_env.sh ${{ runner.os }}
+          source ci/setup_conda.sh "${{ runner.os }}" "${{ runner.arch }}" "${{ env.CONDA_PKGS_DIRS }}"
+          ci/setup_env.sh "${{ runner.os }}"
       - name: Configure Xcode
         run: |
-          sudo xcode-select -s "/Applications/Xcode_13.2.1.app"
+          sudo xcode-select -s "/Applications/Xcode_15.0.1.app"
         if: runner.os == 'macOS'
       - name: Build package
         run: |
@@ -99,12 +97,10 @@ jobs:
         with:
           fetch-depth: 0
           submodules: true
-      - name: Adding conda to PATH
-        run: echo "${CONDA}/bin" >> $GITHUB_PATH
       - name: Set dependencies
         id: dependencies
         env:
-          DEPS_CONFIG: py311_pandas20_numpy124_sklearn13
+          DEPS_CONFIG: py311
         run: |
           source ci/deps/${DEPS_CONFIG}.sh
           echo "CI_PYTHON_VERSION=${CI_PYTHON_VERSION}" >> $GITHUB_ENV
@@ -112,17 +108,17 @@ jobs:
           echo "CI_NUMPY_VERSION=${CI_NUMPY_VERSION}" >> $GITHUB_ENV
           echo "CI_SKLEARN_VERSION=${CI_SKLEARN_VERSION}" >> $GITHUB_ENV
           echo "CI_NO_SLOW=${CI_NO_SLOW}" >> $GITHUB_ENV
-          echo "CONDA_PKGS_DIR=${HOME}/conda_pkgs_dir" >> $GITHUB_ENV
+          echo "CONDA_PKGS_DIRS=${{ runner.temp }}/conda_pkgs_dir" >> $GITHUB_ENV
           echo "requirements=ci/deps/${DEPS_CONFIG}.sh" >> $GITHUB_OUTPUT
       - name: Cache downloaded packages
         uses: actions/cache@v4
         with:
-          path: ${{ env.CONDA_PKGS_DIR }}
-          key: ${{ runner.os }}-conda-3.10-${{ hashFiles(steps.dependencies.outputs.requirements, 'pyproject.toml', 'ci/deps/requirements.yaml.tmpl') }}
+          path: ${{ env.CONDA_PKGS_DIRS }}
+          key: ${{ runner.os }}-${{ runner.arch }}-conda-3.11-${{ hashFiles(steps.dependencies.outputs.requirements, 'pyproject.toml', 'ci/deps/requirements.yaml.tmpl') }}
       - name: Create Conda Environment
         run: |
-          sudo chown -R $USER $CONDA
-          ci/setup_env.sh ${{ runner.os }}
+          source ci/setup_conda.sh "${{ runner.os }}" "${{ runner.arch }}" "${{ env.CONDA_PKGS_DIRS }}"
+          ci/setup_env.sh "${{ runner.os }}"
       - name: Configure matplotlib
         run: |
           mkdir -p ${XDG_CONFIG_HOME}/matplotlib
diff --git a/tests/test_boosting.py b/tests/test_boosting.py
index 70d52c15..076e955f 100644
--- a/tests/test_boosting.py
+++ b/tests/test_boosting.py
@@ -1,4 +1,5 @@
 from contextlib import nullcontext as does_not_raise
+import itertools
 from os.path import dirname, join
 
 import numpy as np
@@ -192,7 +193,7 @@ def test_fit_subsample(self):
     @pytest.mark.slow()
     def test_fit_dropout(self):
         model = self.assert_fit_and_predict(
-            expected_cindex=(0.9094333, 68343, 6806, 0, 14),
+            expected_cindex=(0.9051950, 68024, 7124, 1, 14),
             n_estimators=100,
             max_features=8,
             learning_rate=1.0,
@@ -301,6 +302,21 @@ def test_early_stopping(self):
 
         assert model.n_estimators_ == 36
 
+    def test_early_stopping_with_dropout(self):
+        X, y = self.data
+
+        model = GradientBoostingSurvivalAnalysis(
+            n_estimators=1000,
+            max_depth=2,
+            n_iter_no_change=3,
+            dropout_rate=0.25,
+            validation_fraction=0.2,
+            random_state=0,
+        )
+        model.fit(X, y)
+
+        assert model.n_estimators_ == 21
+
     @staticmethod
     def test_negative_ccp_alpha(make_whas500):
         whas500_data = make_whas500(with_std=False, to_numeric=True)
@@ -442,8 +458,6 @@ def assert_fit_and_predict(self, data, **kwargs):
         assert model.train_score_.shape == (100,)
 
         sparse_predict = model.predict(data.x_sparse)
-
-        model.fit(data.x_sparse, data.y)
         dense_predict = model.predict(data.x_dense.values)
 
         assert_array_almost_equal(sparse_predict, dense_predict)
@@ -553,17 +567,17 @@ def test_fit_dropout(make_whas500):
         p = model.predict(whas500_data.x)
 
         assert_cindex_almost_equal(
-            whas500_data.y["fstat"], whas500_data.y["lenfol"], p, (0.7772425, 58409, 16740, 0, 14)
+            whas500_data.y["fstat"], whas500_data.y["lenfol"], p, (0.7777482, 58447, 16702, 0, 14)
         )
 
         expected_coef = pd.Series(np.zeros(15, dtype=float), index=whas500_data.names)
-        expected_coef["age"] = 0.275537
-        expected_coef["hr"] = 0.040048
-        expected_coef["diasbp"] = -0.029998
-        expected_coef["bmi"] = -0.138909
-        expected_coef["sho"] = 3.318941
-        expected_coef["chf"] = 2.851386
-        expected_coef["mitype"] = -0.075817
+        expected_coef["age"] = 0.248771
+        expected_coef["hr"] = 0.04392
+        expected_coef["diasbp"] = -0.022432
+        expected_coef["bmi"] = -0.138095
+        expected_coef["sho"] = 2.863096
+        expected_coef["chf"] = 3.552457
+        expected_coef["mitype"] = -0.074266
 
         assert_array_almost_equal(expected_coef.values, model.coef_)
 
@@ -662,6 +676,139 @@ def test_squared_loss(make_whas500):
             model.predict_cumulative_hazard_function(whas500_data.x)
 
 
+@pytest.mark.parametrize(
+    "model_cls,loss,dropout_rate",
+    list(
+        itertools.product(
+            [ComponentwiseGradientBoostingSurvivalAnalysis, GradientBoostingSurvivalAnalysis],
+            ["coxph", "ipcwls", "squared"],
+            [0.0, 0.05],
+        )
+    ),
+)
+def test_fit_warm_start(make_whas500, model_cls, loss, dropout_rate):
+    whas500_data = make_whas500(with_std=False, to_numeric=True)
+
+    model_1 = model_cls(loss=loss, n_estimators=100, learning_rate=0.1, dropout_rate=dropout_rate, random_state=0)
+    model_1.fit(whas500_data.x, whas500_data.y)
+    assert model_1.n_estimators_ == 100
+    pred_1 = model_1.predict(whas500_data.x)
+
+    model_2 = model_cls(loss=loss, n_estimators=40, learning_rate=0.1, dropout_rate=dropout_rate, random_state=0)
+    model_2.fit(whas500_data.x, whas500_data.y)
+    assert model_2.n_estimators_ == 40
+    pred_2_40 = model_2.predict(whas500_data.x)
+
+    model_2.set_params(warm_start=True, n_estimators=100)
+    model_2.fit(whas500_data.x, whas500_data.y)
+    assert model_2.n_estimators_ == 100
+    pred_2 = model_2.predict(whas500_data.x)
+
+    assert_array_almost_equal(pred_1, pred_2)
+
+    # fit from start
+    model_2.set_params(warm_start=False, n_estimators=40)
+    model_2.fit(whas500_data.x, whas500_data.y)
+    assert model_2.n_estimators_ == 40
+    assert not hasattr(model_2, "oob_improvement_")
+
+    pred_3 = model_2.predict(whas500_data.x)
+
+    assert_array_almost_equal(pred_2_40, pred_3)
+
+    model_2.set_params(warm_start=True, n_estimators=39)
+    msg = r"n_estimators=39 must be larger or equal to estimators_.shape\[0\]=40 when warm_start==True"
+    with pytest.raises(ValueError, match=msg):
+        model_2.fit(whas500_data.x, whas500_data.y)
+
+
+@pytest.mark.parametrize(
+    "model_cls,subsample",
+    list(
+        itertools.product(
+            [ComponentwiseGradientBoostingSurvivalAnalysis, GradientBoostingSurvivalAnalysis],
+            [1.0, 0.666],
+        )
+    ),
+)
+def test_fit_warm_start_with_subsample(make_whas500, model_cls, subsample):
+    whas500_data = make_whas500(with_std=False, to_numeric=True)
+
+    def assert_subsample_enabled(estimator):
+        assert hasattr(estimator, "oob_scores_")
+        assert hasattr(estimator, "oob_score_")
+        assert hasattr(estimator, "oob_improvement_")
+
+    def assert_subsample_disabled(estimator):
+        assert not hasattr(estimator, "oob_scores_")
+        assert not hasattr(estimator, "oob_score_")
+        assert not hasattr(estimator, "oob_improvement_")
+
+    if subsample < 1:
+        assert_model_fit_orig = assert_subsample_enabled
+        subsample_alt = 1.0
+        assert_model_fit_warm = assert_subsample_enabled  # warm start keeps attributes
+        assert_model_fit_alt = assert_subsample_disabled
+    else:
+        assert_model_fit_orig = assert_subsample_disabled
+        subsample_alt = 0.5
+        assert_model_fit_warm = assert_subsample_enabled  # adds new attributes
+        assert_model_fit_alt = assert_subsample_enabled
+
+    model_1 = model_cls(
+        n_estimators=11,
+        learning_rate=0.1,
+        subsample=subsample,
+        random_state=0,
+    )
+    model_1.fit(whas500_data.x, whas500_data.y)
+    assert model_1.n_estimators_ == 11
+    assert_model_fit_orig(model_1)
+
+    model_1.set_params(warm_start=True, n_estimators=23)
+    model_1.fit(whas500_data.x, whas500_data.y)
+    assert model_1.n_estimators_ == 23
+    assert_model_fit_orig(model_1)
+
+    model_1.set_params(warm_start=True, n_estimators=50, subsample=subsample_alt)
+    model_1.fit(whas500_data.x, whas500_data.y)
+    assert model_1.n_estimators_ == 50
+    assert_model_fit_warm(model_1)
+
+    model_1.set_params(warm_start=False, n_estimators=25, subsample=subsample_alt)
+    model_1.fit(whas500_data.x, whas500_data.y)
+    assert model_1.n_estimators_ == 25
+    assert_model_fit_alt(model_1)
+
+
+@pytest.mark.parametrize("model_cls", [ComponentwiseGradientBoostingSurvivalAnalysis, GradientBoostingSurvivalAnalysis])
+def test_fit_warm_start_with_wrong_dropout(make_whas500, model_cls):
+    whas500_data = make_whas500(with_std=False, to_numeric=True)
+
+    model = model_cls(
+        n_estimators=11,
+        learning_rate=0.1,
+        dropout_rate=0,
+        random_state=0,
+    )
+    model.fit(whas500_data.x, whas500_data.y)
+    assert model.n_estimators_ == 11
+    assert not hasattr(model, "_scale")
+
+    model.set_params(warm_start=True, n_estimators=50, dropout_rate=0.5)
+    msg = (
+        "fitting with warm_start=True and dropout_rate > 0 is only "
+        "supported if the previous fit used dropout_rate > 0 too"
+    )
+    with pytest.raises(ValueError, match=msg):
+        model.fit(whas500_data.x, whas500_data.y)
+
+    model.set_params(warm_start=False, n_estimators=2)
+    model.fit(whas500_data.x, whas500_data.y)
+    assert model.n_estimators_ == 2
+    assert_array_almost_equal(model._scale, np.array([0.5, 0.5]))
+
+
 @pytest.fixture(params=[GradientBoostingSurvivalAnalysis, ComponentwiseGradientBoostingSurvivalAnalysis])
 def sample_gb_class(request):
     x = np.arange(100).reshape(5, 20)
@@ -734,11 +881,10 @@ def test_param_sample_weight(sample_gb_class):
     est_cls, x, y = sample_gb_class
     model = est_cls()
 
-    with pytest.raises(ValueError, match=r"Found input variables with inconsistent numbers of samples: \[5, 3\]"):
+    with pytest.raises(ValueError, match=r"sample_weight.shape == \(3,\), expected \(5,\)!"):
         model.fit(x, y, [2, 3, 4])
 
-    model.set_params(dropout_rate=1.2)
-    with pytest.raises(ValueError, match=r"Found input variables with inconsistent numbers of samples: \[5, 8\]"):
+    with pytest.raises(ValueError, match=r"sample_weight.shape == \(8,\), expected \(5,\)!"):
         model.fit(x, y, [2, 4, 5, 6, 7, 1, 2, 7])
 
 
diff --git a/tests/test_forest.py b/tests/test_forest.py
index 5074f0e6..18c983d3 100644
--- a/tests/test_forest.py
+++ b/tests/test_forest.py
@@ -2,6 +2,7 @@
 from numpy.testing import assert_array_almost_equal, assert_array_equal
 import pytest
 from scipy import sparse
+from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier
 from sklearn.model_selection import train_test_split
 from sklearn.pipeline import make_pipeline
 
@@ -39,6 +40,57 @@ def test_fit_predict(make_whas500, forest_cls, expected_c):
     assert_cindex_almost_equal(whas500.y["fstat"], whas500.y["lenfol"], pred, expected_c)
 
 
+def test_fit_missing_values(make_whas500):
+    whas500 = make_whas500(to_numeric=True)
+
+    rng = np.random.RandomState(42)
+    mask = rng.binomial(n=1, p=0.15, size=whas500.x.shape)
+    mask = mask.astype(bool)
+    X = whas500.x.copy()
+    X[mask] = np.nan
+
+    X_train, y_train = X[:400], whas500.y[:400]
+    X_test, y_test = X[400:], whas500.y[400:]
+
+    forest = RandomSurvivalForest(random_state=42)
+    forest.fit(X_train, y_train)
+
+    tags = forest._get_tags()
+    assert tags["allow_nan"]
+
+    cindex = forest.score(X_test, y_test)
+    assert cindex == pytest.approx(0.7408487204405572)
+
+
+def test_fit_missing_values_not_supported(make_whas500):
+    whas500 = make_whas500(to_numeric=True)
+
+    rng = np.random.RandomState(42)
+    mask = rng.binomial(n=1, p=0.15, size=whas500.x.shape)
+    mask = mask.astype(bool)
+    X = whas500.x.copy()
+    X[mask] = np.nan
+
+    forest = ExtraSurvivalTrees(random_state=42)
+    with pytest.raises(ValueError, match="Input X contains NaN"):
+        forest.fit(X, whas500.y)
+
+    tags = forest._get_tags()
+    assert not tags["allow_nan"]
+
+
+@pytest.mark.parametrize("forst_cls,allows_nan", [(ExtraTreesClassifier, False), (RandomForestClassifier, True)])
+def test_sklearn_random_forest_tags(forst_cls, allows_nan):
+    est = forst_cls()
+
+    # https://scikit-learn.org/stable/developers/develop.html#estimator-tags
+    tags = est._get_tags()
+    assert tags["multioutput"]
+    assert tags["requires_fit"]
+    assert tags["requires_y"]
+    assert tags["allow_nan"] is allows_nan
+
+
 @pytest.mark.parametrize("forest_cls", FORESTS)
 def test_fit_int_time(make_whas500, forest_cls):
     whas500 = make_whas500(to_numeric=True)
diff --git a/tests/test_metrics.py b/tests/test_metrics.py
index d6794e39..24824c7a 100644
--- a/tests/test_metrics.py
+++ b/tests/test_metrics.py
@@ -1203,5 +1203,5 @@ def test_scorer_no_predict_function(make_whas500, pred_func):
     scorer = as_concordance_index_ipcw_scorer(FastSurvivalSVM())
     scorer.fit(whas500_data.x, whas500_data.y)
 
-    with pytest.raises(AttributeError, match=f"'FastSurvivalSVM' object has no attribute {pred_func!r}"):
+    with pytest.raises(AttributeError, match=f"This 'as_concordance_index_ipcw_scorer' has no attribute {pred_func!r}"):
         getattr(scorer, pred_func)
diff --git a/tests/test_show_versions.py b/tests/test_show_versions.py
index 8e6fdbfb..bbc64cc6 100644
--- a/tests/test_show_versions.py
+++ b/tests/test_show_versions.py
@@ -13,7 +13,7 @@ def test_show_versions(capsys):
     # check required dependency
     assert re.search(r"numpy\s*:\s([0-9\.\+a-f]|dev)+\n", captured.out)
     assert re.search(r"pandas\s*:\s([0-9\.\+a-f]|dev)+\n", captured.out)
-    assert re.search(r"scikit-learn\s*:\s([0-9\.\+a-f]|dev)+\n", captured.out)
+    assert re.search(r"scikit-learn\s*:\s([0-9\.\+a-f]|dev|post\d)+\n", captured.out)
 
     # check optional dependency
     assert re.search(r"matplotlib\s*:\s([0-9\.]+|None)\n", captured.out)
diff --git a/tests/test_stacking.py b/tests/test_stacking.py
index a9b2a155..8410e5f5 100644
--- a/tests/test_stacking.py
+++ b/tests/test_stacking.py
@@ -235,7 +235,7 @@ def test_predict_variants(method):
             probabilities=False,
         )
 
-        with pytest.raises(AttributeError, match=f"'_PredictDummy' object has no attribute '{method}'"):
+        with pytest.raises(AttributeError, match=f"This 'Stacking' has no attribute '{method}'"):
             getattr(meta, method)()  # pylint: disable=pointless-statement
 
     @staticmethod
diff --git a/tests/test_tree.py b/tests/test_tree.py
index 138af8b9..a6cf205e 100644
--- a/tests/test_tree.py
+++ b/tests/test_tree.py
@@ -14,7 +14,7 @@
 from sksurv.compare import compare_survival
 from sksurv.datasets import load_breast_cancer, load_veterans_lung_cancer
 from sksurv.nonparametric import kaplan_meier_estimator, nelson_aalen_estimator
-from sksurv.tree import SurvivalTree
+from sksurv.tree import ExtraSurvivalTree, SurvivalTree
 from sksurv.util import Surv
 
 
@@ -850,6 +850,6 @@ def test_missing_value_random_splitter_errors(is_sparse):
     if is_sparse:
         X = sparse.csr_matrix(X)
 
-    tree = SurvivalTree(splitter="random")
+    tree = ExtraSurvivalTree()
     with pytest.raises(ValueError, match="Input X contains NaN"):
         tree.fit(X, y)