diff --git a/30_Deployment/30.6 Practic work/pipeline_learning.ipynb b/30_Deployment/30.6 Practic work/pipeline_learning.ipynb
new file mode 100644
index 0000000..d5dad8f
--- /dev/null
+++ b/30_Deployment/30.6 Practic work/pipeline_learning.ipynb
@@ -0,0 +1,1061 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "45219139-b9ef-42ed-a2d6-54da92eeb1b5",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "## Пошаговое руководство по созданию простейшего pipeline из Sci-kit Learn"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7219263d-0d78-41db-a3fd-1b656e2f20c0",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "#### Большинство проектов по науке о данных требуют определенного уровня очистки и предварительной обработки данных, чтобы максимально использовать модели машинного обучения. Вот некоторые распространенные предварительные обработки или преобразования:\n",
+ "\n",
+ "а. Заполнение пропущенных значений\n",
+ "\n",
+ "б. Удаление выбросов\n",
+ "\n",
+ "в. Нормализация или стандартизация числовых признаков\n",
+ "\n",
+ "д. Кодирование категориальных признаков\n",
+ "\n",
+ "В научном наборе есть набор функций, поддерживающих такого рода преобразование, таких как StandardScaler, SimpleImputer и т. д., в пакете предварительной обработки.\n",
+ "\n",
+ "Типичный и упрощенный рабочий процесс науки о данных примерно выглядит так:\n",
+ "\n",
+ "-Получить данные для тренировки\n",
+ "\n",
+ "-Очистить/предварительно обработать/преобразовать данные\n",
+ "\n",
+ "-Обучить модель машинного обучения\n",
+ "\n",
+ "-Оценить и оптимизировать модель\n",
+ "\n",
+ "-Очистить/предварительно обработать/преобразовать новые данные\n",
+ "\n",
+ "-Дать модели новые данным, чтобы делать прогнозы.\n",
+ "\n",
+ "Вы можете заметить, что предварительная обработка данных должна выполняться как минимум дважды в рабочем процессе. Каким бы утомительным и трудоемким ни был этот шаг, было бы здорово, если бы мы могли автоматизировать этот процесс и применить его ко всем будущим новым наборам данных.\n",
+ "\n",
+ "С конвейером обучения scikit мы можем легко систематизировать процесс и, следовательно, сделать его максимально воспроизводимым. Далее я проведу вас через процесс использования конвейера обучения scikit, чтобы облегчить вашу жизнь."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "446d1565-8b4f-4955-a9b5-3158094dc018",
+ "metadata": {},
+ "source": [
+ "#### Чтение данных\n",
+ "Мы будем использовать данные «ежедневного проката велосипедов» из фантастического учебного материала Microsoft по машинному обучению ."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "a700bcb1-7c92-4157-be8f-8fe50311aa6d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "instant int64\n",
+ "dteday object\n",
+ "season int64\n",
+ "yr int64\n",
+ "mnth int64\n",
+ "holiday int64\n",
+ "weekday int64\n",
+ "workingday int64\n",
+ "weathersit int64\n",
+ "temp float64\n",
+ "atemp float64\n",
+ "hum float64\n",
+ "windspeed float64\n",
+ "rentals int64\n",
+ "dtype: object"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "data = pd.read_csv('https://raw.githubusercontent.com/MicrosoftDocs/ml-basics/master/data/daily-bike-share.csv')\n",
+ "data.dtypes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "fd52b4e1-9d03-416d-989a-ee6a978c04c6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "instant 0\n",
+ "dteday 0\n",
+ "season 0\n",
+ "yr 0\n",
+ "mnth 0\n",
+ "holiday 0\n",
+ "weekday 0\n",
+ "workingday 0\n",
+ "weathersit 0\n",
+ "temp 0\n",
+ "atemp 0\n",
+ "hum 0\n",
+ "windspeed 0\n",
+ "rentals 0\n",
+ "dtype: int64"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data.isnull().sum()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ba5c3bef-ae5a-4e40-b67b-e24bd2ae06f4",
+ "metadata": {},
+ "source": [
+ " К счастью, в этом наборе данных нет пропущенных значений. Хотя кажется, что все функции являются числовыми, на самом деле есть некоторые категориальные функции, которые нам необходимо идентифицировать."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "a8492763-ac30-4426-b10c-ec6e644f1b0b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " instant | \n",
+ " dteday | \n",
+ " season | \n",
+ " yr | \n",
+ " mnth | \n",
+ " holiday | \n",
+ " weekday | \n",
+ " workingday | \n",
+ " weathersit | \n",
+ " temp | \n",
+ " atemp | \n",
+ " hum | \n",
+ " windspeed | \n",
+ " rentals | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 1/1/2011 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 6 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 0.344167 | \n",
+ " 0.363625 | \n",
+ " 0.805833 | \n",
+ " 0.160446 | \n",
+ " 331 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 1/2/2011 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 0.363478 | \n",
+ " 0.353739 | \n",
+ " 0.696087 | \n",
+ " 0.248539 | \n",
+ " 131 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 1/3/2011 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0.196364 | \n",
+ " 0.189405 | \n",
+ " 0.437273 | \n",
+ " 0.248309 | \n",
+ " 120 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 1/4/2011 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0.200000 | \n",
+ " 0.212122 | \n",
+ " 0.590435 | \n",
+ " 0.160296 | \n",
+ " 108 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 1/5/2011 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0.226957 | \n",
+ " 0.229270 | \n",
+ " 0.436957 | \n",
+ " 0.186900 | \n",
+ " 82 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 726 | \n",
+ " 727 | \n",
+ " 12/27/2012 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 0.254167 | \n",
+ " 0.226642 | \n",
+ " 0.652917 | \n",
+ " 0.350133 | \n",
+ " 247 | \n",
+ "
\n",
+ " \n",
+ " 727 | \n",
+ " 728 | \n",
+ " 12/28/2012 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 5 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 0.253333 | \n",
+ " 0.255046 | \n",
+ " 0.590000 | \n",
+ " 0.155471 | \n",
+ " 644 | \n",
+ "
\n",
+ " \n",
+ " 728 | \n",
+ " 729 | \n",
+ " 12/29/2012 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 6 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 0.253333 | \n",
+ " 0.242400 | \n",
+ " 0.752917 | \n",
+ " 0.124383 | \n",
+ " 159 | \n",
+ "
\n",
+ " \n",
+ " 729 | \n",
+ " 730 | \n",
+ " 12/30/2012 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0.255833 | \n",
+ " 0.231700 | \n",
+ " 0.483333 | \n",
+ " 0.350754 | \n",
+ " 364 | \n",
+ "
\n",
+ " \n",
+ " 730 | \n",
+ " 731 | \n",
+ " 12/31/2012 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 0.215833 | \n",
+ " 0.223487 | \n",
+ " 0.577500 | \n",
+ " 0.154846 | \n",
+ " 439 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
731 rows × 14 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " instant dteday season yr mnth holiday weekday workingday \\\n",
+ "0 1 1/1/2011 1 0 1 0 6 0 \n",
+ "1 2 1/2/2011 1 0 1 0 0 0 \n",
+ "2 3 1/3/2011 1 0 1 0 1 1 \n",
+ "3 4 1/4/2011 1 0 1 0 2 1 \n",
+ "4 5 1/5/2011 1 0 1 0 3 1 \n",
+ ".. ... ... ... .. ... ... ... ... \n",
+ "726 727 12/27/2012 1 1 12 0 4 1 \n",
+ "727 728 12/28/2012 1 1 12 0 5 1 \n",
+ "728 729 12/29/2012 1 1 12 0 6 0 \n",
+ "729 730 12/30/2012 1 1 12 0 0 0 \n",
+ "730 731 12/31/2012 1 1 12 0 1 1 \n",
+ "\n",
+ " weathersit temp atemp hum windspeed rentals \n",
+ "0 2 0.344167 0.363625 0.805833 0.160446 331 \n",
+ "1 2 0.363478 0.353739 0.696087 0.248539 131 \n",
+ "2 1 0.196364 0.189405 0.437273 0.248309 120 \n",
+ "3 1 0.200000 0.212122 0.590435 0.160296 108 \n",
+ "4 1 0.226957 0.229270 0.436957 0.186900 82 \n",
+ ".. ... ... ... ... ... ... \n",
+ "726 2 0.254167 0.226642 0.652917 0.350133 247 \n",
+ "727 2 0.253333 0.255046 0.590000 0.155471 644 \n",
+ "728 2 0.253333 0.242400 0.752917 0.124383 159 \n",
+ "729 1 0.255833 0.231700 0.483333 0.350754 364 \n",
+ "730 2 0.215833 0.223487 0.577500 0.154846 439 \n",
+ "\n",
+ "[731 rows x 14 columns]"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "610e2d94-6882-43a0-9739-841b5258591a",
+ "metadata": {},
+ "source": [
+ "Давайте сначала отфильтруем некоторые явно бесполезные функции."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "96c106b3-cbca-4c33-97e7-96190889fa09",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data = data[['season'\n",
+ " , 'mnth'\n",
+ " , 'holiday'\n",
+ " , 'weekday'\n",
+ " , 'workingday'\n",
+ " , 'weathersit'\n",
+ " , 'temp'\n",
+ " , 'atemp'\n",
+ " , 'hum'\n",
+ " , 'windspeed'\n",
+ " , 'rentals']]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "137f5661-b2f3-4c07-9f34-ad9709c1fbf0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " season | \n",
+ " mnth | \n",
+ " holiday | \n",
+ " weekday | \n",
+ " workingday | \n",
+ " weathersit | \n",
+ " temp | \n",
+ " atemp | \n",
+ " hum | \n",
+ " windspeed | \n",
+ " rentals | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 6 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 0.344167 | \n",
+ " 0.363625 | \n",
+ " 0.805833 | \n",
+ " 0.160446 | \n",
+ " 331 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 0.363478 | \n",
+ " 0.353739 | \n",
+ " 0.696087 | \n",
+ " 0.248539 | \n",
+ " 131 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0.196364 | \n",
+ " 0.189405 | \n",
+ " 0.437273 | \n",
+ " 0.248309 | \n",
+ " 120 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0.200000 | \n",
+ " 0.212122 | \n",
+ " 0.590435 | \n",
+ " 0.160296 | \n",
+ " 108 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0.226957 | \n",
+ " 0.229270 | \n",
+ " 0.436957 | \n",
+ " 0.186900 | \n",
+ " 82 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 726 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 0.254167 | \n",
+ " 0.226642 | \n",
+ " 0.652917 | \n",
+ " 0.350133 | \n",
+ " 247 | \n",
+ "
\n",
+ " \n",
+ " 727 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 5 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 0.253333 | \n",
+ " 0.255046 | \n",
+ " 0.590000 | \n",
+ " 0.155471 | \n",
+ " 644 | \n",
+ "
\n",
+ " \n",
+ " 728 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 6 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 0.253333 | \n",
+ " 0.242400 | \n",
+ " 0.752917 | \n",
+ " 0.124383 | \n",
+ " 159 | \n",
+ "
\n",
+ " \n",
+ " 729 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 0.255833 | \n",
+ " 0.231700 | \n",
+ " 0.483333 | \n",
+ " 0.350754 | \n",
+ " 364 | \n",
+ "
\n",
+ " \n",
+ " 730 | \n",
+ " 1 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 0.215833 | \n",
+ " 0.223487 | \n",
+ " 0.577500 | \n",
+ " 0.154846 | \n",
+ " 439 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
731 rows × 11 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " season mnth holiday weekday workingday weathersit temp \\\n",
+ "0 1 1 0 6 0 2 0.344167 \n",
+ "1 1 1 0 0 0 2 0.363478 \n",
+ "2 1 1 0 1 1 1 0.196364 \n",
+ "3 1 1 0 2 1 1 0.200000 \n",
+ "4 1 1 0 3 1 1 0.226957 \n",
+ ".. ... ... ... ... ... ... ... \n",
+ "726 1 12 0 4 1 2 0.254167 \n",
+ "727 1 12 0 5 1 2 0.253333 \n",
+ "728 1 12 0 6 0 2 0.253333 \n",
+ "729 1 12 0 0 0 1 0.255833 \n",
+ "730 1 12 0 1 1 2 0.215833 \n",
+ "\n",
+ " atemp hum windspeed rentals \n",
+ "0 0.363625 0.805833 0.160446 331 \n",
+ "1 0.353739 0.696087 0.248539 131 \n",
+ "2 0.189405 0.437273 0.248309 120 \n",
+ "3 0.212122 0.590435 0.160296 108 \n",
+ "4 0.229270 0.436957 0.186900 82 \n",
+ ".. ... ... ... ... \n",
+ "726 0.226642 0.652917 0.350133 247 \n",
+ "727 0.255046 0.590000 0.155471 644 \n",
+ "728 0.242400 0.752917 0.124383 159 \n",
+ "729 0.231700 0.483333 0.350754 364 \n",
+ "730 0.223487 0.577500 0.154846 439 \n",
+ "\n",
+ "[731 rows x 11 columns]"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "28c56084-4cae-49ec-a410-627b3917fb8d",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "#### Разделим данные\n",
+ "Перед созданием конвейера нам нужно сначала разделить данные на обучающий набор и тестовый набор."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "912fe504-9905-4a2d-a248-60ba6dbb09c9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sklearn.model_selection import train_test_split\n",
+ "X = data.drop('rentals',axis=1)\n",
+ "y = data['rentals']\n",
+ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bb532c1d-a1a2-417e-b4b1-7f6de586ec36",
+ "metadata": {},
+ "source": [
+ "#### Создадим конвейер (pipeline)\n",
+ "Основным параметром пайплайна, над которым мы будем работать, являются « шаги ». Легче просто взглянуть на то, как должен выглядеть конвейер:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c5199aec-a6f8-40b5-ad14-39e19b619c3d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Pipeline(steps=[('name_of_preprocessor', препроцессор), \n",
+ " #('name_of_ml_model', ml_model())])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "df6d7c3c-4594-4b16-a9ee-397d03b7a672",
+ "metadata": {},
+ "source": [
+ "Импортируем нужные библиотеки"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "89df662a-51a2-4747-8936-32636adb475b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sklearn.preprocessing import StandardScaler, OrdinalEncoder\n",
+ "from sklearn.impute import SimpleImputer\n",
+ "from sklearn.compose import ColumnTransformer\n",
+ "from sklearn.pipeline import Pipeline"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c41046dd-77cc-460c-a355-fdd7a2428a17",
+ "metadata": {},
+ "source": [
+ "Во-первых, нам нужно определить преобразователи как для числовых, так и для категориальных признаков. Шаг преобразования представлен кортежем. В этом кортеже вы сначала определяете имя преобразователя, а затем функцию, которую хотите применить. Порядок кортежа будет порядком, в котором конвейер применяет преобразования. Здесь мы сначала имеем дело с пропущенными значениями, затем стандартизируем числовые признаки и кодируем категориальные признаки."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "d10e4cae-c3f8-4a87-8e54-8fcb9b11c3b4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "numeric_transformer = Pipeline(steps=[\n",
+ " ('imputer', SimpleImputer(strategy='mean'))\n",
+ " ,('scaler', StandardScaler())\n",
+ "])\n",
+ "categorical_transformer = Pipeline(steps=[\n",
+ " ('imputer', SimpleImputer(strategy='constant'))\n",
+ " ,('encoder', OrdinalEncoder())\n",
+ "])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a399dbf7-a2a9-4516-b0e8-6d282b57cda2",
+ "metadata": {},
+ "source": [
+ "#### Preprocessor\n",
+ "Следующее, что нам нужно сделать, это указать, какие столбцы являются числовыми, а какие категориальными, чтобы мы могли соответствующим образом применить преобразователи. Мы применяем преобразователи к функциям с помощью ColumnTransformer. Применение преобразователей к функциям — это наш препроцессор. Подобно конвейеру, мы передаем список кортежей, который состоит из («имя», «трансформер», «функции») , параметру « трансформеры »."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "ad374c35-cd2c-42dd-b23d-2996568d86d6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "numeric_features = ['temp', 'atemp', 'hum', 'windspeed']\n",
+ "categorical_features = ['season', 'mnth', 'holiday', 'weekday', 'workingday', 'weathersit']\n",
+ "preprocessor = ColumnTransformer(\n",
+ " transformers=[\n",
+ " ('numeric', numeric_transformer, numeric_features)\n",
+ " ,('categorical', categorical_transformer, categorical_features)\n",
+ "])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2fed8f72-7bb2-468b-847f-aabbede77a8a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "Можно создать список числовых/категориальных функций на основе типа данных, например:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "9d067d0e-628b-4242-a63e-a2b415bb9093",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "numeric_features = data.select_dtypes(include=['int64', 'float64']).columns\n",
+ "categorical_features = data.select_dtypes(include=['object']).columns"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f7ad295d-d484-4e85-b0dd-cb6cf0e1ce2c",
+ "metadata": {},
+ "source": [
+ "Я лично не рекомендую это, потому что если у вас есть категориальные признаки, замаскированные под числовой тип данных, например, этот набор данных, вы не сможете их идентифицировать. Используйте этот метод только в том случае, если вы на 100 % уверены, что только числовые признаки являются числовыми типами данных."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "d7f830a3-fbf1-4994-83a8-ca361ad51537",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Index([], dtype='object')"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "categorical_features"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "df9c6ba4-4650-43ae-82d9-450b3a03ca69",
+ "metadata": {},
+ "source": [
+ "#### Оценщик Estimator\n",
+ "\n",
+ "После сборки нашего препроцессора мы можем добавить оценщик, который представляет собой алгоритм машинного обучения, который вы хотели бы применить, чтобы завершить наш конвейер предварительной обработки и обучения. Поскольку в этом случае целевая переменная непрерывна, я применю здесь модель случайной лесной регрессии."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "49546964-931c-40df-983c-17c7b8e92a83",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sklearn.ensemble import RandomForestRegressor\n",
+ "pipeline = Pipeline(steps = [\n",
+ " ('preprocessor', preprocessor)\n",
+ " ,('regressor',RandomForestRegressor())\n",
+ " ])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bd418898-b174-4dbc-8177-519823364401",
+ "metadata": {},
+ "source": [
+ "Чтобы создать модель, аналогичную тому, что мы делали с алгоритмом машинного обучения, мы используем функцию конвейера fit"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "01653c3e-5a46-48a2-8fc8-6c1a728f3b15",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Pipeline(steps=[('preprocessor',\n",
+ " ColumnTransformer(transformers=[('numeric',\n",
+ " Pipeline(steps=[('imputer',\n",
+ " SimpleImputer()),\n",
+ " ('scaler',\n",
+ " StandardScaler())]),\n",
+ " ['temp', 'atemp', 'hum',\n",
+ " 'windspeed']),\n",
+ " ('categorical',\n",
+ " Pipeline(steps=[('imputer',\n",
+ " SimpleImputer(strategy='constant')),\n",
+ " ('encoder',\n",
+ " OrdinalEncoder())]),\n",
+ " ['season', 'mnth', 'holiday',\n",
+ " 'weekday', 'workingday',\n",
+ " 'weathersit'])])),\n",
+ " ('regressor', RandomForestRegressor())])\n"
+ ]
+ }
+ ],
+ "source": [
+ "rf_model = pipeline.fit(X_train, y_train)\n",
+ "print (rf_model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "90e3276a-4739-4253-8f72-ec23fb66fb6e",
+ "metadata": {},
+ "source": [
+ "Используем обычные методы для оценки модели."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "7355feec-d7c5-4b7b-b312-c5344f26ca3a",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0.7683677302805014\n"
+ ]
+ }
+ ],
+ "source": [
+ "from sklearn.metrics import r2_score\n",
+ "predictions = rf_model.predict(X_test)\n",
+ "print (r2_score(y_test, predictions))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "48ab9d67-ecc4-47e5-bdf4-52a96aad3499",
+ "metadata": {},
+ "source": [
+ "#### Использование модели\n",
+ "Чтобы максимизировать воспроизводимость, мы хотели бы неоднократно использовать эту модель для наших новых входящих данных. Давайте сохраним модель, используя пакет joblib, чтобы сохранить ее"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "9b89c017-2a90-46e2-a6aa-bbf1f1daab9c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['./rf_model.pkl']"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import joblib\n",
+ "joblib.dump(rf_model, './rf_model.pkl')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "957229e8-bb57-454d-8313-e0715bd6a5dc",
+ "metadata": {},
+ "source": [
+ "Теперь мы можем вызвать этот конвейер, который включает в себя все виды предварительной обработки данных, которые нам нужны, и модель обучения, когда нам это нужно."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "50b8cfb4-07f6-484f-a71b-855aecabf04e",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'new_data' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32mC:\\Users\\HPZ2~1\\AppData\\Local\\Temp/ipykernel_12436/1643577056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mrf_model\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mjoblib\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mload\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'./rf_model.pkl'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mnew_prediction\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrf_model\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnew_data\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[1;31mNameError\u001b[0m: name 'new_data' is not defined"
+ ]
+ }
+ ],
+ "source": [
+ "rf_model = joblib.load('PATH/TO/rf_model.pkl')\n",
+ "new_prediction = rf_model.predict(new_data)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "08a09549-7ff9-4109-af85-cc7e4a93c723",
+ "metadata": {},
+ "source": [
+ "#### Заключение\n",
+ "До знакомства с конвейером обучения scikit мне всегда приходилось переделывать всю предварительную обработку и преобразование данных всякий раз, когда я хотел применить одну и ту же модель к разным наборам данных. Это был действительно утомительный процесс. Я попытался написать функцию, выполняющую их все, но результат меня не очень удовлетворил и не избавил меня от большого количества работы.\n",
+ "\n",
+ "Конвейер обучения Scikit действительно делает мои рабочие процессы более плавными и гибкими. Например, вы можете легко сравнить производительность ряда алгоритмов, таких как:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "74bef463-7e3d-4941-b588-2703c858aaa2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "regressors = [\n",
+ " regressor_1()\n",
+ " ,regressor_2()\n",
+ " ,regressor_3()\n",
+ " ....]\n",
+ "for regressor in regressors:\n",
+ " pipeline = Pipeline(steps = [\n",
+ " ('preprocessor', preprocessor)\n",
+ " ,('regressor',regressor)\n",
+ " ])\n",
+ " model = pipeline.fit(X_train, y_train)\n",
+ " predictions = model.predict(X_test)\n",
+ " print (regressor)\n",
+ " print (f('Model r2 score:{r2_score(predictions, y_test)}')"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}