diff --git a/assets/mlflow/requirements.txt b/assets/mlflow/requirements.txt
index 24d3659..f7274ec 100644
--- a/assets/mlflow/requirements.txt
+++ b/assets/mlflow/requirements.txt
@@ -1,4 +1,6 @@
mlflow==2.16
scikit-learn
catboost
-numpy
\ No newline at end of file
+numpy
+mlxtend==0.23.1
+optuna==4.0.0
diff --git a/assets/mlflow/research.ipynb b/assets/mlflow/research.ipynb
index fa97d46..cd10d3c 100644
--- a/assets/mlflow/research.ipynb
+++ b/assets/mlflow/research.ipynb
@@ -731,9 +731,285 @@
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
+ "execution_count": 80,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num__geo_lat | \n",
+ " num__geo_lon | \n",
+ " num__level | \n",
+ " num__levels | \n",
+ " num__rooms | \n",
+ " num__area | \n",
+ " num__kitchen_area | \n",
+ " cat__region | \n",
+ " cat__building_type | \n",
+ " cat__object_type | \n",
+ " quantile__geo_lat | \n",
+ " quantile__geo_lon | \n",
+ " quantile__level | \n",
+ " quantile__levels | \n",
+ " quantile__rooms | \n",
+ " quantile__area | \n",
+ " quantile__kitchen_area | \n",
+ " poly__1 | \n",
+ " poly__area | \n",
+ " poly__kitchen_area | \n",
+ " poly__area^2 | \n",
+ " poly__area kitchen_area | \n",
+ " poly__kitchen_area^2 | \n",
+ " spline__area_sp_0 | \n",
+ " spline__area_sp_1 | \n",
+ " spline__area_sp_2 | \n",
+ " spline__area_sp_3 | \n",
+ " spline__area_sp_4 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.495902 | \n",
+ " -0.449742 | \n",
+ " 0.359235 | \n",
+ " -0.214789 | \n",
+ " 0.253413 | \n",
+ " 0.063735 | \n",
+ " -0.186285 | \n",
+ " 20.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " 0.766257 | \n",
+ " 0.511028 | \n",
+ " 0.717217 | \n",
+ " 0.536537 | \n",
+ " 0.600601 | \n",
+ " 0.623624 | \n",
+ " 0.374875 | \n",
+ " 0.0 | \n",
+ " 0.063735 | \n",
+ " -0.186285 | \n",
+ " -0.010002 | \n",
+ " -0.132188 | \n",
+ " -0.002792 | \n",
+ " 0.155806 | \n",
+ " 0.666179 | \n",
+ " 0.178013 | \n",
+ " 0.000002 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 0.177806 | \n",
+ " 1.433673 | \n",
+ " -0.246529 | \n",
+ " -0.367718 | \n",
+ " 0.253413 | \n",
+ " -0.114293 | \n",
+ " -0.186285 | \n",
+ " 70.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " 0.297142 | \n",
+ " 0.867999 | \n",
+ " 0.522022 | \n",
+ " 0.386887 | \n",
+ " 0.600601 | \n",
+ " 0.541542 | \n",
+ " 0.374875 | \n",
+ " 0.0 | \n",
+ " -0.114293 | \n",
+ " -0.186285 | \n",
+ " -0.017375 | \n",
+ " -0.169370 | \n",
+ " -0.002792 | \n",
+ " 0.156921 | \n",
+ " 0.666275 | \n",
+ " 0.176803 | \n",
+ " 0.000001 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 410773 | \n",
+ " -0.748366 | \n",
+ " -0.804077 | \n",
+ " -0.650371 | \n",
+ " 0.702788 | \n",
+ " 0.253413 | \n",
+ " 1.365441 | \n",
+ " 1.501833 | \n",
+ " 52.0 | \n",
+ " 3.0 | \n",
+ " 0.0 | \n",
+ " 0.193143 | \n",
+ " 0.114753 | \n",
+ " 0.309810 | \n",
+ " 0.741742 | \n",
+ " 0.600601 | \n",
+ " 0.961367 | \n",
+ " 0.984535 | \n",
+ " 0.0 | \n",
+ " 1.365441 | \n",
+ " 1.501833 | \n",
+ " 0.068438 | \n",
+ " 1.570163 | \n",
+ " 0.008616 | \n",
+ " 0.147820 | \n",
+ " 0.665159 | \n",
+ " 0.187011 | \n",
+ " 0.000010 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " 410774 | \n",
+ " 1.257769 | \n",
+ " -1.101815 | \n",
+ " -0.044608 | \n",
+ " 0.091070 | \n",
+ " 1.175911 | \n",
+ " 0.553789 | \n",
+ " -0.142544 | \n",
+ " 14.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " 0.908036 | \n",
+ " 0.075725 | \n",
+ " 0.604605 | \n",
+ " 0.645646 | \n",
+ " 0.867367 | \n",
+ " 0.841842 | \n",
+ " 0.436436 | \n",
+ " 0.0 | \n",
+ " 0.553789 | \n",
+ " -0.142544 | \n",
+ " 0.014463 | \n",
+ " -0.002742 | \n",
+ " -0.002649 | \n",
+ " 0.152767 | \n",
+ " 0.665860 | \n",
+ " 0.181370 | \n",
+ " 0.000004 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
410775 rows × 28 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num__geo_lat num__geo_lon num__level num__levels num__rooms \\\n",
+ "0 0.495902 -0.449742 0.359235 -0.214789 0.253413 \n",
+ "1 0.177806 1.433673 -0.246529 -0.367718 0.253413 \n",
+ "... ... ... ... ... ... \n",
+ "410773 -0.748366 -0.804077 -0.650371 0.702788 0.253413 \n",
+ "410774 1.257769 -1.101815 -0.044608 0.091070 1.175911 \n",
+ "\n",
+ " num__area num__kitchen_area cat__region cat__building_type \\\n",
+ "0 0.063735 -0.186285 20.0 1.0 \n",
+ "1 -0.114293 -0.186285 70.0 1.0 \n",
+ "... ... ... ... ... \n",
+ "410773 1.365441 1.501833 52.0 3.0 \n",
+ "410774 0.553789 -0.142544 14.0 1.0 \n",
+ "\n",
+ " cat__object_type quantile__geo_lat quantile__geo_lon \\\n",
+ "0 0.0 0.766257 0.511028 \n",
+ "1 0.0 0.297142 0.867999 \n",
+ "... ... ... ... \n",
+ "410773 0.0 0.193143 0.114753 \n",
+ "410774 0.0 0.908036 0.075725 \n",
+ "\n",
+ " quantile__level quantile__levels quantile__rooms quantile__area \\\n",
+ "0 0.717217 0.536537 0.600601 0.623624 \n",
+ "1 0.522022 0.386887 0.600601 0.541542 \n",
+ "... ... ... ... ... \n",
+ "410773 0.309810 0.741742 0.600601 0.961367 \n",
+ "410774 0.604605 0.645646 0.867367 0.841842 \n",
+ "\n",
+ " quantile__kitchen_area poly__1 poly__area poly__kitchen_area \\\n",
+ "0 0.374875 0.0 0.063735 -0.186285 \n",
+ "1 0.374875 0.0 -0.114293 -0.186285 \n",
+ "... ... ... ... ... \n",
+ "410773 0.984535 0.0 1.365441 1.501833 \n",
+ "410774 0.436436 0.0 0.553789 -0.142544 \n",
+ "\n",
+ " poly__area^2 poly__area kitchen_area poly__kitchen_area^2 \\\n",
+ "0 -0.010002 -0.132188 -0.002792 \n",
+ "1 -0.017375 -0.169370 -0.002792 \n",
+ "... ... ... ... \n",
+ "410773 0.068438 1.570163 0.008616 \n",
+ "410774 0.014463 -0.002742 -0.002649 \n",
+ "\n",
+ " spline__area_sp_0 spline__area_sp_1 spline__area_sp_2 \\\n",
+ "0 0.155806 0.666179 0.178013 \n",
+ "1 0.156921 0.666275 0.176803 \n",
+ "... ... ... ... \n",
+ "410773 0.147820 0.665159 0.187011 \n",
+ "410774 0.152767 0.665860 0.181370 \n",
+ "\n",
+ " spline__area_sp_3 spline__area_sp_4 \n",
+ "0 0.000002 0.0 \n",
+ "1 0.000001 0.0 \n",
+ "... ... ... \n",
+ "410773 0.000010 0.0 \n",
+ "410774 0.000004 0.0 \n",
+ "\n",
+ "[410775 rows x 28 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
"# Удобно использовать для отображения всех строк\\столбцов в DataFrame\n",
"with pd.option_context('display.max_rows', 5, 'display.max_columns', None):\n",
@@ -914,9 +1190,368 @@
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
+ "execution_count": 81,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num__geo_lat | \n",
+ " num__geo_lon | \n",
+ " num__level | \n",
+ " num__levels | \n",
+ " num__rooms | \n",
+ " num__area | \n",
+ " num__kitchen_area | \n",
+ " cat__region | \n",
+ " cat__building_type | \n",
+ " cat__object_type | \n",
+ " afr__geo_lat | \n",
+ " afr__geo_lon | \n",
+ " afr__level | \n",
+ " afr__levels | \n",
+ " afr__rooms | \n",
+ " afr__area | \n",
+ " afr__kitchen_area | \n",
+ " afr__area*rooms | \n",
+ " afr__area*geo_lon | \n",
+ " afr__levels*rooms | \n",
+ " afr__area*kitchen_area | \n",
+ " afr__sqrt(area)*geo_lat | \n",
+ " afr__sqrt(area)*log(level) | \n",
+ " afr__kitchen_area*log(level) | \n",
+ " afr__sqrt(area)*kitchen_area | \n",
+ " afr__geo_lon*log(kitchen_area) | \n",
+ " afr__sqrt(area)*sqrt(kitchen_area) | \n",
+ " afr__sqrt(geo_lon)*sqrt(kitchen_area) | \n",
+ " afr__log(area) | \n",
+ " afr__rooms*log(level) | \n",
+ " afr__kitchen_area*rooms | \n",
+ " afr__kitchen_area*levels | \n",
+ " afr__sqrt(geo_lon)*sqrt(level) | \n",
+ " afr__area**(3/2) | \n",
+ " afr__geo_lat*log(kitchen_area) | \n",
+ " afr__geo_lat*log(geo_lon) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.495902 | \n",
+ " -0.449742 | \n",
+ " 0.359235 | \n",
+ " -0.214789 | \n",
+ " 0.253413 | \n",
+ " 0.063735 | \n",
+ " -0.186285 | \n",
+ " 20.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " 0.495902 | \n",
+ " -0.449742 | \n",
+ " 0.359235 | \n",
+ " -0.214789 | \n",
+ " 0.253413 | \n",
+ " 0.063735 | \n",
+ " -0.186285 | \n",
+ " 0.006208 | \n",
+ " -0.195129 | \n",
+ " 0.060916 | \n",
+ " -0.132188 | \n",
+ " 0.373151 | \n",
+ " 0.688076 | \n",
+ " 0.044178 | \n",
+ " -0.211335 | \n",
+ " -0.481294 | \n",
+ " -0.153548 | \n",
+ " -0.490805 | \n",
+ " 0.307835 | \n",
+ " 0.690329 | \n",
+ " -0.132529 | \n",
+ " -0.352834 | \n",
+ " 0.323880 | \n",
+ " -0.008748 | \n",
+ " -0.031529 | \n",
+ " 0.068167 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 0.177806 | \n",
+ " 1.433673 | \n",
+ " -0.246529 | \n",
+ " -0.367718 | \n",
+ " 0.253413 | \n",
+ " -0.114293 | \n",
+ " -0.186285 | \n",
+ " 70.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " 0.177806 | \n",
+ " 1.433673 | \n",
+ " -0.246529 | \n",
+ " -0.367718 | \n",
+ " 0.253413 | \n",
+ " -0.114293 | \n",
+ " -0.186285 | \n",
+ " -0.083402 | \n",
+ " 0.655053 | \n",
+ " -0.054279 | \n",
+ " -0.169370 | \n",
+ " 0.005114 | \n",
+ " 0.071369 | \n",
+ " -0.173647 | \n",
+ " -0.252775 | \n",
+ " 1.191304 | \n",
+ " -0.267268 | \n",
+ " 0.615798 | \n",
+ " 0.031907 | \n",
+ " 0.282625 | \n",
+ " -0.132529 | \n",
+ " -0.418643 | \n",
+ " 0.552794 | \n",
+ " -0.056540 | \n",
+ " -0.143829 | \n",
+ " 1.129118 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 410773 | \n",
+ " -0.748366 | \n",
+ " -0.804077 | \n",
+ " -0.650371 | \n",
+ " 0.702788 | \n",
+ " 0.253413 | \n",
+ " 1.365441 | \n",
+ " 1.501833 | \n",
+ " 52.0 | \n",
+ " 3.0 | \n",
+ " 0.0 | \n",
+ " -0.748366 | \n",
+ " -0.804077 | \n",
+ " -0.650371 | \n",
+ " 0.702788 | \n",
+ " 0.253413 | \n",
+ " 1.365441 | \n",
+ " 1.501833 | \n",
+ " 0.661427 | \n",
+ " 0.375199 | \n",
+ " 0.752088 | \n",
+ " 1.570163 | \n",
+ " 1.274445 | \n",
+ " -0.002521 | \n",
+ " 0.745507 | \n",
+ " 2.382258 | \n",
+ " 0.071599 | \n",
+ " 2.828890 | \n",
+ " 1.431272 | \n",
+ " 1.729715 | \n",
+ " -0.160491 | \n",
+ " 1.581436 | \n",
+ " 2.432437 | \n",
+ " -0.843150 | \n",
+ " 0.411475 | \n",
+ " 1.671069 | \n",
+ " -1.052343 | \n",
+ "
\n",
+ " \n",
+ " 410774 | \n",
+ " 1.257769 | \n",
+ " -1.101815 | \n",
+ " -0.044608 | \n",
+ " 0.091070 | \n",
+ " 1.175911 | \n",
+ " 0.553789 | \n",
+ " -0.142544 | \n",
+ " 14.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " 1.257769 | \n",
+ " -1.101815 | \n",
+ " -0.044608 | \n",
+ " 0.091070 | \n",
+ " 1.175911 | \n",
+ " 0.553789 | \n",
+ " -0.142544 | \n",
+ " 0.807887 | \n",
+ " -0.330070 | \n",
+ " 0.982478 | \n",
+ " -0.002742 | \n",
+ " 1.338996 | \n",
+ " 0.635065 | \n",
+ " -0.040302 | \n",
+ " -0.055435 | \n",
+ " -1.025588 | \n",
+ " 0.202136 | \n",
+ " -0.916054 | \n",
+ " 0.940624 | \n",
+ " 1.217910 | \n",
+ " 0.311575 | \n",
+ " -0.174762 | \n",
+ " -0.415359 | \n",
+ " 0.135617 | \n",
+ " 0.359680 | \n",
+ " -0.246790 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
410775 rows × 36 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num__geo_lat num__geo_lon num__level num__levels num__rooms \\\n",
+ "0 0.495902 -0.449742 0.359235 -0.214789 0.253413 \n",
+ "1 0.177806 1.433673 -0.246529 -0.367718 0.253413 \n",
+ "... ... ... ... ... ... \n",
+ "410773 -0.748366 -0.804077 -0.650371 0.702788 0.253413 \n",
+ "410774 1.257769 -1.101815 -0.044608 0.091070 1.175911 \n",
+ "\n",
+ " num__area num__kitchen_area cat__region cat__building_type \\\n",
+ "0 0.063735 -0.186285 20.0 1.0 \n",
+ "1 -0.114293 -0.186285 70.0 1.0 \n",
+ "... ... ... ... ... \n",
+ "410773 1.365441 1.501833 52.0 3.0 \n",
+ "410774 0.553789 -0.142544 14.0 1.0 \n",
+ "\n",
+ " cat__object_type afr__geo_lat afr__geo_lon afr__level afr__levels \\\n",
+ "0 0.0 0.495902 -0.449742 0.359235 -0.214789 \n",
+ "1 0.0 0.177806 1.433673 -0.246529 -0.367718 \n",
+ "... ... ... ... ... ... \n",
+ "410773 0.0 -0.748366 -0.804077 -0.650371 0.702788 \n",
+ "410774 0.0 1.257769 -1.101815 -0.044608 0.091070 \n",
+ "\n",
+ " afr__rooms afr__area afr__kitchen_area afr__area*rooms \\\n",
+ "0 0.253413 0.063735 -0.186285 0.006208 \n",
+ "1 0.253413 -0.114293 -0.186285 -0.083402 \n",
+ "... ... ... ... ... \n",
+ "410773 0.253413 1.365441 1.501833 0.661427 \n",
+ "410774 1.175911 0.553789 -0.142544 0.807887 \n",
+ "\n",
+ " afr__area*geo_lon afr__levels*rooms afr__area*kitchen_area \\\n",
+ "0 -0.195129 0.060916 -0.132188 \n",
+ "1 0.655053 -0.054279 -0.169370 \n",
+ "... ... ... ... \n",
+ "410773 0.375199 0.752088 1.570163 \n",
+ "410774 -0.330070 0.982478 -0.002742 \n",
+ "\n",
+ " afr__sqrt(area)*geo_lat afr__sqrt(area)*log(level) \\\n",
+ "0 0.373151 0.688076 \n",
+ "1 0.005114 0.071369 \n",
+ "... ... ... \n",
+ "410773 1.274445 -0.002521 \n",
+ "410774 1.338996 0.635065 \n",
+ "\n",
+ " afr__kitchen_area*log(level) afr__sqrt(area)*kitchen_area \\\n",
+ "0 0.044178 -0.211335 \n",
+ "1 -0.173647 -0.252775 \n",
+ "... ... ... \n",
+ "410773 0.745507 2.382258 \n",
+ "410774 -0.040302 -0.055435 \n",
+ "\n",
+ " afr__geo_lon*log(kitchen_area) afr__sqrt(area)*sqrt(kitchen_area) \\\n",
+ "0 -0.481294 -0.153548 \n",
+ "1 1.191304 -0.267268 \n",
+ "... ... ... \n",
+ "410773 0.071599 2.828890 \n",
+ "410774 -1.025588 0.202136 \n",
+ "\n",
+ " afr__sqrt(geo_lon)*sqrt(kitchen_area) afr__log(area) \\\n",
+ "0 -0.490805 0.307835 \n",
+ "1 0.615798 0.031907 \n",
+ "... ... ... \n",
+ "410773 1.431272 1.729715 \n",
+ "410774 -0.916054 0.940624 \n",
+ "\n",
+ " afr__rooms*log(level) afr__kitchen_area*rooms \\\n",
+ "0 0.690329 -0.132529 \n",
+ "1 0.282625 -0.132529 \n",
+ "... ... ... \n",
+ "410773 -0.160491 1.581436 \n",
+ "410774 1.217910 0.311575 \n",
+ "\n",
+ " afr__kitchen_area*levels afr__sqrt(geo_lon)*sqrt(level) \\\n",
+ "0 -0.352834 0.323880 \n",
+ "1 -0.418643 0.552794 \n",
+ "... ... ... \n",
+ "410773 2.432437 -0.843150 \n",
+ "410774 -0.174762 -0.415359 \n",
+ "\n",
+ " afr__area**(3/2) afr__geo_lat*log(kitchen_area) \\\n",
+ "0 -0.008748 -0.031529 \n",
+ "1 -0.056540 -0.143829 \n",
+ "... ... ... \n",
+ "410773 0.411475 1.671069 \n",
+ "410774 0.135617 0.359680 \n",
+ "\n",
+ " afr__geo_lat*log(geo_lon) \n",
+ "0 0.068167 \n",
+ "1 1.129118 \n",
+ "... ... \n",
+ "410773 -1.052343 \n",
+ "410774 -0.246790 \n",
+ "\n",
+ "[410775 rows x 36 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
"with pd.option_context('display.max_rows', 5, 'display.max_columns', None):\n",
" display (X_train_afr)\n"
@@ -983,6 +1618,1679 @@
"assert (run.info.status =='FINISHED')"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# FEATURE SELECTION\n",
+ "## RFE\n",
+ "### Используем autofeat признаки\n",
+ "Поскольку autofeat дает разные совокупности сгенерированных признаков, мы можем добавить выбор информативных только как шаг пайплайна "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 294,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num__geo_lat | \n",
+ " num__geo_lon | \n",
+ " num__level | \n",
+ " num__levels | \n",
+ " num__rooms | \n",
+ " num__area | \n",
+ " num__kitchen_area | \n",
+ " cat__region | \n",
+ " cat__building_type | \n",
+ " cat__object_type | \n",
+ " ... | \n",
+ " afr__sqrt(area)*sqrt(kitchen_area) | \n",
+ " afr__sqrt(geo_lon)*sqrt(kitchen_area) | \n",
+ " afr__log(area) | \n",
+ " afr__rooms*log(level) | \n",
+ " afr__kitchen_area*rooms | \n",
+ " afr__kitchen_area*levels | \n",
+ " afr__sqrt(geo_lon)*sqrt(level) | \n",
+ " afr__area**(3/2) | \n",
+ " afr__geo_lat*log(kitchen_area) | \n",
+ " afr__geo_lat*log(geo_lon) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.495902 | \n",
+ " -0.449742 | \n",
+ " 0.359235 | \n",
+ " -0.214789 | \n",
+ " 0.253413 | \n",
+ " 0.063735 | \n",
+ " -0.186285 | \n",
+ " 20.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " -0.153548 | \n",
+ " -0.490805 | \n",
+ " 0.307835 | \n",
+ " 0.690329 | \n",
+ " -0.132529 | \n",
+ " -0.352834 | \n",
+ " 0.323880 | \n",
+ " -0.008748 | \n",
+ " -0.031529 | \n",
+ " 0.068167 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 0.177806 | \n",
+ " 1.433673 | \n",
+ " -0.246529 | \n",
+ " -0.367718 | \n",
+ " 0.253413 | \n",
+ " -0.114293 | \n",
+ " -0.186285 | \n",
+ " 70.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " -0.267268 | \n",
+ " 0.615798 | \n",
+ " 0.031907 | \n",
+ " 0.282625 | \n",
+ " -0.132529 | \n",
+ " -0.418643 | \n",
+ " 0.552794 | \n",
+ " -0.056540 | \n",
+ " -0.143829 | \n",
+ " 1.129118 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 0.440548 | \n",
+ " 0.047222 | \n",
+ " -0.448450 | \n",
+ " -0.367718 | \n",
+ " -0.669085 | \n",
+ " -0.456947 | \n",
+ " -0.142544 | \n",
+ " 15.0 | \n",
+ " 3.0 | \n",
+ " 1.0 | \n",
+ " ... | \n",
+ " -0.454880 | \n",
+ " -0.067183 | \n",
+ " -0.603122 | \n",
+ " -0.512211 | \n",
+ " -0.487813 | \n",
+ " -0.383803 | \n",
+ " -0.243092 | \n",
+ " -0.140800 | \n",
+ " 0.063464 | \n",
+ " 0.460495 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " -1.588818 | \n",
+ " -0.722477 | \n",
+ " -0.246529 | \n",
+ " -0.979436 | \n",
+ " 0.253413 | \n",
+ " -0.181292 | \n",
+ " -0.142544 | \n",
+ " 18.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " -0.254514 | \n",
+ " -0.607607 | \n",
+ " -0.080304 | \n",
+ " 0.282625 | \n",
+ " -0.088119 | \n",
+ " -0.662523 | \n",
+ " -0.369355 | \n",
+ " -0.073838 | \n",
+ " -0.672113 | \n",
+ " -1.481033 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 1.493662 | \n",
+ " 1.125819 | \n",
+ " 0.157313 | \n",
+ " 0.549858 | \n",
+ " 0.253413 | \n",
+ " 0.615045 | \n",
+ " -0.011322 | \n",
+ " 10.0 | \n",
+ " 2.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " 0.438600 | \n",
+ " 0.891383 | \n",
+ " 1.009612 | \n",
+ " 0.574497 | \n",
+ " 0.045112 | \n",
+ " 0.208478 | \n",
+ " 0.945981 | \n",
+ " 0.154902 | \n",
+ " 0.780855 | \n",
+ " 1.923382 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 410770 | \n",
+ " 0.592011 | \n",
+ " 0.355014 | \n",
+ " 0.561156 | \n",
+ " 1.008646 | \n",
+ " 0.253413 | \n",
+ " -0.079836 | \n",
+ " -0.092653 | \n",
+ " 54.0 | \n",
+ " 2.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " -0.120035 | \n",
+ " 0.237580 | \n",
+ " 0.087725 | \n",
+ " 0.792500 | \n",
+ " -0.037463 | \n",
+ " 0.322797 | \n",
+ " 0.974381 | \n",
+ " -0.047496 | \n",
+ " 0.243018 | \n",
+ " 0.789871 | \n",
+ "
\n",
+ " \n",
+ " 410771 | \n",
+ " 0.240478 | \n",
+ " 0.392697 | \n",
+ " -0.650371 | \n",
+ " -0.979436 | \n",
+ " 0.253413 | \n",
+ " -0.334434 | \n",
+ " -0.404989 | \n",
+ " 45.0 | \n",
+ " 3.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " -0.716150 | \n",
+ " -0.510766 | \n",
+ " -0.357277 | \n",
+ " -0.160491 | \n",
+ " -0.354582 | \n",
+ " -0.778657 | \n",
+ " -0.406361 | \n",
+ " -0.111897 | \n",
+ " -0.808157 | \n",
+ " 0.574534 | \n",
+ "
\n",
+ " \n",
+ " 410772 | \n",
+ " -1.936771 | \n",
+ " -0.688830 | \n",
+ " 0.359235 | \n",
+ " 0.855717 | \n",
+ " -0.669085 | \n",
+ " -0.456947 | \n",
+ " -0.142544 | \n",
+ " 18.0 | \n",
+ " 0.0 | \n",
+ " 1.0 | \n",
+ " ... | \n",
+ " -0.454880 | \n",
+ " -0.581851 | \n",
+ " -0.603122 | \n",
+ " -0.211576 | \n",
+ " -0.487813 | \n",
+ " 0.173638 | \n",
+ " 0.170166 | \n",
+ " -0.140800 | \n",
+ " -0.798234 | \n",
+ " -1.663294 | \n",
+ "
\n",
+ " \n",
+ " 410773 | \n",
+ " -0.748366 | \n",
+ " -0.804077 | \n",
+ " -0.650371 | \n",
+ " 0.702788 | \n",
+ " 0.253413 | \n",
+ " 1.365441 | \n",
+ " 1.501833 | \n",
+ " 52.0 | \n",
+ " 3.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " 2.828890 | \n",
+ " 1.431272 | \n",
+ " 1.729715 | \n",
+ " -0.160491 | \n",
+ " 1.581436 | \n",
+ " 2.432437 | \n",
+ " -0.843150 | \n",
+ " 0.411475 | \n",
+ " 1.671069 | \n",
+ " -1.052343 | \n",
+ "
\n",
+ " \n",
+ " 410774 | \n",
+ " 1.257769 | \n",
+ " -1.101815 | \n",
+ " -0.044608 | \n",
+ " 0.091070 | \n",
+ " 1.175911 | \n",
+ " 0.553789 | \n",
+ " -0.142544 | \n",
+ " 14.0 | \n",
+ " 1.0 | \n",
+ " 0.0 | \n",
+ " ... | \n",
+ " 0.202136 | \n",
+ " -0.916054 | \n",
+ " 0.940624 | \n",
+ " 1.217910 | \n",
+ " 0.311575 | \n",
+ " -0.174762 | \n",
+ " -0.415359 | \n",
+ " 0.135617 | \n",
+ " 0.359680 | \n",
+ " -0.246790 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
410775 rows × 36 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num__geo_lat num__geo_lon num__level num__levels num__rooms \\\n",
+ "0 0.495902 -0.449742 0.359235 -0.214789 0.253413 \n",
+ "1 0.177806 1.433673 -0.246529 -0.367718 0.253413 \n",
+ "2 0.440548 0.047222 -0.448450 -0.367718 -0.669085 \n",
+ "3 -1.588818 -0.722477 -0.246529 -0.979436 0.253413 \n",
+ "4 1.493662 1.125819 0.157313 0.549858 0.253413 \n",
+ "... ... ... ... ... ... \n",
+ "410770 0.592011 0.355014 0.561156 1.008646 0.253413 \n",
+ "410771 0.240478 0.392697 -0.650371 -0.979436 0.253413 \n",
+ "410772 -1.936771 -0.688830 0.359235 0.855717 -0.669085 \n",
+ "410773 -0.748366 -0.804077 -0.650371 0.702788 0.253413 \n",
+ "410774 1.257769 -1.101815 -0.044608 0.091070 1.175911 \n",
+ "\n",
+ " num__area num__kitchen_area cat__region cat__building_type \\\n",
+ "0 0.063735 -0.186285 20.0 1.0 \n",
+ "1 -0.114293 -0.186285 70.0 1.0 \n",
+ "2 -0.456947 -0.142544 15.0 3.0 \n",
+ "3 -0.181292 -0.142544 18.0 1.0 \n",
+ "4 0.615045 -0.011322 10.0 2.0 \n",
+ "... ... ... ... ... \n",
+ "410770 -0.079836 -0.092653 54.0 2.0 \n",
+ "410771 -0.334434 -0.404989 45.0 3.0 \n",
+ "410772 -0.456947 -0.142544 18.0 0.0 \n",
+ "410773 1.365441 1.501833 52.0 3.0 \n",
+ "410774 0.553789 -0.142544 14.0 1.0 \n",
+ "\n",
+ " cat__object_type ... afr__sqrt(area)*sqrt(kitchen_area) \\\n",
+ "0 0.0 ... -0.153548 \n",
+ "1 0.0 ... -0.267268 \n",
+ "2 1.0 ... -0.454880 \n",
+ "3 0.0 ... -0.254514 \n",
+ "4 0.0 ... 0.438600 \n",
+ "... ... ... ... \n",
+ "410770 0.0 ... -0.120035 \n",
+ "410771 0.0 ... -0.716150 \n",
+ "410772 1.0 ... -0.454880 \n",
+ "410773 0.0 ... 2.828890 \n",
+ "410774 0.0 ... 0.202136 \n",
+ "\n",
+ " afr__sqrt(geo_lon)*sqrt(kitchen_area) afr__log(area) \\\n",
+ "0 -0.490805 0.307835 \n",
+ "1 0.615798 0.031907 \n",
+ "2 -0.067183 -0.603122 \n",
+ "3 -0.607607 -0.080304 \n",
+ "4 0.891383 1.009612 \n",
+ "... ... ... \n",
+ "410770 0.237580 0.087725 \n",
+ "410771 -0.510766 -0.357277 \n",
+ "410772 -0.581851 -0.603122 \n",
+ "410773 1.431272 1.729715 \n",
+ "410774 -0.916054 0.940624 \n",
+ "\n",
+ " afr__rooms*log(level) afr__kitchen_area*rooms \\\n",
+ "0 0.690329 -0.132529 \n",
+ "1 0.282625 -0.132529 \n",
+ "2 -0.512211 -0.487813 \n",
+ "3 0.282625 -0.088119 \n",
+ "4 0.574497 0.045112 \n",
+ "... ... ... \n",
+ "410770 0.792500 -0.037463 \n",
+ "410771 -0.160491 -0.354582 \n",
+ "410772 -0.211576 -0.487813 \n",
+ "410773 -0.160491 1.581436 \n",
+ "410774 1.217910 0.311575 \n",
+ "\n",
+ " afr__kitchen_area*levels afr__sqrt(geo_lon)*sqrt(level) \\\n",
+ "0 -0.352834 0.323880 \n",
+ "1 -0.418643 0.552794 \n",
+ "2 -0.383803 -0.243092 \n",
+ "3 -0.662523 -0.369355 \n",
+ "4 0.208478 0.945981 \n",
+ "... ... ... \n",
+ "410770 0.322797 0.974381 \n",
+ "410771 -0.778657 -0.406361 \n",
+ "410772 0.173638 0.170166 \n",
+ "410773 2.432437 -0.843150 \n",
+ "410774 -0.174762 -0.415359 \n",
+ "\n",
+ " afr__area**(3/2) afr__geo_lat*log(kitchen_area) \\\n",
+ "0 -0.008748 -0.031529 \n",
+ "1 -0.056540 -0.143829 \n",
+ "2 -0.140800 0.063464 \n",
+ "3 -0.073838 -0.672113 \n",
+ "4 0.154902 0.780855 \n",
+ "... ... ... \n",
+ "410770 -0.047496 0.243018 \n",
+ "410771 -0.111897 -0.808157 \n",
+ "410772 -0.140800 -0.798234 \n",
+ "410773 0.411475 1.671069 \n",
+ "410774 0.135617 0.359680 \n",
+ "\n",
+ " afr__geo_lat*log(geo_lon) \n",
+ "0 0.068167 \n",
+ "1 1.129118 \n",
+ "2 0.460495 \n",
+ "3 -1.481033 \n",
+ "4 1.923382 \n",
+ "... ... \n",
+ "410770 0.789871 \n",
+ "410771 0.574534 \n",
+ "410772 -1.663294 \n",
+ "410773 -1.052343 \n",
+ "410774 -0.246790 \n",
+ "\n",
+ "[410775 rows x 36 columns]"
+ ]
+ },
+ "execution_count": 294,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.feature_selection import RFE\n",
+ "X_train_afr"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "rfe_selector = RFE(estimator=regressor, n_features_to_select=12, step = 0.2) #drop 20% of features each iteration\n",
+ "X_train_rfe = rfe_selector.fit_transform(X_train_afr,y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 297,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num__geo_lat | \n",
+ " num__geo_lon | \n",
+ " afr__geo_lon | \n",
+ " afr__area*kitchen_area | \n",
+ " afr__sqrt(area)*geo_lat | \n",
+ " afr__sqrt(area)*log(level) | \n",
+ " afr__kitchen_area*log(level) | \n",
+ " afr__sqrt(area)*sqrt(kitchen_area) | \n",
+ " afr__rooms*log(level) | \n",
+ " afr__kitchen_area*rooms | \n",
+ " afr__sqrt(geo_lon)*sqrt(level) | \n",
+ " afr__geo_lat*log(geo_lon) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.495902 | \n",
+ " -0.449742 | \n",
+ " -0.449742 | \n",
+ " -0.132188 | \n",
+ " 0.373151 | \n",
+ " 0.688076 | \n",
+ " 0.044178 | \n",
+ " -0.153548 | \n",
+ " 0.690329 | \n",
+ " -0.132529 | \n",
+ " 0.323880 | \n",
+ " 0.068167 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 0.177806 | \n",
+ " 1.433673 | \n",
+ " 1.433673 | \n",
+ " -0.169370 | \n",
+ " 0.005114 | \n",
+ " 0.071369 | \n",
+ " -0.173647 | \n",
+ " -0.267268 | \n",
+ " 0.282625 | \n",
+ " -0.132529 | \n",
+ " 0.552794 | \n",
+ " 1.129118 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 0.440548 | \n",
+ " 0.047222 | \n",
+ " 0.047222 | \n",
+ " -0.226261 | \n",
+ " -0.425530 | \n",
+ " -0.335537 | \n",
+ " -0.239271 | \n",
+ " -0.454880 | \n",
+ " -0.512211 | \n",
+ " -0.487813 | \n",
+ " -0.243092 | \n",
+ " 0.460495 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " -1.588818 | \n",
+ " -0.722477 | \n",
+ " -0.722477 | \n",
+ " -0.165302 | \n",
+ " -0.723225 | \n",
+ " 0.034116 | \n",
+ " -0.129771 | \n",
+ " -0.254514 | \n",
+ " 0.282625 | \n",
+ " -0.088119 | \n",
+ " -0.369355 | \n",
+ " -1.481033 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 1.493662 | \n",
+ " 1.125819 | \n",
+ " 1.125819 | \n",
+ " 0.094342 | \n",
+ " 1.522265 | \n",
+ " 0.862773 | \n",
+ " 0.194490 | \n",
+ " 0.438600 | \n",
+ " 0.574497 | \n",
+ " 0.045112 | \n",
+ " 0.945981 | \n",
+ " 1.923382 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 410770 | \n",
+ " 0.592011 | \n",
+ " 0.355014 | \n",
+ " 0.355014 | \n",
+ " -0.120841 | \n",
+ " 0.206926 | \n",
+ " 0.714499 | \n",
+ " 0.226990 | \n",
+ " -0.120035 | \n",
+ " 0.792500 | \n",
+ " -0.037463 | \n",
+ " 0.974381 | \n",
+ " 0.789871 | \n",
+ "
\n",
+ " \n",
+ " 410771 | \n",
+ " 0.240478 | \n",
+ " 0.392697 | \n",
+ " 0.392697 | \n",
+ " -0.296252 | \n",
+ " -0.297209 | \n",
+ " -0.551021 | \n",
+ " -0.560144 | \n",
+ " -0.716150 | \n",
+ " -0.160491 | \n",
+ " -0.354582 | \n",
+ " -0.406361 | \n",
+ " 0.574534 | \n",
+ "
\n",
+ " \n",
+ " 410772 | \n",
+ " -1.936771 | \n",
+ " -0.688830 | \n",
+ " -0.688830 | \n",
+ " -0.226261 | \n",
+ " -1.192706 | \n",
+ " 0.306280 | \n",
+ " 0.100868 | \n",
+ " -0.454880 | \n",
+ " -0.211576 | \n",
+ " -0.487813 | \n",
+ " 0.170166 | \n",
+ " -1.663294 | \n",
+ "
\n",
+ " \n",
+ " 410773 | \n",
+ " -0.748366 | \n",
+ " -0.804077 | \n",
+ " -0.804077 | \n",
+ " 1.570163 | \n",
+ " 1.274445 | \n",
+ " -0.002521 | \n",
+ " 0.745507 | \n",
+ " 2.828890 | \n",
+ " -0.160491 | \n",
+ " 1.581436 | \n",
+ " -0.843150 | \n",
+ " -1.052343 | \n",
+ "
\n",
+ " \n",
+ " 410774 | \n",
+ " 1.257769 | \n",
+ " -1.101815 | \n",
+ " -1.101815 | \n",
+ " -0.002742 | \n",
+ " 1.338996 | \n",
+ " 0.635065 | \n",
+ " -0.040302 | \n",
+ " 0.202136 | \n",
+ " 1.217910 | \n",
+ " 0.311575 | \n",
+ " -0.415359 | \n",
+ " -0.246790 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
410775 rows × 12 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num__geo_lat num__geo_lon afr__geo_lon afr__area*kitchen_area \\\n",
+ "0 0.495902 -0.449742 -0.449742 -0.132188 \n",
+ "1 0.177806 1.433673 1.433673 -0.169370 \n",
+ "2 0.440548 0.047222 0.047222 -0.226261 \n",
+ "3 -1.588818 -0.722477 -0.722477 -0.165302 \n",
+ "4 1.493662 1.125819 1.125819 0.094342 \n",
+ "... ... ... ... ... \n",
+ "410770 0.592011 0.355014 0.355014 -0.120841 \n",
+ "410771 0.240478 0.392697 0.392697 -0.296252 \n",
+ "410772 -1.936771 -0.688830 -0.688830 -0.226261 \n",
+ "410773 -0.748366 -0.804077 -0.804077 1.570163 \n",
+ "410774 1.257769 -1.101815 -1.101815 -0.002742 \n",
+ "\n",
+ " afr__sqrt(area)*geo_lat afr__sqrt(area)*log(level) \\\n",
+ "0 0.373151 0.688076 \n",
+ "1 0.005114 0.071369 \n",
+ "2 -0.425530 -0.335537 \n",
+ "3 -0.723225 0.034116 \n",
+ "4 1.522265 0.862773 \n",
+ "... ... ... \n",
+ "410770 0.206926 0.714499 \n",
+ "410771 -0.297209 -0.551021 \n",
+ "410772 -1.192706 0.306280 \n",
+ "410773 1.274445 -0.002521 \n",
+ "410774 1.338996 0.635065 \n",
+ "\n",
+ " afr__kitchen_area*log(level) afr__sqrt(area)*sqrt(kitchen_area) \\\n",
+ "0 0.044178 -0.153548 \n",
+ "1 -0.173647 -0.267268 \n",
+ "2 -0.239271 -0.454880 \n",
+ "3 -0.129771 -0.254514 \n",
+ "4 0.194490 0.438600 \n",
+ "... ... ... \n",
+ "410770 0.226990 -0.120035 \n",
+ "410771 -0.560144 -0.716150 \n",
+ "410772 0.100868 -0.454880 \n",
+ "410773 0.745507 2.828890 \n",
+ "410774 -0.040302 0.202136 \n",
+ "\n",
+ " afr__rooms*log(level) afr__kitchen_area*rooms \\\n",
+ "0 0.690329 -0.132529 \n",
+ "1 0.282625 -0.132529 \n",
+ "2 -0.512211 -0.487813 \n",
+ "3 0.282625 -0.088119 \n",
+ "4 0.574497 0.045112 \n",
+ "... ... ... \n",
+ "410770 0.792500 -0.037463 \n",
+ "410771 -0.160491 -0.354582 \n",
+ "410772 -0.211576 -0.487813 \n",
+ "410773 -0.160491 1.581436 \n",
+ "410774 1.217910 0.311575 \n",
+ "\n",
+ " afr__sqrt(geo_lon)*sqrt(level) afr__geo_lat*log(geo_lon) \n",
+ "0 0.323880 0.068167 \n",
+ "1 0.552794 1.129118 \n",
+ "2 -0.243092 0.460495 \n",
+ "3 -0.369355 -1.481033 \n",
+ "4 0.945981 1.923382 \n",
+ "... ... ... \n",
+ "410770 0.974381 0.789871 \n",
+ "410771 -0.406361 0.574534 \n",
+ "410772 0.170166 -1.663294 \n",
+ "410773 -0.843150 -1.052343 \n",
+ "410774 -0.415359 -0.246790 \n",
+ "\n",
+ "[410775 rows x 12 columns]"
+ ]
+ },
+ "execution_count": 297,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "X_train_afr_rfe = pd.DataFrame(X_train_rfe, columns=rfe_selector.get_feature_names_out())\n",
+ "X_train_afr_rfe"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rfe_pipeline = Pipeline(steps=[\n",
+ " ('preprocessor', preprocessor_afr), \n",
+ " ('rfe_extractor', RFE(estimator=regressor, n_features_to_select=12, step = 0.2)),\n",
+ " ('model', regressor)\n",
+ "])\n",
+ "\n",
+ "rfe_pipeline.fit(X_train, y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 301,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'mae': 1431925.3203264712,\n",
+ " 'mape': 1.239752923791043e+18,\n",
+ " 'mse': 261947924998018.2}"
+ ]
+ },
+ "execution_count": 301,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "predictions_rfe = rfe_pipeline.predict(X_test)\n",
+ "\n",
+ "metrics = {}\n",
+ "metrics[\"mae\"] = mean_absolute_error(y_test, predictions_rfe) \n",
+ "metrics[\"mape\"] = mean_absolute_percentage_error(y_test, predictions_rfe)\n",
+ "metrics[\"mse\"] = mean_squared_error(y_test, predictions_rfe)\n",
+ "\n",
+ "metrics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 302,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Downloading artifacts: 100%|██████████| 7/7 [00:00<00:00, 40.15it/s]\n",
+ "2024/10/17 14:26:50 INFO mlflow.tracking._tracking_service.client: 🏃 View run rfe_feature_selection at: http://127.0.0.1:5000/#/experiments/1/runs/96f0bbcd6d88466abcf38f3b53f06ff1.\n",
+ "2024/10/17 14:26:50 INFO mlflow.tracking._tracking_service.client: 🧪 View experiment at: http://127.0.0.1:5000/#/experiments/1.\n"
+ ]
+ }
+ ],
+ "source": [
+ "experiment_id = mlflow.get_experiment_by_name(EXPERIMENT_NAME).experiment_id\n",
+ "RUN_NAME = 'rfe_feature_selection'\n",
+ "\n",
+ "with mlflow.start_run(run_name=RUN_NAME, experiment_id=experiment_id) as run:\n",
+ " # получаем уникальный идентификатор запуска эксперимента\n",
+ " run_id = run.info.run_id \n",
+ " mlflow.sklearn.log_model(rfe_pipeline, \n",
+ " artifact_path=\"models\",\n",
+ " signature=signature,\n",
+ " input_example=input_example,\n",
+ " pip_requirements=req_file\n",
+ " )\n",
+ " mlflow.log_metrics(metrics)\n",
+ " mlflow.log_artifact(art)\n",
+ " mlflow.log_params(model_sklearn.get_params())\n",
+ "\n",
+ "run = mlflow.get_run(run_id) \n",
+ "assert (run.info.status =='FINISHED')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Используем sklearn признаки\n",
+ "Тут мы можем отобрать признаки один раз на обучении, а далее в качестве шага пайплайна использовать написанный класс ColumnExtractor для выбора нуных столбцов"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "rfe_skl_selector = RFE(estimator=regressor, n_features_to_select=12, step = 0.2) #drop 20% of features each iteration\n",
+ "X_train_skl_rfe = rfe_skl_selector.fit_transform(X_train_sklearn,y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 305,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num__geo_lat | \n",
+ " num__geo_lon | \n",
+ " num__level | \n",
+ " num__rooms | \n",
+ " num__kitchen_area | \n",
+ " cat__region | \n",
+ " quantile__geo_lat | \n",
+ " quantile__geo_lon | \n",
+ " quantile__level | \n",
+ " poly__area kitchen_area | \n",
+ " spline__area_sp_0 | \n",
+ " spline__area_sp_2 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.495902 | \n",
+ " -0.449742 | \n",
+ " 0.359235 | \n",
+ " 0.253413 | \n",
+ " -0.186285 | \n",
+ " 20.0 | \n",
+ " 0.766257 | \n",
+ " 0.511028 | \n",
+ " 0.717217 | \n",
+ " -0.132188 | \n",
+ " 0.155806 | \n",
+ " 0.178013 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 0.177806 | \n",
+ " 1.433673 | \n",
+ " -0.246529 | \n",
+ " 0.253413 | \n",
+ " -0.186285 | \n",
+ " 70.0 | \n",
+ " 0.297142 | \n",
+ " 0.867999 | \n",
+ " 0.522022 | \n",
+ " -0.169370 | \n",
+ " 0.156921 | \n",
+ " 0.176803 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 0.440548 | \n",
+ " 0.047222 | \n",
+ " -0.448450 | \n",
+ " -0.669085 | \n",
+ " -0.142544 | \n",
+ " 15.0 | \n",
+ " 0.732330 | \n",
+ " 0.629984 | \n",
+ " 0.417417 | \n",
+ " -0.226261 | \n",
+ " 0.159080 | \n",
+ " 0.174488 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " -1.588818 | \n",
+ " -0.722477 | \n",
+ " -0.246529 | \n",
+ " 0.253413 | \n",
+ " -0.142544 | \n",
+ " 18.0 | \n",
+ " 0.148789 | \n",
+ " 0.295262 | \n",
+ " 0.522022 | \n",
+ " -0.165302 | \n",
+ " 0.157341 | \n",
+ " 0.176349 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 1.493662 | \n",
+ " 1.125819 | \n",
+ " 0.157313 | \n",
+ " 0.253413 | \n",
+ " -0.011322 | \n",
+ " 10.0 | \n",
+ " 0.985937 | \n",
+ " 0.758363 | \n",
+ " 0.662663 | \n",
+ " 0.094342 | \n",
+ " 0.152390 | \n",
+ " 0.181792 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 410770 | \n",
+ " 0.592011 | \n",
+ " 0.355014 | \n",
+ " 0.561156 | \n",
+ " 0.253413 | \n",
+ " -0.092653 | \n",
+ " 54.0 | \n",
+ " 0.788393 | \n",
+ " 0.686728 | \n",
+ " 0.771271 | \n",
+ " -0.120841 | \n",
+ " 0.156705 | \n",
+ " 0.177037 | \n",
+ "
\n",
+ " \n",
+ " 410771 | \n",
+ " 0.240478 | \n",
+ " 0.392697 | \n",
+ " -0.650371 | \n",
+ " 0.253413 | \n",
+ " -0.404989 | \n",
+ " 45.0 | \n",
+ " 0.494062 | \n",
+ " 0.717240 | \n",
+ " 0.309810 | \n",
+ " -0.296252 | \n",
+ " 0.158306 | \n",
+ " 0.175314 | \n",
+ "
\n",
+ " \n",
+ " 410772 | \n",
+ " -1.936771 | \n",
+ " -0.688830 | \n",
+ " 0.359235 | \n",
+ " -0.669085 | \n",
+ " -0.142544 | \n",
+ " 18.0 | \n",
+ " 0.131352 | \n",
+ " 0.327613 | \n",
+ " 0.717217 | \n",
+ " -0.226261 | \n",
+ " 0.159080 | \n",
+ " 0.174488 | \n",
+ "
\n",
+ " \n",
+ " 410773 | \n",
+ " -0.748366 | \n",
+ " -0.804077 | \n",
+ " -0.650371 | \n",
+ " 0.253413 | \n",
+ " 1.501833 | \n",
+ " 52.0 | \n",
+ " 0.193143 | \n",
+ " 0.114753 | \n",
+ " 0.309810 | \n",
+ " 1.570163 | \n",
+ " 0.147820 | \n",
+ " 0.187011 | \n",
+ "
\n",
+ " \n",
+ " 410774 | \n",
+ " 1.257769 | \n",
+ " -1.101815 | \n",
+ " -0.044608 | \n",
+ " 1.175911 | \n",
+ " -0.142544 | \n",
+ " 14.0 | \n",
+ " 0.908036 | \n",
+ " 0.075725 | \n",
+ " 0.604605 | \n",
+ " -0.002742 | \n",
+ " 0.152767 | \n",
+ " 0.181370 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
410775 rows × 12 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num__geo_lat num__geo_lon num__level num__rooms num__kitchen_area \\\n",
+ "0 0.495902 -0.449742 0.359235 0.253413 -0.186285 \n",
+ "1 0.177806 1.433673 -0.246529 0.253413 -0.186285 \n",
+ "2 0.440548 0.047222 -0.448450 -0.669085 -0.142544 \n",
+ "3 -1.588818 -0.722477 -0.246529 0.253413 -0.142544 \n",
+ "4 1.493662 1.125819 0.157313 0.253413 -0.011322 \n",
+ "... ... ... ... ... ... \n",
+ "410770 0.592011 0.355014 0.561156 0.253413 -0.092653 \n",
+ "410771 0.240478 0.392697 -0.650371 0.253413 -0.404989 \n",
+ "410772 -1.936771 -0.688830 0.359235 -0.669085 -0.142544 \n",
+ "410773 -0.748366 -0.804077 -0.650371 0.253413 1.501833 \n",
+ "410774 1.257769 -1.101815 -0.044608 1.175911 -0.142544 \n",
+ "\n",
+ " cat__region quantile__geo_lat quantile__geo_lon quantile__level \\\n",
+ "0 20.0 0.766257 0.511028 0.717217 \n",
+ "1 70.0 0.297142 0.867999 0.522022 \n",
+ "2 15.0 0.732330 0.629984 0.417417 \n",
+ "3 18.0 0.148789 0.295262 0.522022 \n",
+ "4 10.0 0.985937 0.758363 0.662663 \n",
+ "... ... ... ... ... \n",
+ "410770 54.0 0.788393 0.686728 0.771271 \n",
+ "410771 45.0 0.494062 0.717240 0.309810 \n",
+ "410772 18.0 0.131352 0.327613 0.717217 \n",
+ "410773 52.0 0.193143 0.114753 0.309810 \n",
+ "410774 14.0 0.908036 0.075725 0.604605 \n",
+ "\n",
+ " poly__area kitchen_area spline__area_sp_0 spline__area_sp_2 \n",
+ "0 -0.132188 0.155806 0.178013 \n",
+ "1 -0.169370 0.156921 0.176803 \n",
+ "2 -0.226261 0.159080 0.174488 \n",
+ "3 -0.165302 0.157341 0.176349 \n",
+ "4 0.094342 0.152390 0.181792 \n",
+ "... ... ... ... \n",
+ "410770 -0.120841 0.156705 0.177037 \n",
+ "410771 -0.296252 0.158306 0.175314 \n",
+ "410772 -0.226261 0.159080 0.174488 \n",
+ "410773 1.570163 0.147820 0.187011 \n",
+ "410774 -0.002742 0.152767 0.181370 \n",
+ "\n",
+ "[410775 rows x 12 columns]"
+ ]
+ },
+ "execution_count": 305,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "X_train_skl_rfe = pd.DataFrame(X_train_skl_rfe, columns=rfe_skl_selector.get_feature_names_out())\n",
+ "X_train_skl_rfe"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 306,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['num__geo_lat',\n",
+ " 'num__geo_lon',\n",
+ " 'num__level',\n",
+ " 'num__rooms',\n",
+ " 'num__kitchen_area',\n",
+ " 'cat__region',\n",
+ " 'quantile__geo_lat',\n",
+ " 'quantile__geo_lon',\n",
+ " 'quantile__level',\n",
+ " 'poly__area kitchen_area',\n",
+ " 'spline__area_sp_0',\n",
+ " 'spline__area_sp_2']"
+ ]
+ },
+ "execution_count": 306,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "rfe_cols = X_train_skl_rfe.columns.tolist()\n",
+ "rfe_cols"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 307,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([ True, True, True, False, True, False, True, True, False,\n",
+ " False, True, True, True, False, False, False, False, False,\n",
+ " False, False, False, True, False, True, False, True, False,\n",
+ " False])"
+ ]
+ },
+ "execution_count": 307,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "rfe_idx = rfe_skl_selector.support_\n",
+ "rfe_idx"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 316,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Отбираемые столбцы нужно залогировать, иначе мы потеряем информацию о том, какие призныки выбраны\n",
+ "with open('rfe_skl_idx.txt', 'w+') as f:\n",
+ " f.write(str(rfe_idx))\n",
+ "with open('rfe_skl_cols.txt', 'w+') as f:\n",
+ " f.write(str(rfe_cols))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 309,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class ColumnExtractor(object):\n",
+ "\n",
+ " def __init__(self, cols):\n",
+ " self.cols = cols\n",
+ "\n",
+ " def transform(self, X):\n",
+ " return X[:,self.cols]\n",
+ " \n",
+ " def fit(self, X, y=None):\n",
+ " return self\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rfe_skl_pipeline = Pipeline(steps=[\n",
+ " ('preprocessor', preprocessor_sklearn), \n",
+ " ('rfe_extractor', ColumnExtractor(rfe_idx)),\n",
+ " ('model', regressor)\n",
+ "])\n",
+ "\n",
+ "rfe_skl_pipeline.fit(X_train, y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 311,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Downloading artifacts: 100%|██████████| 7/7 [00:00<00:00, 193.34it/s]\n",
+ "2024/10/17 14:32:07 INFO mlflow.tracking._tracking_service.client: 🏃 View run rfe_skl_feature_selection at: http://127.0.0.1:5000/#/experiments/1/runs/e55206caeb1549e4aa0d98343d5c1d4d.\n",
+ "2024/10/17 14:32:07 INFO mlflow.tracking._tracking_service.client: 🧪 View experiment at: http://127.0.0.1:5000/#/experiments/1.\n"
+ ]
+ }
+ ],
+ "source": [
+ "predictions_rfe_skl = rfe_skl_pipeline.predict(X_test)\n",
+ "\n",
+ "metrics = {}\n",
+ "metrics[\"mae\"] = mean_absolute_error(y_test, predictions_rfe_skl) \n",
+ "metrics[\"mape\"] = mean_absolute_percentage_error(y_test, predictions_rfe_skl)\n",
+ "metrics[\"mse\"] = mean_squared_error(y_test, predictions_rfe_skl)\n",
+ "\n",
+ "metrics\n",
+ "experiment_id = mlflow.get_experiment_by_name(EXPERIMENT_NAME).experiment_id\n",
+ "RUN_NAME = 'rfe_skl_feature_selection'\n",
+ "\n",
+ "with mlflow.start_run(run_name=RUN_NAME, experiment_id=experiment_id) as run:\n",
+ " # получаем уникальный идентификатор запуска эксперимента\n",
+ " run_id = run.info.run_id \n",
+ " mlflow.sklearn.log_model(rfe_pipeline, \n",
+ " artifact_path=\"models\",\n",
+ " signature=signature,\n",
+ " input_example=input_example,\n",
+ " pip_requirements=req_file\n",
+ " )\n",
+ " mlflow.log_metrics(metrics)\n",
+ " mlflow.log_artifact('rfe_skl_cols.txt')\n",
+ " mlflow.log_artifact('rfe_skl_idx.txt')\n",
+ " mlflow.log_params(model_sklearn.get_params())\n",
+ "\n",
+ "run = mlflow.get_run(run_id) \n",
+ "assert (run.info.status =='FINISHED')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## mlextend\n",
+ "https://github.com/rasbt/mlxtend/blob/master/docs/sources/user_guide/feature_selection/SequentialFeatureSelector.ipynb "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 312,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from mlxtend.feature_selection import SequentialFeatureSelector \n",
+ "#from sklearn.feature_selection import SequentialFeatureSelector"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sfs = SequentialFeatureSelector(RandomForestRegressor(n_estimators=3), \n",
+ " k_features=3,\n",
+ " forward=True,\n",
+ " floating=False, # True to drop selected features\n",
+ " scoring='neg_mean_absolute_error',\n",
+ " cv=2)\n",
+ "\n",
+ "sfs.fit(X_train_sklearn,y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 314,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num__geo_lon | \n",
+ " quantile__geo_lat | \n",
+ " spline__area_sp_3 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " -0.449742 | \n",
+ " 0.766257 | \n",
+ " 1.826008e-06 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 1.433673 | \n",
+ " 0.297142 | \n",
+ " 1.310449e-06 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 0.047222 | \n",
+ " 0.732330 | \n",
+ " 6.098363e-07 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " -0.722477 | \n",
+ " 0.148789 | \n",
+ " 1.144942e-06 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 1.125819 | \n",
+ " 0.985937 | \n",
+ " 4.240047e-06 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 410770 | \n",
+ " 0.355014 | \n",
+ " 0.788393 | \n",
+ " 1.401454e-06 | \n",
+ "
\n",
+ " \n",
+ " 410771 | \n",
+ " 0.392697 | \n",
+ " 0.494062 | \n",
+ " 8.202272e-07 | \n",
+ "
\n",
+ " \n",
+ " 410772 | \n",
+ " -0.688830 | \n",
+ " 0.131352 | \n",
+ " 6.098363e-07 | \n",
+ "
\n",
+ " \n",
+ " 410773 | \n",
+ " -0.804077 | \n",
+ " 0.193143 | \n",
+ " 1.004843e-05 | \n",
+ "
\n",
+ " \n",
+ " 410774 | \n",
+ " -1.101815 | \n",
+ " 0.908036 | \n",
+ " 3.903343e-06 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
410775 rows × 3 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num__geo_lon quantile__geo_lat spline__area_sp_3\n",
+ "0 -0.449742 0.766257 1.826008e-06\n",
+ "1 1.433673 0.297142 1.310449e-06\n",
+ "2 0.047222 0.732330 6.098363e-07\n",
+ "3 -0.722477 0.148789 1.144942e-06\n",
+ "4 1.125819 0.985937 4.240047e-06\n",
+ "... ... ... ...\n",
+ "410770 0.355014 0.788393 1.401454e-06\n",
+ "410771 0.392697 0.494062 8.202272e-07\n",
+ "410772 -0.688830 0.131352 6.098363e-07\n",
+ "410773 -0.804077 0.193143 1.004843e-05\n",
+ "410774 -1.101815 0.908036 3.903343e-06\n",
+ "\n",
+ "[410775 rows x 3 columns]"
+ ]
+ },
+ "execution_count": 314,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "selected_features_sfs = X_train_sklearn.loc[:, sfs.k_feature_names_]\n",
+ "selected_features_sfs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 315,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['num__geo_lon', 'quantile__geo_lat', 'spline__area_sp_3']"
+ ]
+ },
+ "execution_count": 315,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "rfe_sfs_idx = list(sfs.k_feature_idx_)\n",
+ "rfe_sfs_idx\n",
+ "rfe_sfs_col = list(sfs.k_feature_names_)\n",
+ "rfe_sfs_col"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 317,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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AHjxxRdhMpnQq1cvvPjii3jxxRdx4403HvX8y5cvh91ux5QpU/D444+jR48emDFjRp1uf8iyjIKCgnL/PB5P5PPjxo3DjBkzcMopp+Cxxx5D7969MWfOHFxzzTUVjrV161Zce+216NevHx5//HGcdNJJ6NWrFzZt2hQJJ0IIrF+/HlqtFuvWrYs8dt26ddBqtZE3sB07duCdd97BwIEDMX/+fNx555347bff0Lt373JzPso88MAD+OCDD3DHHXfgoYcegtFoxCeffIIrrrgCGo0Gc+bMweWXX47Ro0fjxx9/rPb70rp1awDAG2+8US7AVsbn86F379546aWXMGLECDzxxBM4++yzMX369HJv7JXJzc3FmWeeiU8//RS33HILHn/8cXTo0AFjx47FggULIvvJsoyBAwdi1qxZ6NGjBx599FHcdtttKC0txe+//46MjAw888wzAIDBgwdHfp+GDBly1HPX5me7bds2DB06FP369cOjjz6KlJQUjBo1Cn/88UeVX58kSfjhhx8qBOJevXpBURR8/fXXkW1lvwNH/l788ssv8Hg8OPfcc6s8z5HKfnYvvPAChBBH3e/GG29Ev379ACDy/XrxxRcBqL+nl112GV588UVcf/31ePDBB7Fv3z6MHDmyxuMoM3z4cADAJ598EtlWk9eSSy65BHa7Ha+//nqFY7722mvo1q0bunfvHtmWlJSE9u3bN/pJ6o2CIIqDTz75ROh0OqHT6UTPnj3Ff/7zH/Hxxx+LUChUbr9du3YJnU4nZs+eXW77b7/9JvR6fWR7KBQSmZmZ4qSTThLBYDCy33PPPScAiN69e0e2LVu2TAAQO3fuLHfMzz//XAAQn3/+uRBCCEVRRMeOHUX//v2FoiiR/Xw+n2jbtq3o169fZNvMmTMFADFmzJhyxxw8eLBIS0srt81ms4mRI0dW+J5UNi6fz1dhvxtvvFFYrVYRCAQi20aOHClat25dYd9/6927twBQ4V/ZeDZu3CgAiHHjxpV73B133CEAiM8++yyyrXXr1gKAWL16dbl9f/jhBwFAfPjhh0IIIX799VcBQFx55ZXijDPOiOw3aNAgcfLJJ0c+DgQCQpblcsfauXOnMJlM4v77749sK/s5tWvXrsL356STThLZ2dmipKQksu2TTz4RAGr0/RkxYoQAIFJSUsTgwYPFvHnzxObNmyvs98ADDwibzSb++uuvctunTZsmdDqd2LNnT2QbADFz5szIx2PHjhXZ2dmioKCg3GOvueYakZSUFPmali5dKgCI+fPnVzh/2e9jfn5+heOXKfudLBPNz/arr76KbMvLyxMmk0lMnTq1wrmOtG3bNgFAPPnkk+W2y7IsnE6n+M9//hP5GtLS0sSVV14pdDqdcLvdQggh5s+fL7RarSguLq7yPEfy+Xyic+fOkZ/zqFGjxJIlS0Rubm6FfSdOnCgqe2t75513BADxyCOPRLaFw2HRq1cvAUAsW7Yssr3se5ufn1/peIqLiwUAMXjw4MjXWtPXkmuvvVZkZmaKcDgc2Xbw4EGh1WrLPQ/KXHjhheK4446r4rtDscArQxQX/fr1w7fffotBgwZh06ZNeOSRR9C/f3+0aNGi3K2Ut99+G4qi4Kqrrip3JSMrKwsdO3bE559/DgD48ccfkZeXhwkTJsBoNEYeX3bJOxobN27E33//jeuuuw6FhYWRc3u9XlxwwQX46quvKtwSmTBhQrmPe/XqhcLCwshVkto6cv6N2+1GQUEBevXqBZ/PF3X1V5s2bbBmzZpy//7zn/8AUCeXAqhwdWPq1KkAgA8++KDc9rZt26J///7ltp188smw2+346quvAKh//efk5GDEiBH4+eef4fP5IITA119/jV69ekUeZzKZInN+ZFlGYWEh7HY7OnfujJ9//rnC1zFy5Mhy35+DBw9i48aNGDlyZLmfeb9+/dC1a9cafW+WLVuGp556Cm3btsWqVatwxx134LjjjsMFF1yA/fv3R/Z744030KtXL6SkpJT7vezbty9kWY587f8mhMBbb72FSy+9FEKIco/t378/SktLI1/rW2+9hfT09EqLCaIpma/tz7Zr167lfj4ZGRno3LkzduzYUeV5CgsLAQApKSnltmu1Wpx11lmR783mzZtRWFiIadOmQQiBb7/9FoD6+9K9e/dKb6EfjcViwXfffYc777wTgHpFdezYscjOzsakSZNqVN314YcfQq/X46abbops0+l0URVzlN0edLvdAGr3WnL11VcjLy+v3O36N998E4qi4Oqrr65wrrLfQYovhqFa+Oqrr3DppZeiefPm0Gg0UZVPCyEwb948dOrUCSaTCS1atMDs2bNjP9gG4LTTTsPbb7+N4uJifP/995g+fTrcbjeGDh2KP//8EwDw999/QwiBjh07IiMjo9y/zZs3RyZb7969GwDQsWPHcucwGAxRTyz8+++/Aahvuv8+9+LFixEMBlFaWlruMa1atSr3cdkbQnFxcVRj+OOPPzB48GAkJSXB6XQiIyMjMvn53+euKZvNhr59+5b7VxYWdu/eDa1Wiw4dOpR7TFZWFpKTkyPf5zJt27atcHydToeePXtGbn2sW7cOvXr1wjnnnANZlrFhwwb8+eefKCoqKvdmqygKHnvsMXTs2BEmkwnp6enIyMjAr7/+WunX+u9zH+13AAA6d+5ck28NtFotJk6ciJ9++gkFBQX43//+h4suugifffZZuVtJf//9N1avXl3h96JsDsfRigDy8/NRUlKC5557rsJjR48eXe6x27dvR+fOnWM2Cbq2P9t//y4D6u9zTX+XRSW3q3r16oWffvoJfr8f69atQ3Z2Nk455RSceOKJkd+Xf4fkmkpKSsIjjzyCXbt2YdeuXViyZAk6d+6Mp556Cg888EC1j9+9ezeys7PLzXMCav67c6Sy284OhwNA7V5LyuYUvfbaa5HjvfbaazjppJPQqVOnCucSQiS0n1RTwWqyWvB6vTjxxBMxZsyYKu/bV+W2227DJ598gnnz5uH4449HUVERioqKYjzShsVoNOK0007Daaedhk6dOmH06NF44403MHPmTCiKEplkW1ml1b9fuGriaC8c/56UXPaX2v/93//hpJNOqvQx/z7/0arBKntjqE5JSQl69+4Np9OJ+++/H+3bt4fZbMbPP/+Mu+66q0YTdaNV0xfXo1WOnXPOOZg9ezYCgQDWrVuHe+65B8nJyejevTvWrVuHZs2aAUC5N72HHnoI9957L8aMGYMHHngAqamp0Gq1mDx5cqVfa7yr1tLS0jBo0CAMGjQIffr0wZdffondu3ejdevWUBQF/fr1i1xR+7fK3rSAf36nrr/++qPORTnhhBNi8wUcRU1/ttH+LqelpQGo/A+Ac845B5Ik4dtvv42EZED9PVi3bh22bNmC/Pz8qMLQkVq3bo0xY8Zg8ODBaNeuHVauXIkHH3ywTsesjbK5kGXBszavJSaTCZdffjlWrVqFp59+Grm5uVi/fj0eeuihSh9XXFxcrqKN4oNhqBYuuugiXHTRRUf9fDAYxD333INXXnkFJSUl6N69O+bOnRupdNq8eTOeeeYZ/P7775G/Rir7y/tYduqppwJQb3kAQPv27SGEQNu2bY/6BgP8M4Hy77//xvnnnx/ZLkkSdu7ciRNPPDGyrexqzb+rRP79l3H79u0BAE6nM/IXfyzU9M3oiy++QGFhId5+++1yk0l37twZs7H8W9kb/d9//43jjjsusj03NxclJSWR73N1evXqhVAohFdeeQX79++PvLmde+65kTDUqVOnSCgC1FsB5513HpYsWVLuWCUlJTV6sT/yd+Dftm7dWqNxH82pp56KL7/8EgcPHkTr1q3Rvn17eDyeWv9eZGRkwOFwQJblah/bvn17fPfdd5AkCQaDodJ9anNFIFY/2+q0atUKFoul0t/T008/HUajEevWrcO6desit7XOPfdcPP/881i7dm3k41hISUlB+/btyxVqHO171rp1a6xduxYej6fcHznR/O6UTcouu4Vc29eSq6++GitWrMDatWuxefNmCCEqvUUGoMLrG8UHb5PF0C233IJvv/0Wr776Kn799VdceeWVGDBgQOTF+7333kO7du3w/vvvo23btmjTpg3GjRt3TF4Z+vzzzyv9C7NsXkNZGBwyZAh0Oh1mzZpVYX8hRGR+wqmnnoqMjAw8++yz5XqKLF++vELoKXthOnJehyzLFXrL9OjRA+3bt8e8efPKVVuVibbvjM1mq1G5btlf5kd+3aFQCE8//XRU562Jiy++GADKVTUBwPz58wGo1S41ccYZZ8BgMGDu3LlITU1Ft27dAKghacOGDfjyyy8r/PWv0+kq/IzfeOONcnN1qpKdnY2TTjoJK1asKHdbbc2aNZHbrlU5dOhQpfuFQiGsXbu23C2mq666Ct9++y0+/vjjCvuXlJQgHA5Xeg6dTocrrrgCb731VqWVlEf+Tl1xxRUoKCjAU089VWG/su+T1WqNnLM6sfrZVsdgMODUU0+ttILPbDbjtNNOwyuvvII9e/aUuzLk9/vxxBNPoH379sjOzgag3gresmVLtbeEN23aVOm8md27d+PPP/8sd6vLZrMBqPg9u/jiixEOhyMVeoD6ulDbjvgvv/wyFi9ejJ49e+KCCy4AUPvXkr59+yI1NRWvvfYaXnvtNZx++umV/mFcWlqK7du346yzzqrVGKn2eGUoRvbs2YNly5Zhz549kU6od9xxB1avXo1ly5bhoYcewo4dO7B792688cYbeOGFFyDLMm6//XYMHToUn332WYK/gtiaNGkSfD4fBg8ejC5duiAUCuGbb77Ba6+9hjZt2kTmT7Rv3x4PPvggpk+fjl27duHyyy+Hw+HAzp07sWrVKtxwww244447YDAY8OCDD+LGG2/E+eefj6uvvho7d+7EsmXLKswZ6tatG84880xMnz4dRUVFSE1NxauvvlrhDUyr1WLx4sW46KKL0K1bN4wePRotWrTA/v378fnnn8PpdOK9996r9dfeo0cPfPrpp5g/fz6aN2+Otm3bVrrG0FlnnYWUlBSMHDkSt956KzQaDV588cWobrnV1IknnoiRI0fiueeei9ym+/7777FixQpcfvnlOO+882p0HKvVih49emDDhg2RHkOA+he/1+uF1+utEIYGDhyI+++/H6NHj8ZZZ52F3377DStXrqzVnK85c+bgkksuwTnnnIMxY8agqKgITz75JLp161bpm9CR9u3bh9NPPx3nn38+LrjgAmRlZSEvLw+vvPIKNm3ahMmTJ0euUN1555149913MXDgQIwaNQo9evSA1+vFb7/9hjfffBO7du066tWshx9+GJ9//jnOOOMMjB8/Hl27dkVRURF+/vlnfPrpp5E/fkaMGIEXXngBU6ZMwffff49evXrB6/Xi008/xc0334zLLrsMFosFXbt2xWuvvYZOnTohNTUV3bt3L1d+XSZWP9uauOyyy3DPPffA5XJFevyU6dWrFx5++GEkJSXh+OOPB6D2FuvcuTO2bt0a6bsFAKtWrcLo0aOxbNmyctv/bc2aNZg5cyYGDRqEM888E3a7HTt27MDSpUsRDAbLdZvu0aMHALXbeP/+/aHT6XDNNdfg0ksvxdlnn41p06Zh165d6Nq1K95+++0qg9ibb74Ju92OUCgU6UC9fv16nHjiiXjjjTci+9X2tcRgMGDIkCF49dVX4fV6MW/evErP/+mnn0ZaAlCc1W/x2rEDgFi1alXk4/fff18AEDabrdw/vV4vrrrqKiGEEOPHjxcAxNatWyOP++mnnwQAsWXLlvr+EuLqo48+EmPGjBFdunQRdrtdGI1G0aFDBzFp0qRKy2Hfeustcc4550S+b126dBETJ04s970SQoinn35atG3bVphMJnHqqaeKr776SvTu3btcab0QQmzfvl307dtXmEwm0axZM3H33XeLNWvWlCutL/PLL7+IIUOGiLS0NGEymUTr1q3FVVddJdauXRvZ52iltpWV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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "from mlxtend.plotting import plot_sequential_feature_selection as plot_sfs\n",
+ "\n",
+ "fig = plot_sfs(sfs.get_metric_dict(), kind='std_dev')\n",
+ "\n",
+ "plt.title('Sequential Forward Selection (w. StdDev)')\n",
+ "plt.grid()\n",
+ "plt.show()\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rfe_sfs_pipeline = Pipeline(steps=[\n",
+ " ('preprocessor', preprocessor_sklearn), \n",
+ " ('rfe_extractor', ColumnExtractor(rfe_sfs_idx)),\n",
+ " ('model', regressor)\n",
+ "])\n",
+ "\n",
+ "rfe_sfs_pipeline.fit(X_train, y_train)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "predictions_sfs = rfe_sfs_pipeline.predict(X_test)\n",
+ "\n",
+ "metrics = {}\n",
+ "metrics[\"mae\"] = mean_absolute_error(y_test, predictions_sfs) \n",
+ "metrics[\"mape\"] = mean_absolute_percentage_error(y_test, predictions_sfs)\n",
+ "metrics[\"mse\"] = mean_squared_error(y_test, predictions_sfs)\n",
+ "\n",
+ "metrics\n",
+ "experiment_id = mlflow.get_experiment_by_name(EXPERIMENT_NAME).experiment_id\n",
+ "RUN_NAME = 'rfe_sfs_feature_selection'\n",
+ "\n",
+ "with mlflow.start_run(run_name=RUN_NAME, experiment_id=experiment_id) as run:\n",
+ " # получаем уникальный идентификатор запуска эксперимента\n",
+ " run_id = run.info.run_id \n",
+ " mlflow.sklearn.log_model(rfe_sfs_pipeline, \n",
+ " artifact_path=\"models\",\n",
+ " signature=signature,\n",
+ " input_example=input_example,\n",
+ " pip_requirements=req_file\n",
+ " )\n",
+ " mlflow.log_metrics(metrics)\n",
+ " mlflow.log_artifact('rfe_skl_cols.txt')\n",
+ " mlflow.log_artifact('rfe_skl_idx.txt')\n",
+ " mlflow.log_params(model_sklearn.get_params())\n",
+ "\n",
+ "run = mlflow.get_run(run_id) \n",
+ "assert (run.info.status =='FINISHED')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "Можно совмещать признаки, выбранные по sfs и sbs: брать их объединение или пересечение. Можно комбинировать с признаками, выделенными разными подходами - целое поле для исследований"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# HYPERPARAMS\n",
+ "## Gridsearch"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 224,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sklearn.model_selection import GridSearchCV"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "param_grid = {\n",
+ " 'model__depth': [1,3,5]\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gs = GridSearchCV(rfe_sfs_pipeline, param_grid, cv=2, scoring='neg_mean_absolute_error')\n",
+ "gs.fit(X_train, y_train)\n",
+ "print(\"Лучшие гиперпараметры:\", gs.best_params_)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gs_pipeline = Pipeline(steps=[\n",
+ " ('preprocessor', preprocessor_sklearn), \n",
+ " ('rfe_extractor', ColumnExtractor(rfe_sfs_idx)),\n",
+ " ('model', CatBoostRegressor(depth=5))\n",
+ "])\n",
+ "\n",
+ "# Проведем стандартную проверку на тестовом множестве и залогируем run"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Вместо GridSearch можно использовать RandomSearch"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Optuna"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 292,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import optuna"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def objective(trial):\n",
+ " # предлагаем гиперпараметры\n",
+ " depth = trial.suggest_int('depth', 1, 10)\n",
+ " learning_rate = trial.suggest_float('learning_rate', 0.001, 0.1)\n",
+ "\n",
+ " # создаём и обучаем модель\n",
+ " opt_pipeline = Pipeline(steps=[\n",
+ " ('preprocessor', preprocessor_sklearn), \n",
+ " ('rfe_extractor', ColumnExtractor(rfe_sfs_idx)),\n",
+ " ('model', CatBoostRegressor(depth=depth, learning_rate=learning_rate, verbose=0))\n",
+ " ])\n",
+ "\n",
+ " opt_pipeline.fit(X_train, y_train)\n",
+ "\n",
+ " # предсказываем и вычисляем RMSE\n",
+ " preds = opt_pipeline.predict(X_test)\n",
+ " mae = mean_absolute_error(y_test, preds) \n",
+ "\n",
+ " return mae"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "study = optuna.create_study(direction='minimize')\n",
+ "study.optimize(objective, n_trials=10)\n",
+ "\n",
+ "# выводим результаты\n",
+ "print('Number of finished trials:', len(study.trials))\n",
+ "print('Best trial:', study.best_trial.params) "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "opt_pipeline = Pipeline(steps=[\n",
+ " ('preprocessor', preprocessor_sklearn), \n",
+ " ('rfe_extractor', ColumnExtractor(rfe_sfs_idx)),\n",
+ " ('model', CatBoostRegressor(depth=3, learning_rate=0.02789))\n",
+ "])\n",
+ "\n",
+ "# Проведем стандартную проверку на тестовом множестве и залогируем run"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Выбираем лучшую модель.\n",
+ "Обучаем ее на всей выборке (а не только на train-части). \n",
+ "Далее будем деплоить именно её"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,