diff --git a/docs/source/notebooks/pca_gp_plaid_pipeline.ipynb b/docs/source/notebooks/pca_gp_plaid_pipeline.ipynb new file mode 100644 index 0000000..5f37fdd --- /dev/null +++ b/docs/source/notebooks/pca_gp_plaid_pipeline.ipynb @@ -0,0 +1,2711 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exemple of pipeline PCA-GP-PCA type" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import make_regression\n", + "\n", + "from sklearn.decomposition import PCA\n", + "from sklearn.preprocessing import MinMaxScaler, StandardScaler\n", + "from sklearn.gaussian_process import GaussianProcessRegressor\n", + "\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.compose import ColumnTransformer, TransformedTargetRegressor" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from plaid.containers.dataset import Dataset\n", + "from plaid.containers.sample import Sample\n", + "from plaid.problem_definition import ProblemDefinition\n", + "from plaid.wrappers.sklearn import WrappedSklearnTransform, WrappedSklearnRegressor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate some synthetic regression data" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "NB_SAMPLES = 103\n", + "NB_INPUT_SCALARS = 3\n", + "NB_OUTPUT_SCALARS = 5\n", + "FIELD_SIZE = 17\n", + "\n", + "X, y = make_regression(n_samples=NB_SAMPLES, n_features=NB_INPUT_SCALARS, n_targets=NB_OUTPUT_SCALARS + FIELD_SIZE, noise=0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n", + " 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,\n", + " 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\n", + " 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n", + " 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,\n", + " 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,\n", + " 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,\n", + " 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dset = Dataset()\n", + "samples = []\n", + "for sample_id in range(NB_SAMPLES):\n", + " sample = Sample()\n", + " for scalar_id in range(NB_INPUT_SCALARS):\n", + " sample.add_scalar(f\"input_scalar_{scalar_id}\", X[sample_id, scalar_id])\n", + " for scalar_id in range(NB_OUTPUT_SCALARS):\n", + " sample.add_scalar(f\"output_scalar_{scalar_id}\", y[sample_id, scalar_id])\n", + " sample.init_base(topological_dim=3, physical_dim=3)\n", + " sample.init_zone(np.array([0,0,0]))\n", + " sample.add_field(f\"output_field\", y[sample_id, NB_OUTPUT_SCALARS:])\n", + " samples.append(sample)\n", + "dset.add_samples(samples)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# pr_def = ProblemDefinition()\n", + "# pr_def.set_split({\n", + "# 'train': np.arange(NB_SAMPLES * 0.8),\n", + "# 'test': np.arange(NB_SAMPLES * 0.8,NB_SAMPLES),\n", + "# })\n", + "# pr_def.add_input_scalars_names([f\"input_scalar_{scalar_id}\" for scalar_id in range(NB_OUTPUT_SCALARS)])\n", + "# pr_def.add_output_scalars_names([f\"output_scalar_{scalar_id}\" for scalar_id in range(NB_OUTPUT_SCALARS)])\n", + "# pr_def.add_output_fields_names(['output_field'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## PCA-GP-PCA as a pipeline with PLAID inputs/outputs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Define the PCA for the shape embedding\n", + "\n", + "In this example we only apply PCA to the scalars, other features are not modified" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
WrappedSklearnTransform(PCA(n_components=2))
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "WrappedSklearnTransform(PCA(n_components=2))" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "### old version\n", + "# feats_to_reduce = list(range(NB_INPUT_SCALARS))\n", + "# preprocessor = ColumnTransformer(\n", + "# transformers=[\n", + "# (\n", + "# \"pca\",\n", + "# WrappedSklearnTransform(PCA(n_components=2), in_features=['scalar::all']),\n", + "# feats_to_reduce,\n", + "# ),\n", + "# ],\n", + "# remainder=\"passthrough\",\n", + "# )\n", + "\n", + "### new version\n", + "preprocessor = WrappedSklearnTransform(PCA(n_components=2), in_features=[f\"scalar::input_scalar_{scalar_id}\" for scalar_id in range(NB_INPUT_SCALARS)])\n", + "preprocessor" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
WrappedSklearnTransform(PCA(n_components=2))
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "WrappedSklearnTransform(PCA(n_components=2))" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "preprocessor.fit(dataset=dset)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "preprocessor._is_fitted" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== In <_convert_y_to_plaid>\n", + "- self.sklearn_block.feature_names_in_ not found\n", + "- self.sklearn_block.get_feature_names_out()=array(['pca0', 'pca1'], dtype=object)\n", + "- self.output_scalars=[]\n", + "- self.output_time_series=[]\n", + "- self.output_fields=[]\n", + "- dataset.get_scalar_names()=['input_scalar_0', 'input_scalar_1', 'input_scalar_2', 'output_scalar_0', 'output_scalar_1', 'output_scalar_2', 'output_scalar_3', 'output_scalar_4']\n", + "- dataset.get_time_series_names()=[]\n", + "- dataset.get_field_names()=['output_field']\n", + "- y.shape=(103, 2)\n", + "- dataset.get_scalar_names()=['input_scalar_0', 'input_scalar_1', 'input_scalar_2', 'output_scalar_0', 'output_scalar_1', 'output_scalar_2', 'output_scalar_3', 'output_scalar_4']\n", + "- dataset.get_time_series_names()=[]\n", + "- dataset.get_field_names()=['output_field']\n" + ] + }, + { + "data": { + "text/plain": [ + "(True,\n", + " ['input_scalar_0',\n", + " 'input_scalar_1',\n", + " 'input_scalar_2',\n", + " 'output_scalar_0',\n", + " 'output_scalar_1',\n", + " 'output_scalar_2',\n", + " 'output_scalar_3',\n", + " 'output_scalar_4'],\n", + " ['output_field'])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "out_dset = preprocessor.transform(dset)\n", + "id(dset) == id(out_dset), out_dset.get_scalar_names(), out_dset.get_field_names()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(preprocessor.sklearn_block.explained_variance_ratio_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Define the output scaler for the output fields (MinMaxScaler + PCA)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Pipeline(steps=[('scaler',\n",
+       "                 WrappedSklearnTransform(in_features=['field::output_field'], sklearn_block=MinMaxScaler())),\n",
+       "                ('pca',\n",
+       "                 WrappedSklearnTransform(in_features=['field::output_field'], sklearn_block=PCA(n_components=9)))])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "Pipeline(steps=[('scaler',\n", + " WrappedSklearnTransform(in_features=['field::output_field'], sklearn_block=MinMaxScaler())),\n", + " ('pca',\n", + " WrappedSklearnTransform(in_features=['field::output_field'], sklearn_block=PCA(n_components=9)))])" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "postprocessor = Pipeline(\n", + " [\n", + " (\"scaler\", WrappedSklearnTransform(MinMaxScaler(), in_features=[\"field::output_field\"])),\n", + " (\"pca\", WrappedSklearnTransform(PCA(n_components=9), in_features=[\"field::output_field\"])),\n", + " ]\n", + ")\n", + "postprocessor" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== In <_convert_y_to_plaid>\n", + "- self.sklearn_block.feature_names_in_ not found\n", + "- self.sklearn_block.get_feature_names_out()=array(['x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10',\n", + " 'x11', 'x12', 'x13', 'x14', 'x15', 'x16'], dtype=object)\n", + "- self.output_scalars=[]\n", + "- self.output_time_series=[]\n", + "- self.output_fields=[]\n", + "- dataset.get_scalar_names()=['input_scalar_0', 'input_scalar_1', 'input_scalar_2', 'output_scalar_0', 'output_scalar_1', 'output_scalar_2', 'output_scalar_3', 'output_scalar_4']\n", + "- dataset.get_time_series_names()=[]\n", + "- dataset.get_field_names()=['output_field']\n", + "- y.shape=(103, 17)\n", + "- dataset.get_scalar_names()=['input_scalar_0', 'input_scalar_1', 'input_scalar_2', 'output_scalar_0', 'output_scalar_1', 'output_scalar_2', 'output_scalar_3', 'output_scalar_4']\n", + "- dataset.get_time_series_names()=[]\n", + "- dataset.get_field_names()=['output_field']\n" + ] + }, + { + "ename": "TypeError", + "evalue": "PlaidWrapper.fit() takes 2 positional arguments but 3 were given", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[13]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mpostprocessor\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdset\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\d606912\\.conda\\envs\\plaid_dev\\Lib\\site-packages\\sklearn\\base.py:1363\u001b[39m, in \u001b[36m_fit_context..decorator..wrapper\u001b[39m\u001b[34m(estimator, *args, **kwargs)\u001b[39m\n\u001b[32m 1356\u001b[39m estimator._validate_params()\n\u001b[32m 1358\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[32m 1359\u001b[39m skip_parameter_validation=(\n\u001b[32m 1360\u001b[39m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[32m 1361\u001b[39m )\n\u001b[32m 1362\u001b[39m ):\n\u001b[32m-> \u001b[39m\u001b[32m1363\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfit_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mestimator\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\d606912\\.conda\\envs\\plaid_dev\\Lib\\site-packages\\sklearn\\pipeline.py:661\u001b[39m, in \u001b[36mPipeline.fit\u001b[39m\u001b[34m(self, X, y, **params)\u001b[39m\n\u001b[32m 655\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._final_estimator != \u001b[33m\"\u001b[39m\u001b[33mpassthrough\u001b[39m\u001b[33m\"\u001b[39m:\n\u001b[32m 656\u001b[39m last_step_params = \u001b[38;5;28mself\u001b[39m._get_metadata_for_step(\n\u001b[32m 657\u001b[39m step_idx=\u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m) - \u001b[32m1\u001b[39m,\n\u001b[32m 658\u001b[39m step_params=routed_params[\u001b[38;5;28mself\u001b[39m.steps[-\u001b[32m1\u001b[39m][\u001b[32m0\u001b[39m]],\n\u001b[32m 659\u001b[39m all_params=params,\n\u001b[32m 660\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m661\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_final_estimator\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mXt\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mlast_step_params\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mfit\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 663\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\n", + "\u001b[31mTypeError\u001b[39m: PlaidWrapper.fit() takes 2 positional arguments but 3 were given" + ] + } + ], + "source": [ + "postprocessor.fit(dset)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. Define the regressor\n", + "\n", + "Y = GP(transformer(X)) where transformer(X) = postprocessor(X)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "regressor = TransformedTargetRegressor(\n", + " regressor=WrappedSklearnRegressor(\n", + " GaussianProcessRegressor(n_restarts_optimizer=3),\n", + " in_features=[f\"scalar::input_scalar_{scalar_id}\" for scalar_id in range(NB_INPUT_SCALARS)],\n", + " out_featuresures=[\"field::output_field\", *[f\"scalar::output_scalar_{scalar_id}\" for scalar_id in range(NB_OUTPUT_SCALARS)]],\n", + " ),\n", + " check_inverse=False,\n", + " transformer=postprocessor,\n", + ")\n", + "regressor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. Combine to make the pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = Pipeline(\n", + " steps=[\n", + " (\"preprocessor\", preprocessor),\n", + " (\"scaler\", WrappedSklearnTransform(StandardScaler(), in_features=[f\"scalar::input_scalar_{scalar_id}\" for scalar_id in range(NB_INPUT_SCALARS)])),\n", + " (\"regressor\", regressor),\n", + " ]\n", + ")\n", + "model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Fit the model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model.fit(dset)\n", + "model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Predict on the training data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_pred = model.predict(X)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Other way to define the pipeline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Define the regressor" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "regressor = Pipeline(\n", + " steps=[\n", + " (\"preprocessor\", preprocessor),\n", + " (\"scaler\", WrappedSklearnTransform(\n", + " StandardScaler(),\n", + " in_features=[f\"scalar::input_scalar_{scalar_id}\" for scalar_id in range(NB_INPUT_SCALARS)],\n", + " )),\n", + " (\"regressor\", WrappedSklearnRegressor(\n", + " GaussianProcessRegressor(n_restarts_optimizer=3),\n", + " in_features=[f\"scalar::input_scalar_{scalar_id}\" for scalar_id in range(NB_INPUT_SCALARS)],\n", + " out_featuresures=[\"field::output_field\", *[f\"scalar::output_scalar_{scalar_id}\" for scalar_id in range(NB_OUTPUT_SCALARS)]],\n", + " )),\n", + " ]\n", + ")\n", + "regressor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Combine to make the pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = TransformedTargetRegressor(\n", + " regressor=regressor,\n", + " check_inverse=False,\n", + " transformer=postprocessor,\n", + ")\n", + "model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model.fit(X,y)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "plaid_dev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/notebooks/pca_gp_sklearn_pipeline.ipynb b/docs/source/notebooks/pca_gp_sklearn_pipeline.ipynb new file mode 100644 index 0000000..f865796 --- /dev/null +++ b/docs/source/notebooks/pca_gp_sklearn_pipeline.ipynb @@ -0,0 +1,7899 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exemple of pipeline PCA-GP-PCA type" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import make_regression\n", + "\n", + "from sklearn.decomposition import PCA\n", + "from sklearn.preprocessing import MinMaxScaler, StandardScaler\n", + "from sklearn.gaussian_process import GaussianProcessRegressor\n", + "\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.compose import ColumnTransformer, TransformedTargetRegressor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate some synthetic regression data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "X, y = make_regression(n_samples=100, n_features=10, noise=0.1, n_targets=11)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## PCA-GP-PCA as an sklearn pipeline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Define the PCA for the shape embedding\n", + "\n", + "In this example we only apply PCA to the first 8 columns\n", + "\n", + "The last two columns are unchanged" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ColumnTransformer(remainder='passthrough',\n",
+       "                  transformers=[('pca', PCA(n_components=8),\n",
+       "                                 [0, 1, 2, 3, 4, 5, 6, 7])])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "ColumnTransformer(remainder='passthrough',\n", + " transformers=[('pca', PCA(n_components=8),\n", + " [0, 1, 2, 3, 4, 5, 6, 7])])" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "feats_to_reduce = list(range(8))\n", + "preprocessor = ColumnTransformer(\n", + " transformers=[\n", + " (\n", + " \"pca\",\n", + " PCA(n_components=8),\n", + " feats_to_reduce,\n", + " ),\n", + " ],\n", + " remainder=\"passthrough\",\n", + ")\n", + "preprocessor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Define the output scaler for the output fields (MinMaxScaler + PCA)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Pipeline(steps=[('scaler', MinMaxScaler()), ('pca', PCA(n_components=9))])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "Pipeline(steps=[('scaler', MinMaxScaler()), ('pca', PCA(n_components=9))])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "postprocessor = Pipeline(\n", + " [\n", + " (\"scaler\", MinMaxScaler()),\n", + " (\"pca\", PCA(n_components=9)),\n", + " ]\n", + ")\n", + "postprocessor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. Define the regressor\n", + "\n", + "Y = GP(transformer(X)) where transformer(X) = postprocessor(X)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
TransformedTargetRegressor(check_inverse=False,\n",
+       "                           regressor=GaussianProcessRegressor(n_restarts_optimizer=3),\n",
+       "                           transformer=Pipeline(steps=[('scaler',\n",
+       "                                                        MinMaxScaler()),\n",
+       "                                                       ('pca',\n",
+       "                                                        PCA(n_components=9))]))
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "TransformedTargetRegressor(check_inverse=False,\n", + " regressor=GaussianProcessRegressor(n_restarts_optimizer=3),\n", + " transformer=Pipeline(steps=[('scaler',\n", + " MinMaxScaler()),\n", + " ('pca',\n", + " PCA(n_components=9))]))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "regressor = TransformedTargetRegressor(\n", + " regressor=GaussianProcessRegressor(\n", + " n_restarts_optimizer=3,\n", + " ),\n", + " check_inverse=False,\n", + " transformer=postprocessor,\n", + ")\n", + "regressor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. Combine to make the pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Pipeline(steps=[('preprocessor',\n",
+       "                 ColumnTransformer(remainder='passthrough',\n",
+       "                                   transformers=[('pca', PCA(n_components=8),\n",
+       "                                                  [0, 1, 2, 3, 4, 5, 6, 7])])),\n",
+       "                ('scaler', StandardScaler()),\n",
+       "                ('regressor',\n",
+       "                 TransformedTargetRegressor(check_inverse=False,\n",
+       "                                            regressor=GaussianProcessRegressor(n_restarts_optimizer=3),\n",
+       "                                            transformer=Pipeline(steps=[('scaler',\n",
+       "                                                                         MinMaxScaler()),\n",
+       "                                                                        ('pca',\n",
+       "                                                                         PCA(n_components=9))])))])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.