From 1f9b7fcbe97e147f4e5adc18db1413bec63375c8 Mon Sep 17 00:00:00 2001 From: GokaPek Date: Fri, 11 Oct 2024 23:18:43 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D1=87=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab_3/lab3.ipynb | 484 +++++++++++++++++++++++------------------------ 1 file changed, 239 insertions(+), 245 deletions(-) diff --git a/lab_3/lab3.ipynb b/lab_3/lab3.ipynb index 337db01..7c9e25e 100644 --- a/lab_3/lab3.ipynb +++ b/lab_3/lab3.ipynb @@ -45,7 +45,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -78,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -181,82 +181,9 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " ID Price Levy Manufacturer Prod. year Engine volume \\\n", - "3438 45793776 13485 781 VOLKSWAGEN 2012 2.5 \n", - "3185 45760664 314 781 SUBARU 2012 2.5 \n", - "5529 45777845 5645 5908 BMW 1999 2.5 \n", - "7891 45651201 7997 1850 LEXUS 2008 3.5 \n", - "12167 45798755 15681 765 VOLKSWAGEN 2015 2 \n", - "... ... ... ... ... ... ... \n", - "2750 45656065 941 1055 LEXUS 2013 3.5 \n", - "17390 45785069 12000 - FORD 1998 2.5 \n", - "5563 45815001 941 777 TOYOTA 2014 2.5 \n", - "3813 45809829 54850 831 HONDA 2018 1.5 \n", - "6041 45397141 9095 - FORD 2003 1.7 \n", - "\n", - " Mileage Cylinders Drive wheels Doors ... Fuel type_Hybrid \\\n", - "3438 160000 km 4.0 Rear 04-May ... False \n", - "3185 204579 km 4.0 4x4 04-May ... False \n", - "5529 0 km 6.0 Rear 04-May ... False \n", - "7891 244731 km 6.0 Front 04-May ... True \n", - "12167 103000 km 4.0 Front 04-May ... False \n", - "... ... ... ... ... ... ... \n", - "2750 361603 km 6.0 Front 04-May ... True \n", - "17390 220000 km 4.0 Rear 04-May ... False \n", - "5563 202355 km 4.0 Front 04-May ... False \n", - "3813 13048 km 4.0 Front 04-May ... False \n", - "6041 159000 km 4.0 Front 04-May ... False \n", - "\n", - " Fuel type_LPG Fuel type_Petrol Fuel type_Plug-in Hybrid \\\n", - "3438 False True False \n", - "3185 False True False \n", - "5529 False True False \n", - "7891 False False False \n", - "12167 False True False \n", - "... ... ... ... \n", - "2750 False False False \n", - "17390 False False False \n", - "5563 False True False \n", - "3813 False True False \n", - "6041 False False False \n", - "\n", - " Gear box type_Automatic Gear box type_Manual Gear box type_Tiptronic \\\n", - "3438 True False False \n", - "3185 True False False \n", - "5529 False False True \n", - "7891 True False False \n", - "12167 False False True \n", - "... ... ... ... \n", - "2750 True False False \n", - "17390 False True False \n", - "5563 True False False \n", - "3813 True False False \n", - "6041 False True False \n", - "\n", - " Gear box type_Variator Leather interior_No Leather interior_Yes \n", - "3438 False False True \n", - "3185 False False True \n", - "5529 False True False \n", - "7891 False False True \n", - "12167 False True False \n", - "... ... ... ... \n", - "2750 False False True \n", - "17390 False True False \n", - "5563 False False True \n", - "3813 False False True \n", - "6041 False True False \n", - "\n", - "[12311 rows x 1247 columns]\n" - ] - } - ], + "outputs": [], "source": [ "import pandas as pd\n", "\n", @@ -279,82 +206,9 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 16, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " ID Price Levy Manufacturer Prod. year Engine volume \\\n", - "736 45753963 27284 259 CHEVROLET 2014 1.4 \n", - "8674 45786053 10349 - MERCEDES-BENZ 1997 2.9 Turbo \n", - "5971 45757478 40769 - MERCEDES-BENZ 1996 1.8 \n", - "1957 45732345 38737 639 HYUNDAI 2014 2 \n", - "11075 45729790 42102 831 SSANGYONG 2017 1.6 \n", - "... ... ... ... ... ... ... \n", - "12026 45786994 12231 650 CHEVROLET 2016 1.4 Turbo \n", - "17893 45756187 15681 - FORD 2003 2.4 Turbo \n", - "5339 45769967 314 2410 MERCEDES-BENZ 2010 6.2 \n", - "11859 45801865 14069 687 HYUNDAI 2010 1.6 \n", - "9276 45803366 15681 891 HYUNDAI 2016 2 \n", - "\n", - " Mileage Cylinders Drive wheels Doors ... Fuel type_LPG \\\n", - "736 65000 km 4.0 Front 04-May ... False \n", - "8674 3333 km 6.0 Rear 02-Mar ... False \n", - "5971 212485 km 8.0 Rear 04-May ... False \n", - "1957 132756 km 4.0 Front 04-May ... False \n", - "11075 50750 km 4.0 Front 04-May ... False \n", - "... ... ... ... ... ... ... \n", - "12026 9000 km 4.0 Front 04-May ... False \n", - "17893 250000 km 4.0 Rear 04-May ... False \n", - "5339 274771 km 8.0 Rear 04-May ... False \n", - "11859 100403 km 4.0 Front 04-May ... False \n", - "9276 322292 km 4.0 Front 04-May ... True \n", - "\n", - " Fuel type_Petrol Fuel type_Plug-in Hybrid Gear box type_Automatic \\\n", - "736 False True True \n", - "8674 False False False \n", - "5971 True False False \n", - "1957 False False True \n", - "11075 True False True \n", - "... ... ... ... \n", - "12026 True False False \n", - "17893 False False False \n", - "5339 True False True \n", - "11859 True False True \n", - "9276 False False True \n", - "\n", - " Gear box type_Manual Gear box type_Tiptronic Gear box type_Variator \\\n", - "736 False False False \n", - "8674 True False False \n", - "5971 True False False \n", - "1957 False False False \n", - "11075 False False False \n", - "... ... ... ... \n", - "12026 False True False \n", - "17893 True False False \n", - "5339 False False False \n", - "11859 False False False \n", - "9276 False False False \n", - "\n", - " Leather interior_No Leather interior_Yes Year bin \n", - "736 True False 4 \n", - "8674 False True 3 \n", - "5971 True False 3 \n", - "1957 False True 4 \n", - "11075 False True 4 \n", - "... ... ... ... \n", - "12026 True False 4 \n", - "17893 True False 3 \n", - "5339 False True 4 \n", - "11859 False True 4 \n", - "9276 False True 4 \n", - "\n", - "[3848 rows x 658 columns]\n" - ] - } - ], + "outputs": [], "source": [ "# Пример дискретизации признака 'year'\n", "train_data_encoded['Year bin'] = pd.cut(train_data_encoded['Prod. year'], bins=5, labels=False)\n", @@ -372,82 +226,9 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 15, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " ID Price Levy Manufacturer Prod. year Engine volume \\\n", - "3438 45793776 13485 781 VOLKSWAGEN 2012 2.5 \n", - "3185 45760664 314 781 SUBARU 2012 2.5 \n", - "5529 45777845 5645 5908 BMW 1999 2.5 \n", - "7891 45651201 7997 1850 LEXUS 2008 3.5 \n", - "12167 45798755 15681 765 VOLKSWAGEN 2015 2 \n", - "... ... ... ... ... ... ... \n", - "2750 45656065 941 1055 LEXUS 2013 3.5 \n", - "17390 45785069 12000 - FORD 1998 2.5 \n", - "5563 45815001 941 777 TOYOTA 2014 2.5 \n", - "3813 45809829 54850 831 HONDA 2018 1.5 \n", - "6041 45397141 9095 - FORD 2003 1.7 \n", - "\n", - " Mileage Cylinders Drive wheels Doors ... Fuel type_Petrol \\\n", - "3438 160000 km 4.0 Rear 04-May ... True \n", - "3185 204579 km 4.0 4x4 04-May ... True \n", - "5529 0 km 6.0 Rear 04-May ... True \n", - "7891 244731 km 6.0 Front 04-May ... False \n", - "12167 103000 km 4.0 Front 04-May ... True \n", - "... ... ... ... ... ... ... \n", - "2750 361603 km 6.0 Front 04-May ... False \n", - "17390 220000 km 4.0 Rear 04-May ... False \n", - "5563 202355 km 4.0 Front 04-May ... True \n", - "3813 13048 km 4.0 Front 04-May ... True \n", - "6041 159000 km 4.0 Front 04-May ... False \n", - "\n", - " Fuel type_Plug-in Hybrid Gear box type_Automatic Gear box type_Manual \\\n", - "3438 False True False \n", - "3185 False True False \n", - "5529 False False False \n", - "7891 False True False \n", - "12167 False False False \n", - "... ... ... ... \n", - "2750 False True False \n", - "17390 False False True \n", - "5563 False True False \n", - "3813 False True False \n", - "6041 False False True \n", - "\n", - " Gear box type_Tiptronic Gear box type_Variator Leather interior_No \\\n", - "3438 False False False \n", - "3185 False False False \n", - "5529 True False True \n", - "7891 False False False \n", - "12167 True False True \n", - "... ... ... ... \n", - "2750 False False False \n", - "17390 False False True \n", - "5563 False False False \n", - "3813 False False False \n", - "6041 False False True \n", - "\n", - " Leather interior_Yes Year bin Age \n", - "3438 True 4 12 \n", - "3185 True 4 12 \n", - "5529 False 3 25 \n", - "7891 True 4 16 \n", - "12167 False 4 9 \n", - "... ... ... ... \n", - "2750 True 4 11 \n", - "17390 False 3 26 \n", - "5563 True 4 10 \n", - "3813 True 4 6 \n", - "6041 False 3 21 \n", - "\n", - "[12311 rows x 1249 columns]\n" - ] - } - ], + "outputs": [], "source": [ "# Пример синтеза признака \"возраст автомобиля\"\n", "train_data_encoded['Age'] = 2024 - train_data_encoded['Prod. year']\n", @@ -464,7 +245,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -488,23 +269,33 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 51, "metadata": {}, "outputs": [ { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'pkg_resources'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[25], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mft\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;66;03m# Определение сущностей\u001b[39;00m\n\u001b[0;32m 4\u001b[0m es \u001b[38;5;241m=\u001b[39m ft\u001b[38;5;241m.\u001b[39mEntitySet(\u001b[38;5;28mid\u001b[39m\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcar_data\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[1;32mc:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\__init__.py:4\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mversion\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m __version__\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mconfig_init\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m config\n\u001b[1;32m----> 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mapi\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;241m*\u001b[39m\n\u001b[0;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m primitives\n\u001b[0;32m 6\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msynthesis\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mapi\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;241m*\u001b[39m\n", - "File \u001b[1;32mc:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\entityset\\__init__.py:2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# flake8: noqa\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mapi\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;241m*\u001b[39m\n", - "File \u001b[1;32mc:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\entityset\\api.py:2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# flake8: noqa\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdeserialize\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m read_entityset\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m EntitySet\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mrelationship\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Relationship\n", - "File \u001b[1;32mc:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\entityset\\deserialize.py:8\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01minspect\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m getfullargspec\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpd\u001b[39;00m\n\u001b[1;32m----> 8\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mwoodwork\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mtype_sys\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mtype_system\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mww_type_system\u001b[39;00m\n\u001b[0;32m 9\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mwoodwork\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdeserialize\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m read_woodwork_table\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfeaturetools\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mentityset\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mrelationship\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Relationship\n", - "File \u001b[1;32mc:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\__init__.py:2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# flake8: noqa\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpkg_resources\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01msys\u001b[39;00m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mwarnings\u001b[39;00m\n", - "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'pkg_resources'" + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\entityset\\entityset.py:724: UserWarning: A Woodwork-initialized DataFrame was provided, so the following parameters were ignored: index\n", + " warnings.warn(\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\synthesis\\deep_feature_synthesis.py:169: UserWarning: Only one dataframe in entityset, changing max_depth to 1 since deeper features cannot be created\n", + " warnings.warn(\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " df = pd.concat([df, default_df], sort=True)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " df = pd.concat([df, default_df], sort=True)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n" ] } ], @@ -513,17 +304,220 @@ "\n", "# Определение сущностей\n", "es = ft.EntitySet(id='car_data')\n", - "es = es.entity_from_dataframe(entity_id='cars', dataframe=train_data_encoded, index='id')\n", + "es = es.add_dataframe(dataframe_name='cars', dataframe=train_data_encoded, index='id')\n", "\n", "# Определение связей между сущностями (если есть)\n", "# es = es.add_relationship(...)\n", "\n", "# Генерация признаков\n", - "feature_matrix, feature_defs = ft.dfs(entityset=es, target_entity='cars', max_depth=2)\n", + "feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name='cars', max_depth=2)\n", "\n", "# Преобразование признаков для контрольной и тестовой выборок\n", "val_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=val_data_encoded.index)\n", - "test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_data_encoded.index)" + "test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_data_encoded.index)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Оценка качества каждого набора признаков\n", + "Предсказательная способность\n", + "Метрики: RMSE, MAE, R²\n", + "\n", + "Методы: Обучение модели на обучающей выборке и оценка на контрольной и тестовой выборках.\n", + "\n", + "Скорость вычисления\n", + "Методы: Измерение времени выполнения генерации признаков и обучения модели.\n", + "\n", + "Надежность\n", + "Методы: Кросс-валидация, анализ чувствительности модели к изменениям в данных.\n", + "\n", + "Корреляция\n", + "Методы: Анализ корреляционной матрицы признаков, удаление мультиколлинеарных признаков.\n", + "\n", + "Цельность\n", + "Методы: Проверка логической связи между признаками и целевой переменной, интерпретация результатов модели." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\entityset\\entityset.py:724: UserWarning: A Woodwork-initialized DataFrame was provided, so the following parameters were ignored: index\n", + " warnings.warn(\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\synthesis\\deep_feature_synthesis.py:169: UserWarning: Only one dataframe in entityset, changing max_depth to 1 since deeper features cannot be created\n", + " warnings.warn(\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " df = pd.concat([df, default_df], sort=True)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " df = pd.concat([df, default_df], sort=True)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", + " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n" + ] + } + ], + "source": [ + "import featuretools as ft\n", + "\n", + "# Определение сущностей\n", + "es = ft.EntitySet(id='car_data')\n", + "es = es.add_dataframe(dataframe_name='cars', dataframe=train_data_encoded, index='id')\n", + "\n", + "# Генерация признаков\n", + "feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name='cars', max_depth=2)\n", + "\n", + "# Преобразование признаков для контрольной и тестовой выборок\n", + "val_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=val_data_encoded.index)\n", + "test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_data_encoded.index)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\sklearn\\metrics\\_regression.py:492: FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RMSE: 234661.34107821883\n", + "R²: 0.8029264507217629\n", + "MAE: 7964.677649030692\n", + "Cross-validated RMSE: 259310.71680259163\n", + "Train RMSE: 109324.02870848698\n", + "Train R²: 0.7887252013114727\n", + "Train MAE: 3471.173866063129\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Egor\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\sklearn\\metrics\\_regression.py:492: FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "image/png": "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ekm6cx7V/Pnzde7cOZ08edLcHhsbq969e+vMmTPKkiWLSpcurd9++83hOQAASO88PT21detWszSFhIRoypQpql+/vsXJACDzSvLiEN9++62aN28ub29vubu7KyoqSqNHj1afPn1SOmOycuYEMAAArLJt2zbVqVNHgwYNUs+ePTlfFwBSgDPdIMlnlI4aNUodO3ZUZGSkrl69qg8//FAjR4585LAAAGRm//zzjzp37nzXQkcVK1bUqVOn9O6771KaACANSPKMU9asWRUeHq5ChQpJunPYnI+Pj86cOaPAwMAUDZmcmHECAKQFCQkJmj17tgYOHKgrV66oTJky2r59u9zcnD79GADwkFJkxunmzZsOT+bh4SEvLy9FR0c/fFIAADKhLVu2qHLlyurcubOuXLkiSTp27Jj27dtncTIAwP049Wut2bNnK2vWrOb9+Ph4zZ8/X9mzZzfHUns5cgAA0ouLFy9qwIABmjt3rsN4q1atNGbMGC6vAQBpWJIP1cufP79sNtuDn8xm07Fjx5IlWErhUD0AQGqLj4/XzJkz9f777+vatWvmeKlSpTR9+nRVr17dunAAkIk50w2SPON04sSJR80FAECm1KVLF3366afmfT8/Pw0fPlxdunThnCYASCeSfI4TAAB4OGFhYXJxufNfbtu2bRUREaHu3btTmgAgHeEnNgAAySguLk5nzpxR/vz5zbHSpUtr/Pjxqly5sqpUqWJdOADAQ6M4AQCQTNauXauwsDAZhqHw8HB5eHiY23r27GldMADAI+NQPQAAHtHp06fVvHlzPfPMM9q/f78OHDigqVOnWh0LAJCMKE4AADyk2NhYjR49WkWLFtXXX39tjleqVEk1a9a0MBkAILkl6VC9qKioJD8hS3wDADKDX3/9Vd26dVNERIQ5lj17dn300Udq166duRgEACBjSFJxypYtW6LXcPpXQkLCIwUCACAtO336tHr06KGlS5eaYy4uLnr77bc1bNgwBQQEWJgOAJBSklSc1q5da/75xIkT6t+/v9q2bWuuDLR582Z99tlnGjVqVMqkBAAgjYiOjtby5cvN+1WrVtX06dMVGhpqXSgAQIqzGYZhOPOAOnXqqEOHDmrZsqXD+MKFCzVr1iz9/vvvyZkv2TlzdWAAAO6lX79++vzzzzVmzBi98cYbST4qAwCQtjjTDZwuTlmyZNHu3btV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169XYGBgSmVNFixHDiAzs9vtWrRokZo1ayZPT09zPCoqSlu2bFG9evUsTAcAQOpyphs4fahecHCwdu/ercWLF2v37t2Kjo5W+/bt9frrrzssFgEASFu2bdumrl27atu2bTp58qQGDBhgbvPz86M0AQDwAE7NOMXFxalo0aJasWKFihUrlpK5UgwzTgAym8uXL2vgwIGaPXu2/v2RnyVLFp08eVKPP/64xekAALBOil0A193dXbdv336kcACA1JGQkKAZM2YoJCREn376qVmaihcvrhUrVlCaAABwgtOLQ3Tt2lWjR4/mQogAkIZt3rxZlSpVUpcuXXT16lVJkq+vryZMmKDw8HDVrl3b4oQAAKQvTp/jtG3bNq1evVq//vqrSpUqJR8fH4ftS5cuTbZwAADndenSRTNmzHAYe+ONNzR69Gjlzp3bolQAAKRvThenbNmy6eWXX06JLACAZBAQEGD+uXTp0po+fbqefvppCxMBAJD+Ob0ceXrH4hAAMhrDMGSz2cz7N2/eVJUqVdSxY0d17txZbm5O/44MAIBMIUWWI7fb7Ro7dqyWL1+u2NhY1alTR4MHD2YJcgCwyLlz59S3b18VLFhQQ4cONcezZMmiXbt2ycXF6dNYAQDAfST5f9URI0Zo4MCBypo1q/LkyaPJkyera9euj/TF169fr8aNGysoKEg2m03fffddoo/5/fffVa5cOXl6eqpQoUKaP3/+I2UAgPQmLi5OEyZMUJEiRbRgwQKNHj1aR48eddiH0gQAQPJK8v+sn3/+uT7++GP98ssv+u677/TDDz9owYIFstvtD/3Fb9y4oTJlymj69OlJ2v/48eNq1KiRateurfDwcPXs2VMdOnTQL7/88tAZACA9Wbt2rUJDQ9W7d29dv35d0p0ZpoiICIuTAQCQsSX5HCdPT08dOXJEwcHB5piXl5eOHDmivHnzPnoQm03Lli1TkyZN7rvPu+++qx9//FH79u0zx1q0aKFr165p5cqVSfo6nOMEID06ffq0evfura+//tocs9ls6tixo0aMGKHs2bNbmA4AgPQpRS6AGx8fLy8vL4cxd3d3xcXFPVzKh7B582bVrVvXYax+/fravHnzfR8TExOjqKgohxsApBexsbEaPXq0ihYt6lCaKlWqpK1bt+qTTz6hNAEAkAqSvDiEYRhq27atPD09zbHbt2+rc+fODtdySsnrOJ0/f145c+Z0GMuZM6eioqJ069atey5UMWrUKIeTpgEgPfnkk0/Uv39/83727Nn10UcfqV27dpzHBABAKkry/7pt2rRRYGCg/P39zVurVq0UFBTkMJbWDBgwQJGRkebt1KlTVkcCgCTr2LGjChYsKBcXF3Xt2lURERFq3749pQkAgFSW5BmnefPmpWSOJMmVK5cuXLjgMHbhwgX5+fndd1l0T09Ph1kyAEirbt++rY0bN6pOnTrmmJeXlz777DP5+PgoNDTUunAAAGRy6epXllWqVNHq1asdxlatWqUqVapYlAgAksePP/6okiVLqkGDBjp48KDDtmrVqlGaAACwmKXFKTo6WuHh4QoPD5d0Z7nx8PBwnTx5UtKdw+xat25t7t+5c2cdO3ZM/fr108GDB/Xxxx/r66+/1jvvvGNFfAB4ZEePHlXjxo31/PPP6+jRo4qPj+dnGgAAaZClxWn79u0qW7asypYtK0nq1auXypYtqw8++ECSdO7cObNESVKBAgX0448/atWqVSpTpozGjx+v2bNnq379+pbkB4CHdfPmTX3wwQcqUaKEVqxYYY7XqFFDY8aMsTAZAAC4lyRfxymj4DpOAKxkGIa+//579ezZU3///bc5HhQUpHHjxqlFixay2WwWJgQAIPNwphskeXEIAMCjuXTpkt544w398ssv5pibm5veeecdvf/++/L19bUwHQAAeBCKEwCkkmzZsjkcflynTh1NnTpVxYoVszAVAABIinS1qh4ApGfu7u6aNm2agoOD9c0332jVqlWUJgAA0gmKEwCkgAMHDqh+/fravXu3w/gzzzyjw4cPq1mzZpzLBABAOsKhegCQjK5fv65hw4Zp0qRJio+P182bN7V+/XqHksRFuQEASH+YcQKAZGAYhhYuXKgiRYpo3Lhxio+PlySdPn1aZ86csTgdAAB4VBQnAHhEe/fuVa1atfT666/r3Llzku7MKg0ePFj79+9X3rx5LU4IAAAeFYfqAcBDunbtmoYMGaJp06YpISHBHH/hhRc0ceJEPfnkkxamAwAAyYniBAAPqUWLFg7XZCpYsKCmTJmihg0bWpgKAACkBA7VA4CH9P7770uSvL299eGHH2rfvn2UJgAAMihmnAAgCa5evap//vlHhQoVMseqVaum6dOnq1GjRsqXL5+F6QAAQEpjxgkAHsBut2v2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1K1bN61fv15nz561Oo5TGjRooHPnzunw4cPq3bu3hgwZorFjx95z39jYWElSjhw5lCVLltSMCQCZVlhYmDZv3qyvvvpKe/bs0SuvvKIGDRro8OHD99x/9uzZCgkJUfXq1Z36OhQnAECKio6O1uLFi/X222+rUaNGmj9//l37/PDDD6pYsaK8vLyUPXt287eKtWrV0t9//6133nnHnPmR7hyvHhoa6vAckyZNUv78+c3727Zt07PPPqvs2bPL399fNWvW1M6dO53O7+npqVy5cilfvnx6++23VbduXS1fvlzSnRmpJk2aaMSIEQoKClKRIkUk3T1Ldu3aNXXq1Ek5c+aUl5eXSpYsqRUrVpjbN2zYoOrVq8vb21vBwcHq3r27bty44XRWAMhsTp48qXnz5umbb75R9erVVbBgQfXp00dPP/205s2bd9f+t2/f1oIFC5yebZIoTgCAFPb111+raNGiKlKkiFq1aqW5c+fKMAxz+48//qimTZuqYcOG2rVrl1avXq1KlSpJkpYuXaq8efNq2LBh5nHpSXX9+nW1adNGGzZs0JYtW1S4cGE1bNhQ169ff6TX4+3tbc4sSdLq1at16NAhrVq1yqEM/ctut+u5557Txo0b9eWXX2r//v366KOP5OrqKkk6evSoGjRooJdffll79uzR4sWLtWHDBoWFhT1STgDIDPbu3auEhASFhIQoa9as5m3dunU6evToXfsvW7bM/P/BWW7JERgAgPuZM2eOWrVqJenOYW+RkZFat26datWqJUkaMWKEWrRooaFDh5qPKVOmjCQpICBArq6u8vX1Va5cuZz6us8884zD/VmzZilbtmxat26dnn/+eadfh2EYWr16tX755Rd169bNHPfx8dHs2bPl4eFxz8f99ttv2rp1qw4cOKCQkBBJ0pNPPmluHzVqlF5//XX17NlTklS4cGFNmTJFNWvW1IwZM+Tl5eV0VgDILKKjo+Xq6qodO3aYv5D6V9asWe/af/bs2Xr++eeVM2dOp78WxQkAkGIOHTqkrVu3atmyZZIkNzc3NW/eXHPmzDGLU3h4uDp27JjsX/vChQt677339Pvvv+vixYtKSEjQzZs3dfLkSaeeZ8WKFcqaNavi4uJkt9v12muvaciQIeb2UqVK3bc0SXdeX968ec3S9F+7d+/Wnj17tGDBAnPMMAzZ7XYdP35cxYoVcyovAGQmZcuWVUJCgi5evJjoOUvHjx/X2rVrzcOtnUVxAgCkmDlz5ig+Pl5BQUHmmGEY8vT01LRp0+Tv7y9vb2+nn9fFxcXhcD9JiouLc7jfpk0b/fPPP5o8ebLy5csnT09PValSxeEwu6SoXbu2ZsyYIQ8PDwUFBcnNzfG/zsSuA5LY64uOjlanTp3UvXv3u7Y98cQTTmUFgIwoOjpaR44cMe8fP35c4eHhCggIUEhIiF5//XW1bt1a48ePV9myZXXp0iWtXr1apUuXdljNde7cucqdO7eee+65h8pBcQIApIj4+Hh9/vnnGj9+vOrVq+ewrUmTJlq0aJE6d+6s0qVLa/Xq1WrXrt09n8fDw0MJCQkOYzly5ND58+dlGIa5YER4eLjDPhs3btTHH3+shg0bSpJOnTqly5cvO/06fHx8VKhQIacf96/SpUvr9OnTioiIuOesU7ly5bR///5H+hoAkJFt375dtWvXNu/36tVL0p1fkM2fP1/z5s3Thx9+qN69e+vMmTPKnj27nnrqKYfDsu12u+bPn6+2bdvedUhfUlGcAAApYsWKFbp69arat28vf39/h20vv/yy5syZo86dO2vw4MGqU6eOChYsqBYtWig+Pl4//fST3n33XUl3Vqhbv369WrRoIU9PT2XPnl21atXSpUuXNGbMGDVr1kwrV67Uzz//LD8/P/NrFC5cWF988YUqVKigqKgo9e3b96Fmtx5VzZo1VaNGDb388suaMGGCChUqpIMHD8pms6lBgwZ699139dRTTyksLEwdOnSQj4+P9u/fr1WrVmnatGmpnhcA0ppatWrddZTB/3J3d9fQoUMdzpX9LxcXF506deqRcrCqHgAgRcyZM0d169a9qzRJd4rT9u3btWfPHtWqVUvffPONli9frtDQUD3zzDPaunWrue+wYcN04sQJFSxYUDly5JAkFStWTB9//LGmT5+uMmXKaOvWrerTp89dX//q1asqV66c3njjDXXv3l2BgYEp+6LvY8mSJapYsaJatmyp4sWLq1+/fuYsWunSpbVu3TpFRESoevXqKlu2rD744AOHwxsBANazGQ+qbwAAAAAAZpwAAAAAIDEUJwAAAABIBMUJAAAAABJBcQIAAACARFCcAAAAACARFCcAAAAASATFCQAAAAASQXECAAAAgERQnAAAAAAgERQnAAAAAEgExQkAAAAAEvH/ADkyCDY9Et2KAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.ensemble import RandomForestRegressor\n", + "from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error\n", + "from sklearn.model_selection import cross_val_score\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "# Удаление строк с NaN\n", + "feature_matrix = feature_matrix.dropna()\n", + "val_feature_matrix = val_feature_matrix.dropna()\n", + "test_feature_matrix = test_feature_matrix.dropna()\n", + "\n", + "# Разделение данных на обучающую и тестовую выборки\n", + "X_train = feature_matrix.drop('Price', axis=1)\n", + "y_train = feature_matrix['Price']\n", + "X_val = val_feature_matrix.drop('Price', axis=1)\n", + "y_val = val_feature_matrix['Price']\n", + "X_test = test_feature_matrix.drop('Price', axis=1)\n", + "y_test = test_feature_matrix['Price']\n", + "\n", + "# Выбор модели\n", + "model = RandomForestRegressor(random_state=42)\n", + "\n", + "# Обучение модели\n", + "model.fit(X_train, y_train)\n", + "\n", + "# Предсказание и оценка\n", + "y_pred = model.predict(X_test)\n", + "\n", + "rmse = mean_squared_error(y_test, y_pred, squared=False)\n", + "r2 = r2_score(y_test, y_pred)\n", + "mae = mean_absolute_error(y_test, y_pred)\n", + "\n", + "print(f\"RMSE: {rmse}\")\n", + "print(f\"R²: {r2}\")\n", + "print(f\"MAE: {mae}\")\n", + "\n", + "# Кросс-валидация\n", + "scores = cross_val_score(model, X_train, y_train, cv=5, scoring='neg_mean_squared_error')\n", + "rmse_cv = (-scores.mean())**0.5\n", + "print(f\"Cross-validated RMSE: {rmse_cv}\")\n", + "\n", + "# Анализ важности признаков\n", + "feature_importances = model.feature_importances_\n", + "feature_names = X_train.columns\n", + "\n", + "# importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': feature_importances})\n", + "# importance_df = importance_df.sort_values(by='Importance', ascending=False)\n", + "\n", + "# plt.figure(figsize=(10, 6))\n", + "# sns.barplot(x='Importance', y='Feature', data=importance_df)\n", + "# plt.title('Feature Importance')\n", + "# plt.show()\n", + "\n", + "# Проверка на переобучение\n", + "y_train_pred = model.predict(X_train)\n", + "\n", + "rmse_train = mean_squared_error(y_train, y_train_pred, squared=False)\n", + "r2_train = r2_score(y_train, y_train_pred)\n", + "mae_train = mean_absolute_error(y_train, y_train_pred)\n", + "\n", + "print(f\"Train RMSE: {rmse_train}\")\n", + "print(f\"Train R²: {r2_train}\")\n", + "print(f\"Train MAE: {mae_train}\")\n", + "\n", + "# Визуализация результатов\n", + "plt.figure(figsize=(10, 6))\n", + "plt.scatter(y_test, y_pred, alpha=0.5)\n", + "plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)\n", + "plt.xlabel('Actual Price')\n", + "plt.ylabel('Predicted Price')\n", + "plt.title('Actual vs Predicted Price')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Точность предсказаний: Модель показывает довольно высокий R² (0.8029), что указывает на хорошее объяснение вариации цен. Однако, значения RMSE и MAE довольно высоки, что говорит о том, что модель не очень точно предсказывает цены, особенно для высоких значений.\n", + "\n", + "Переобучение: Разница между RMSE на обучающей и тестовой выборках не очень большая, что указывает на то, что переобучение не является критическим. Однако, стоит быть осторожным и продолжать мониторинг этого показателя.\n", + "\n", + "Кросс-валидация: Значение RMSE после кросс-валидации немного выше, чем на тестовой выборке, что может указывать на некоторую нестабильность модели." ] } ],