{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "7g-aS09aNwxg"
   },
   "outputs": [],
   "source": [
    "# импортируем библиотеки numpy, pandas и sklearn\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import sklearn\n",
    "# импортируем функцию train_test_split(), с помощью\n",
    "# которой разбиваем данные на обучающие и тестовые\n",
    "from sklearn.model_selection import train_test_split\n",
    "# импортируем классы BaseEstimator и TransformerMixin, \n",
    "# позволяющие написать собственные классы\n",
    "from sklearn.base import BaseEstimator, TransformerMixin\n",
    "# импортируем класс SimpleImputer, позволяющий\n",
    "# выполнить импутацию пропусков\n",
    "from sklearn.impute import SimpleImputer\n",
    "# импортируем класс StandardScaler, позволяющий выполнить стандартизацию\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "# импортируем класс OneHotEncoder, позволяющий выполнить дамми-кодирование\n",
    "from sklearn.preprocessing import OneHotEncoder\n",
    "# импортируем класс LogisticRegression\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "# импортируем функцию roc_auc_score() для вычисления AUC-ROC\n",
    "from sklearn.metrics import roc_auc_score\n",
    "# импортируем класс ColumnTransformer, позволяющий выполнять\n",
    "# преобразования для отдельных типов столбцов\n",
    "from sklearn.compose import ColumnTransformer\n",
    "# импортируем класс FunctionTransformer, позволяющий\n",
    "# задавать пользовательские функции\n",
    "from sklearn.preprocessing import FunctionTransformer\n",
    "# импортируем класс Pipeline, позволяющий создавать конвейеры\n",
    "from sklearn.pipeline import Pipeline\n",
    "# импортируем класс GridSearchCV, позволяющий \n",
    "# выполнить поиск по сетке\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "# импортируем dill и cloudpickle для сохранения модели\n",
    "import dill\n",
    "import cloudpickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "numpy: 1.22.4\n",
      "pandas: 1.5.3\n",
      "dill: 0.3.6\n",
      "cloudpickle: 2.0.0\n",
      "scikit-learn: 1.0.2\n"
     ]
    }
   ],
   "source": [
    "# смотрим версии библиотек\n",
    "print(f\"numpy: {np.__version__}\")\n",
    "print(f\"pandas: {pd.__version__}\")\n",
    "print(f\"dill: {dill.__version__}\")\n",
    "print(f\"cloudpickle: {cloudpickle.__version__}\")\n",
    "print(f\"scikit-learn: {sklearn.__version__}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "XJUTB8AHNwxi"
   },
   "outputs": [],
   "source": [
    "# считываем данные\n",
    "data = pd.read_csv('Data/cs-training.csv', index_col='Unnamed: 0')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "id": "BO6nztUKNwxk"
   },
   "outputs": [],
   "source": [
    "# пишем функцию предварительной подготовки\n",
    "def preprocessing(df):\n",
    "    \n",
    "    # значения переменной age меньше 18 заменяем\n",
    "    # минимально допустимым значением возраста\n",
    "    df['age'] = np.where(df['age'] < 18, 18, df['age'])\n",
    "    \n",
    "    # создаем переменную Ratio - отношение количества \n",
    "    # просрочек 90+ к общему количеству просрочек\n",
    "    sum_of_delinq = (df['NumberOfTimes90DaysLate'] + \n",
    "                     df['NumberOfTime30-59DaysPastDueNotWorse'] + \n",
    "                     df['NumberOfTime60-89DaysPastDueNotWorse'])\n",
    "\n",
    "    cond = (df['NumberOfTimes90DaysLate'] == 0) | (sum_of_delinq == 0)\n",
    "    df['Ratio'] = np.where(\n",
    "        cond, 0, df['NumberOfTimes90DaysLate'] / sum_of_delinq)\n",
    "    \n",
    "    # создаем индикатор нулевых значений переменной \n",
    "    # NumberOfOpenCreditLinesAndLoans\n",
    "    df['NumberOfOpenCreditLinesAndLoans_is_0'] = np.where(\n",
    "        df['NumberOfOpenCreditLinesAndLoans'] == 0, 'T', 'F')\n",
    "    \n",
    "    # создаем индикатор нулевых значений переменной \n",
    "    # NumberRealEstateLoansOrLines\n",
    "    df['NumberRealEstateLoansOrLines_is_0'] = np.where(\n",
    "        df['NumberRealEstateLoansOrLines'] == 0, 'T', 'F')\n",
    "    \n",
    "    # создаем индикатор нулевых значений переменной \n",
    "    # RevolvingUtilizationOfUnsecuredLines\n",
    "    df['RevolvingUtilizationOfUnsecuredLines_is_0'] = np.where(\n",
    "        df['RevolvingUtilizationOfUnsecuredLines'] == 0, 'T', 'F')\n",
    "    \n",
    "    # преобразовываем переменные в категориальные, применив\n",
    "    # биннинг и перевод в единый строковый формат\n",
    "    for col in ['NumberOfTime30-59DaysPastDueNotWorse', \n",
    "                'NumberOfTime60-89DaysPastDueNotWorse',\n",
    "                'NumberOfTimes90DaysLate']:\n",
    "        df.loc[df[col] > 3, col] = 4\n",
    "        df[col] = df[col].apply(lambda x: f\"cat_{x}\")\n",
    "        \n",
    "    # создаем список списков - список 2-факторных взаимодействий\n",
    "    lst = [\n",
    "        ['NumberOfDependents', \n",
    "         'NumberOfTime30-59DaysPastDueNotWorse'],\n",
    "        ['NumberOfTime60-89DaysPastDueNotWorse', \n",
    "         'NumberOfTimes90DaysLate'],\n",
    "        ['NumberOfTime30-59DaysPastDueNotWorse', \n",
    "         'NumberOfTime60-89DaysPastDueNotWorse'],\n",
    "        ['NumberRealEstateLoansOrLines_is_0', \n",
    "         'NumberOfTimes90DaysLate'],\n",
    "        ['NumberOfOpenCreditLinesAndLoans_is_0', \n",
    "         'NumberOfTimes90DaysLate']\n",
    "    ]\n",
    "    \n",
    "    # создаем взаимодействия\n",
    "    for i in lst:\n",
    "        f1 = i[0]\n",
    "        f2 = i[1]\n",
    "        df[f1 + ' + ' + f2 + '_interact'] = (df[f1].astype(str) + ' + ' \n",
    "                                             + df[f2].astype(str))\n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "J5DKZD34Nwxl"
   },
   "outputs": [],
   "source": [
    "# применяем нашу функцию\n",
    "data = preprocessing(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "aKFlPA82Nwxm"
   },
   "outputs": [],
   "source": [
    "# создаем обучающий массив предикторов, тестовый массив предикторов,\n",
    "# обучающий массив меток, тестовый массив меток\n",
    "train, test, y_train, y_test = train_test_split(\n",
    "    data.drop('SeriousDlqin2yrs', axis=1), \n",
    "    data['SeriousDlqin2yrs'], \n",
    "    test_size=.3, \n",
    "    stratify=data['SeriousDlqin2yrs'], \n",
    "    random_state=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "id": "mr66UCKyNwxm"
   },
   "outputs": [],
   "source": [
    "# создаем собственный класс NumberOfDependentsReplacer, который\n",
    "# заменяет пропуски переменной NumberOfDependents\n",
    "# на определенное константное значение\n",
    "class NumberOfDependentsReplacer(BaseEstimator, TransformerMixin):\n",
    "    \"\"\"\n",
    "    Параметры:\n",
    "        threshold: пороговое значение\n",
    "        replace_value: значение, \n",
    "        на которое заменяем\n",
    "    \"\"\"\n",
    "    def __init__(self, replace_value=0):\n",
    "        self.replace_value = replace_value\n",
    "        \n",
    "    def fit(self, X, y=None):\n",
    "        return self\n",
    "    \n",
    "    def transform(self, X):\n",
    "        X_replaced = np.where(X.isnull(), self.replace_value, X)\n",
    "        return X_replaced"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "lPT-DXGmNwxn"
   },
   "outputs": [],
   "source": [
    "# создаем собственный класс MonthlyIncomeReplacer, который\n",
    "# заменяет пропуски и значения переменной MonthlyIncome\n",
    "# ниже заданного порога на определенное константное значение\n",
    "class MonthlyIncomeReplacer(BaseEstimator, TransformerMixin):\n",
    "    \"\"\"\n",
    "    Параметры:\n",
    "        threshold: пороговое значение\n",
    "        replace_value: значение, \n",
    "        на которое заменяем\n",
    "    \"\"\"\n",
    "    def __init__(self, threshold=1200, replace_value=1200):\n",
    "        self.threshold = threshold\n",
    "        self.replace_value = replace_value\n",
    "        \n",
    "    def fit(self, X, y=None):\n",
    "        return self\n",
    "    \n",
    "    def transform(self, X):\n",
    "        X_trans = np.where((X.isnull()) | (X < self.threshold), \n",
    "                           self.replace_value, X)\n",
    "        return X_trans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "uuBGcDHwNwxn"
   },
   "outputs": [],
   "source": [
    "# создаем собственный класс UtilizationThresholdSetter, который\n",
    "# заменяет значения переменной RevolvingUtilizationOfUnsecuredLines\n",
    "# выше заданного порога на пропуски\n",
    "class UtilizationThresholdSetter(BaseEstimator, TransformerMixin):\n",
    "    \"\"\"\n",
    "    Параметры:\n",
    "        threshold: пороговое значение\n",
    "    \"\"\"\n",
    "    def __init__(self, threshold=2):\n",
    "        self.threshold = threshold\n",
    "        \n",
    "    def fit(self, X, y=None):\n",
    "        return self\n",
    "    \n",
    "    def transform(self, X):\n",
    "        X_trans = np.where(X > self.threshold, np.NaN, X)\n",
    "        return X_trans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "id": "0VupffXXNwxo"
   },
   "outputs": [],
   "source": [
    "# создаем собственный класс, выполняющий биннинг\n",
    "class CustomDiscretizer(BaseEstimator, TransformerMixin):\n",
    "    \"\"\"\n",
    "    Параметры:\n",
    "        bins: список бинов.\n",
    "    \"\"\"\n",
    "    def __init__(self, bins=np.arange(0, 1.05, 0.05)):\n",
    "        self.bins = bins\n",
    "    \n",
    "    def fit(self, X, y=None):\n",
    "        # fit опять бездельничает\n",
    "        return self\n",
    "    \n",
    "    def transform(self, X):\n",
    "        # transform выполняет всю работу: применяет преобразование \n",
    "        # с помощью заданного значения параметра bins\n",
    "        self.bins[0] = -1\n",
    "        X_bin = np.digitize(X, self.bins).astype('object')\n",
    "        return X_bin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "id": "QGPcDRE7Nwxo"
   },
   "outputs": [],
   "source": [
    "# создаем собственный класс, выполняющий винзоризацию\n",
    "class OutlierRemover(BaseEstimator, TransformerMixin):\n",
    "    \"\"\"\n",
    "    Параметры:\n",
    "    lower_quantile: float, по умолчанию 0\n",
    "        Нижний квантиль.\n",
    "    upper_quantile: float, по умолчанию 0.75\n",
    "        Верхний квантиль.\n",
    "    k: float, по умолчанию 1.5\n",
    "        Коэффициент.\n",
    "    copy: bool, по умолчанию True\n",
    "        Возвращает копию.\n",
    "    \"\"\"\n",
    "    def __init__(self, copy=True, lower_quantile=0, \n",
    "                 upper_quantile=0.75, k=1.5):\n",
    "        # все параметры для инициализации публичных атрибутов \n",
    "        # должны быть заданы в методе __init__\n",
    "        \n",
    "        # публичные атрибуты\n",
    "        self.copy = copy\n",
    "        self.lower_quantile = lower_quantile\n",
    "        self.upper_quantile = upper_quantile\n",
    "        self.k = k\n",
    "        \n",
    "    def __is_numpy(self, X):\n",
    "        # частный метод, который с помощью функции isinstance()\n",
    "        # проверяет, является ли наш объект массивом NumPy\n",
    "        return isinstance(X, np.ndarray)\n",
    "                \n",
    "    def fit(self, X, y=None):\n",
    "        # fit должен принимать в качестве аргументов X и y\n",
    "        \n",
    "        # обучение модели осуществляется прямо здесь\n",
    "        # создаем пустой словарь, в котором ключами\n",
    "        # будут имена/целые числа, а значениями - кортежами\n",
    "        self._dict = {}\n",
    "        \n",
    "        # если 1D-массив, то переводим в 2D\n",
    "        if len(X.shape) == 1:\n",
    "            X = X.reshape(-1, 1)\n",
    "            \n",
    "        # записываем количество столбцов\n",
    "        ncols = X.shape[1]\n",
    "        \n",
    "        # записываем результат __is_numpy()\n",
    "        is_np = self.__is_numpy(X)\n",
    "        \n",
    "        # если объект - массив NumPy, выполняем следующие действия:\n",
    "        if is_np:\n",
    "            # по каждому столбцу массива NumPy\n",
    "            for col in range(ncols):\n",
    "                lower = np.quantile(X[:, col], self.lower_quantile)\n",
    "                upper = np.quantile(X[:, col], self.upper_quantile)\n",
    "                IQR = (upper - lower) * self.k\n",
    "                self._dict[col] = (lower, upper, IQR)\n",
    "        # в противном случае, т.е. если объект - датафрейм pandas,\n",
    "        # выполняем следующие действия:\n",
    "        else:\n",
    "            # по каждому столбцу датафрейма pandas\n",
    "            for col in X.columns:\n",
    "                # вычисляем и записываем в словарь\n",
    "                lower = X[col].quantile(self.lower_quantile)\n",
    "                upper = X[col].quantile(self.upper_quantile)\n",
    "                IQR = (upper - lower) * self.k\n",
    "                self._dict[col] = (lower, upper, IQR)\n",
    "\n",
    "        # fit возвращает self\n",
    "        return self\n",
    "    \n",
    "    def transform(self, X):\n",
    "        # transform принимает в качестве аргумента только X\n",
    "        \n",
    "        # выполняем копирование массива во избежание \n",
    "        # предупреждения SettingWithCopyWarning\n",
    "        # \"A value is trying to be set on a copy of \n",
    "        # a slice from a DataFrame (Происходит попытка изменить \n",
    "        # значение в копии среза данных датафрейма)\"\n",
    "        if self.copy:\n",
    "            X = X.copy()\n",
    "        \n",
    "        # если 1D-массив, то переводим в 2D\n",
    "        if len(X.shape) == 1:\n",
    "            X = X.reshape(-1, 1)\n",
    "            \n",
    "        # записываем количество столбцов\n",
    "        ncols = X.shape[1]\n",
    "        \n",
    "        # записываем результат __is_numpy()\n",
    "        is_np = self.__is_numpy(X)\n",
    "        \n",
    "        # применяем преобразование к X\n",
    "        # если объект - массив NumPy, выполняем следующие действия:\n",
    "        if is_np:\n",
    "            # по каждому столбцу массива NumPy\n",
    "            for col in range(ncols):\n",
    "                # заменяем\n",
    "                X[:, col] = np.where(\n",
    "                    X[:, col] < (self._dict[col][0] - self._dict[col][2]), \n",
    "                    self._dict[col][0] - self._dict[col][2], \n",
    "                    X[:, col])\n",
    "                X[:, col] = np.where(\n",
    "                    X[:, col] >= (self._dict[col][1] + self._dict[col][2]), \n",
    "                    self._dict[col][1] + self._dict[col][2], \n",
    "                    X[:, col])\n",
    "                \n",
    "        # в противном случае, т.е. если объект - датафрейм pandas,\n",
    "        # выполняем следующие действия:\n",
    "        else:\n",
    "            # по каждому столбцу датафрейма pandas\n",
    "            for col in X.columns:\n",
    "                # заменяем\n",
    "                X[col] = np.where(\n",
    "                    X[col] < (self._dict[col][0] - self._dict[col][2]), \n",
    "                    self._dict[col][0] - self._dict[col][2], \n",
    "                    X[col])\n",
    "                X[col] = np.where(\n",
    "                    X[col] >= (self._dict[col][1] + self._dict[col][2]), \n",
    "                    self._dict[col][1] + self._dict[col][2], \n",
    "                    X[col]) \n",
    "        # transform возвращает X\n",
    "        return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "oS-h2duxNwxp"
   },
   "outputs": [],
   "source": [
    "# создаем список категориальных переменных\n",
    "cat_columns = train.dtypes[train.dtypes == 'object'].index.tolist()\n",
    "# создаем список количественных переменных\n",
    "num_columns = train.dtypes[train.dtypes != 'object'].index.tolist()\n",
    "# создаем список с переменной NumberOfDependents\n",
    "numberofdependents = ['NumberOfDependents']\n",
    "# создаем список с переменной MonthlyIncome\n",
    "income = ['MonthlyIncome']\n",
    "# создаем список с переменной DebtRatio\n",
    "debtratio = ['DebtRatio']\n",
    "# создаем список с переменной RevolvingUtilizationOfUnsecuredLines\n",
    "utilization = ['RevolvingUtilizationOfUnsecuredLines']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# удаляем из списка количественных переменных переменные MonthlyIncome,\n",
    "# DebtRatio и RevolvingUtilizationOfUnsecuredLines\n",
    "num_columns = list(set(num_columns).difference(\n",
    "    set(numberofdependents + income + debtratio + utilization)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "id": "hwfEvpPaNwxq"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для количественных переменных\n",
    "num_pipe = Pipeline([\n",
    "    ('imp', SimpleImputer(strategy='median')),\n",
    "    ('scaler', StandardScaler())\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "id": "qqWBa4TlsxpW"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для переменной NumberOfDependents\n",
    "numberofdependents_pipe = Pipeline([\n",
    "    ('trans', NumberOfDependentsReplacer()),\n",
    "    ('scaler', StandardScaler())\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "4EjLJPIuNwxq"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для переменной MonthlyIncome\n",
    "income_pipe = Pipeline([\n",
    "    ('trans', MonthlyIncomeReplacer()),\n",
    "    ('imp', SimpleImputer(strategy='median')),\n",
    "    ('log', FunctionTransformer(np.log, validate=False)),\n",
    "    ('scaler', StandardScaler())\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "82o_rJF8Nwxr"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для переменной DebtRatio\n",
    "debtratio_pipe = Pipeline([\n",
    "    ('outl', OutlierRemover()),\n",
    "    ('scaler', StandardScaler())\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "id": "jY0965HCNwxr"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для переменной DebtRatio\n",
    "debtratio_pipe2 = Pipeline([\n",
    "    ('outl', OutlierRemover()),\n",
    "    ('binn', CustomDiscretizer()),\n",
    "    ('ohe', OneHotEncoder(sparse=False, handle_unknown='ignore'))\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "id": "oXyCVUl7Nwxs"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для переменной RevolvingUtilizationOfUnsecuredLines\n",
    "utilization_pipe = Pipeline([\n",
    "    ('trans', UtilizationThresholdSetter()),\n",
    "    ('imp', SimpleImputer(strategy='mean')),\n",
    "    ('scaler', StandardScaler())\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "id": "l_Iub7l8Nwxs"
   },
   "outputs": [],
   "source": [
    "# создаем конвейер для категориальных переменных\n",
    "cat_pipe = Pipeline([('ohe', OneHotEncoder(sparse=False, \n",
    "                                           handle_unknown='ignore'))])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "id": "rJOXK2rLNwxs"
   },
   "outputs": [],
   "source": [
    "# создаем список трехэлементных кортежей, в котором первый\n",
    "# элемент кортежа - название конвейера с преобразованиями\n",
    "transformers = [('num', num_pipe, num_columns),\n",
    "                ('numberofdependents', numberofdependents_pipe, numberofdependents),\n",
    "                ('income', income_pipe, income),\n",
    "                ('debtratio', debtratio_pipe, debtratio),\n",
    "                ('debtratio2', debtratio_pipe2, debtratio),\n",
    "                ('utilization', utilization_pipe, utilization),\n",
    "                ('cat', cat_pipe, cat_columns)]\n",
    "\n",
    "# передаем список трансформеров в ColumnTransformer\n",
    "transformer = ColumnTransformer(transformers=transformers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "id": "vU68FGtQNwxt"
   },
   "outputs": [],
   "source": [
    "# задаем итоговый конвейер\n",
    "pipe = Pipeline([('tf', transformer), \n",
    "                 ('logreg', LogisticRegression(C=0.03,\n",
    "                                               solver='liblinear', \n",
    "                                               random_state=42))])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "id": "HlFgy-AGNwxt"
   },
   "outputs": [],
   "source": [
    "# задаем сетку гиперпараметров\n",
    "param_grid = {'tf__utilization__trans__threshold': [1.5, 1.75, 2],\n",
    "              'tf__numberofdependents__trans__replace_value': [0, 1, 2, 3],\n",
    "              'tf__debtratio2__binn__bins': [np.arange(0, 1.05, 0.05), \n",
    "                                             np.arange(0, 1.05, 0.1)],\n",
    "              'tf__income__trans__replace_value': [25000, 30000, 35000],\n",
    "              'tf__debtratio__outl__upper_quantile': [0.75, 0.8, 0.85]\n",
    "             }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "id": "PONjaHY5Nwxt"
   },
   "outputs": [],
   "source": [
    "# создаем экземпляр класса GridSearchCV, передав конвейер,\n",
    "# сетку гиперпараметров и указав количество\n",
    "# блоков перекрестной проверки\n",
    "gs = GridSearchCV(pipe, \n",
    "                  param_grid, \n",
    "                  scoring='roc_auc',\n",
    "                  cv=5,\n",
    "                  n_jobs=-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "wqhwVvm7Nwxu",
    "outputId": "1832b187-80cf-4ca5-cfb8-6fa5c70100f4",
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/artemgruzdev/anaconda3/lib/python3.10/site-packages/joblib/externals/loky/process_executor.py:702: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Наилучшие значения гиперпараметров: {'tf__debtratio2__binn__bins': array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]), 'tf__debtratio__outl__upper_quantile': 0.8, 'tf__income__trans__replace_value': 35000, 'tf__numberofdependents__trans__replace_value': 3, 'tf__utilization__trans__threshold': 2}\n",
      "Наилучшее значение AUC-ROC: 0.863\n",
      "AUC-ROC на тестовом наборе: 0.864\n"
     ]
    }
   ],
   "source": [
    "# выполняем поиск по сетке\n",
    "gs.fit(train, y_train)\n",
    "# смотрим наилучшие значения гиперпараметров\n",
    "print(\"Наилучшие значения гиперпараметров: {}\".format(gs.best_params_))\n",
    "# смотрим наилучшее значение AUC-ROC\n",
    "print(\"Наилучшее значение AUC-ROC: {:.3f}\".format(gs.best_score_))\n",
    "# смотрим значение AUC-ROC на тестовой выборке\n",
    "print(\"AUC-ROC на тестовом наборе: {:.3f}\".format(\n",
    "    roc_auc_score(y_test, gs.predict_proba(test)[:, 1])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['DebtRatio_1',\n",
       " 'DebtRatio_2',\n",
       " 'DebtRatio_3',\n",
       " 'DebtRatio_4',\n",
       " 'DebtRatio_5',\n",
       " 'DebtRatio_6',\n",
       " 'DebtRatio_7',\n",
       " 'DebtRatio_8',\n",
       " 'DebtRatio_9',\n",
       " 'DebtRatio_10',\n",
       " 'DebtRatio_11']"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# извлекаем дамми-переменные, созданные классом OneHotEncoder\n",
    "# для конвейера debtratio_pipe2\n",
    "debtratio2 = gs.best_estimator_['tf'].named_transformers_['debtratio2']\n",
    "debtratio2_onehot_columns = list(\n",
    "    debtratio2.named_steps['ohe'].get_feature_names_out(input_features=debtratio)\n",
    ")\n",
    "debtratio2_onehot_columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['NumberOfTime30-59DaysPastDueNotWorse_cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_4',\n",
       " 'NumberOfTimes90DaysLate_cat_0',\n",
       " 'NumberOfTimes90DaysLate_cat_1',\n",
       " 'NumberOfTimes90DaysLate_cat_2',\n",
       " 'NumberOfTimes90DaysLate_cat_3',\n",
       " 'NumberOfTimes90DaysLate_cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_4',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0_F',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0_T',\n",
       " 'NumberRealEstateLoansOrLines_is_0_F',\n",
       " 'NumberRealEstateLoansOrLines_is_0_T',\n",
       " 'RevolvingUtilizationOfUnsecuredLines_is_0_F',\n",
       " 'RevolvingUtilizationOfUnsecuredLines_is_0_T',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_10.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_10.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_13.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_20.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_8.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_9.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_4',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_0',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_1',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_2',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_3',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_4',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_0',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_1',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_2',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_3',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_4',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_0',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_1',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_2',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_3',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_4',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_0',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_1',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_2',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_3',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_4']"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# извлекаем дамми-переменные, созданные классом OneHotEncoder\n",
    "# для конвейера cat_pipe\n",
    "cat = gs.best_estimator_['tf'].named_transformers_['cat']\n",
    "cat_onehot_columns = list(\n",
    "    cat.named_steps['ohe'].get_feature_names_out(input_features=cat_columns)\n",
    ")\n",
    "cat_onehot_columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['NumberRealEstateLoansOrLines',\n",
       " 'Ratio',\n",
       " 'age',\n",
       " 'NumberOfOpenCreditLinesAndLoans',\n",
       " 'NumberOfDependents',\n",
       " 'MonthlyIncome',\n",
       " 'DebtRatio',\n",
       " 'DebtRatio_1',\n",
       " 'DebtRatio_2',\n",
       " 'DebtRatio_3',\n",
       " 'DebtRatio_4',\n",
       " 'DebtRatio_5',\n",
       " 'DebtRatio_6',\n",
       " 'DebtRatio_7',\n",
       " 'DebtRatio_8',\n",
       " 'DebtRatio_9',\n",
       " 'DebtRatio_10',\n",
       " 'DebtRatio_11',\n",
       " 'RevolvingUtilizationOfUnsecuredLines',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse_cat_4',\n",
       " 'NumberOfTimes90DaysLate_cat_0',\n",
       " 'NumberOfTimes90DaysLate_cat_1',\n",
       " 'NumberOfTimes90DaysLate_cat_2',\n",
       " 'NumberOfTimes90DaysLate_cat_3',\n",
       " 'NumberOfTimes90DaysLate_cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse_cat_4',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0_F',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0_T',\n",
       " 'NumberRealEstateLoansOrLines_is_0_F',\n",
       " 'NumberRealEstateLoansOrLines_is_0_T',\n",
       " 'RevolvingUtilizationOfUnsecuredLines_is_0_F',\n",
       " 'RevolvingUtilizationOfUnsecuredLines_is_0_T',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_10.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_10.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_13.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_20.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_4',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_8.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_9.0 + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_0',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_1',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_2',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_3',\n",
       " 'NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_4',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_0',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_1',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_2',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_3',\n",
       " 'NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_4',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_0',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_1',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_2',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_3',\n",
       " 'NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_4',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_0',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_1',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_2',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_3',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_4',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_0',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_1',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_2',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_3',\n",
       " 'NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_4',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_0',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_1',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_2',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_3',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_4',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_0',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_1',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_2',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_3',\n",
       " 'NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_4']"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# объединяем списки признаков, сохраняем тот же порядок\n",
    "# столбцов, что задал ColumnTransformer\n",
    "all_columns = (num_columns + numberofdependents + income + \n",
    "               debtratio + debtratio2_onehot_columns + \n",
    "               utilization + cat_onehot_columns)\n",
    "all_columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.251"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# извлекаем константу\n",
    "intercept = np.round(gs.best_estimator_['logreg'].intercept_[0], 3)\n",
    "intercept"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.164,  0.245, -0.234,  0.178,  0.014, -0.147, -0.08 , -0.285,\n",
       "        -0.291, -0.329, -0.217, -0.085,  0.003,  0.066,  0.197,  0.196,\n",
       "         0.179,  0.315,  0.609, -0.52 , -0.086,  0.002,  0.172,  0.181,\n",
       "        -0.116, -0.131, -0.05 ,  0.027,  0.018, -0.423, -0.122,  0.081,\n",
       "         0.149,  0.064, -0.178, -0.073, -0.2  , -0.051, -0.281,  0.03 ,\n",
       "        -0.169, -0.05 ,  0.08 ,  0.03 ,  0.07 , -0.066, -0.104, -0.049,\n",
       "         0.109, -0.001, -0.002, -0.002, -0.011, -0.057, -0.078, -0.017,\n",
       "        -0.123,  0.108, -0.012,  0.02 , -0.014, -0.06 ,  0.038,  0.145,\n",
       "        -0.009,  0.127,  0.026,  0.069, -0.042, -0.034, -0.025, -0.057,\n",
       "         0.001, -0.024,  0.08 ,  0.042,  0.064,  0.01 ,  0.008, -0.009,\n",
       "        -0.009,  0.014,  0.012, -0.016, -0.01 , -0.263,  0.049,  0.023,\n",
       "         0.023, -0.088, -0.442, -0.255, -0.048,  0.138,  0.184,  0.059,\n",
       "         0.016,  0.004, -0.135, -0.067,  0.103,  0.085, -0.07 , -0.045,\n",
       "         0.009,  0.064, -0.056, -0.001,  0.074,  0.067,  0.101,  0.079,\n",
       "         0.065, -0.005, -0.175, -0.763,  0.003,  0.055,  0.153,  0.032,\n",
       "        -0.276, -0.172,  0.107,  0.157,  0.098,  0.096, -0.046, -0.128,\n",
       "         0.008,  0.073,  0.144,  0.03 ,  0.038, -0.052,  0.012,  0.377,\n",
       "         0.062,  0.009, -0.117, -0.15 , -0.224, -0.05 ,  0.011,  0.043,\n",
       "         0.02 ,  0.109, -0.08 , -0.06 , -0.017, -0.003, -0.274, -0.042,\n",
       "         0.034, -0.028,  0.133,  0.159, -0.088, -0.083,  0.055, -0.115]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# извлекаем коэффициенты\n",
    "coef = np.round(gs.best_estimator_['logreg'].coef_, 3)\n",
    "coef"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Константа: -0.251\n",
      "Регрессионные коэффициенты:\n",
      "NumberRealEstateLoansOrLines 0.164\n",
      "Ratio 0.245\n",
      "age -0.234\n",
      "NumberOfOpenCreditLinesAndLoans 0.178\n",
      "NumberOfDependents 0.014\n",
      "MonthlyIncome -0.147\n",
      "DebtRatio -0.08\n",
      "DebtRatio_1 -0.285\n",
      "DebtRatio_2 -0.291\n",
      "DebtRatio_3 -0.329\n",
      "DebtRatio_4 -0.217\n",
      "DebtRatio_5 -0.085\n",
      "DebtRatio_6 0.003\n",
      "DebtRatio_7 0.066\n",
      "DebtRatio_8 0.197\n",
      "DebtRatio_9 0.196\n",
      "DebtRatio_10 0.179\n",
      "DebtRatio_11 0.315\n",
      "RevolvingUtilizationOfUnsecuredLines 0.609\n",
      "NumberOfTime30-59DaysPastDueNotWorse_cat_0 -0.52\n",
      "NumberOfTime30-59DaysPastDueNotWorse_cat_1 -0.086\n",
      "NumberOfTime30-59DaysPastDueNotWorse_cat_2 0.002\n",
      "NumberOfTime30-59DaysPastDueNotWorse_cat_3 0.172\n",
      "NumberOfTime30-59DaysPastDueNotWorse_cat_4 0.181\n",
      "NumberOfTimes90DaysLate_cat_0 -0.116\n",
      "NumberOfTimes90DaysLate_cat_1 -0.131\n",
      "NumberOfTimes90DaysLate_cat_2 -0.05\n",
      "NumberOfTimes90DaysLate_cat_3 0.027\n",
      "NumberOfTimes90DaysLate_cat_4 0.018\n",
      "NumberOfTime60-89DaysPastDueNotWorse_cat_0 -0.423\n",
      "NumberOfTime60-89DaysPastDueNotWorse_cat_1 -0.122\n",
      "NumberOfTime60-89DaysPastDueNotWorse_cat_2 0.081\n",
      "NumberOfTime60-89DaysPastDueNotWorse_cat_3 0.149\n",
      "NumberOfTime60-89DaysPastDueNotWorse_cat_4 0.064\n",
      "NumberOfOpenCreditLinesAndLoans_is_0_F -0.178\n",
      "NumberOfOpenCreditLinesAndLoans_is_0_T -0.073\n",
      "NumberRealEstateLoansOrLines_is_0_F -0.2\n",
      "NumberRealEstateLoansOrLines_is_0_T -0.051\n",
      "RevolvingUtilizationOfUnsecuredLines_is_0_F -0.281\n",
      "RevolvingUtilizationOfUnsecuredLines_is_0_T 0.03\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_0 -0.169\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_1 -0.05\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_2 0.08\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_3 0.03\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_0.0 + cat_4 0.07\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_0 -0.066\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_1 -0.104\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_2 -0.049\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_3 0.109\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_1.0 + cat_4 -0.001\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_10.0 + cat_0 -0.002\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_10.0 + cat_1 -0.002\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_13.0 + cat_1 -0.011\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_0 -0.057\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_1 -0.078\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_2 -0.017\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_3 -0.123\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_2.0 + cat_4 0.108\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_20.0 + cat_1 -0.012\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_0 0.02\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_1 -0.014\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_2 -0.06\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_3 0.038\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_3.0 + cat_4 0.145\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_0 -0.009\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_1 0.127\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_2 0.026\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_3 0.069\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_4.0 + cat_4 -0.042\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_0 -0.034\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_1 -0.025\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_2 -0.057\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_3 0.001\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_5.0 + cat_4 -0.024\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_0 0.08\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_1 0.042\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_2 0.064\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_6.0 + cat_3 0.01\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_0 0.008\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_1 -0.009\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_2 -0.009\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_3 0.014\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_7.0 + cat_4 0.012\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_8.0 + cat_0 -0.016\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_9.0 + cat_0 -0.01\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_0 -0.263\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_1 0.049\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_2 0.023\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_3 0.023\n",
      "NumberOfDependents + NumberOfTime30-59DaysPastDueNotWorse_interact_nan + cat_4 -0.088\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_0 -0.442\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_1 -0.255\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_2 -0.048\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_3 0.138\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_0 + cat_4 0.184\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_0 0.059\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_1 0.016\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_2 0.004\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_3 -0.135\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_1 + cat_4 -0.067\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_0 0.103\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_1 0.085\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_2 -0.07\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_3 -0.045\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_2 + cat_4 0.009\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_0 0.064\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_1 -0.056\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_2 -0.001\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_3 0.074\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_3 + cat_4 0.067\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_0 0.101\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_1 0.079\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_2 0.065\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_3 -0.005\n",
      "NumberOfTime60-89DaysPastDueNotWorse + NumberOfTimes90DaysLate_interact_cat_4 + cat_4 -0.175\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_0 -0.763\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_1 0.003\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_2 0.055\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_3 0.153\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_0 + cat_4 0.032\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_0 -0.276\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_1 -0.172\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_2 0.107\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_3 0.157\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_1 + cat_4 0.098\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_0 0.096\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_1 -0.046\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_2 -0.128\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_3 0.008\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_2 + cat_4 0.073\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_0 0.144\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_1 0.03\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_2 0.038\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_3 -0.052\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_3 + cat_4 0.012\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_0 0.377\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_1 0.062\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_2 0.009\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_3 -0.117\n",
      "NumberOfTime30-59DaysPastDueNotWorse + NumberOfTime60-89DaysPastDueNotWorse_interact_cat_4 + cat_4 -0.15\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_0 -0.224\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_1 -0.05\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_2 0.011\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_3 0.043\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_F + cat_4 0.02\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_0 0.109\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_1 -0.08\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_2 -0.06\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_3 -0.017\n",
      "NumberRealEstateLoansOrLines_is_0 + NumberOfTimes90DaysLate_interact_T + cat_4 -0.003\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_0 -0.274\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_1 -0.042\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_2 0.034\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_3 -0.028\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_F + cat_4 0.133\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_0 0.159\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_1 -0.088\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_2 -0.083\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_3 0.055\n",
      "NumberOfOpenCreditLinesAndLoans_is_0 + NumberOfTimes90DaysLate_interact_T + cat_4 -0.115\n"
     ]
    }
   ],
   "source": [
    "# печатаем название \"Константа\"    \n",
    "print(\"Константа:\", intercept)\n",
    "# печатаем название \"Регрессионные коэффициенты\"\n",
    "print(\"Регрессионные коэффициенты:\")\n",
    "# для удобства сопоставим каждому названию \n",
    "# предиктора соответствующий коэффициент\n",
    "for c, feature in zip(coef[0], all_columns):\n",
    "    print(feature, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "id": "jAldb_csNwxu"
   },
   "outputs": [],
   "source": [
    "# записываем CSV-файл в объект DataFrame \n",
    "fulldata = pd.read_csv('Data/cs-training.csv', index_col='Unnamed: 0')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "id": "oIwFqLw3Nwxu"
   },
   "outputs": [],
   "source": [
    "# применяем функцию предварительной обработки \n",
    "# ко всем историческим данным\n",
    "fulldata = preprocessing(fulldata)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "id": "8atRZ6plNwxv"
   },
   "outputs": [],
   "source": [
    "# создаем массив меток и массив признаков\n",
    "y_fulldata = fulldata.pop('SeriousDlqin2yrs')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "HUHKxEPnNwxv",
    "outputId": "6b1756e0-dd39-4ad9-ed4d-df57b97b07b4"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUC-ROC на всей исторической выборке: 0.864\n"
     ]
    }
   ],
   "source": [
    "# записываем оптимальные значения гиперпараметров\n",
    "best_params = gs.best_params_\n",
    "# присваиваем итоговому конвейеру оптимальные \n",
    "# значения гиперпараметров\n",
    "pipe.set_params(**best_params)\n",
    "# обучаем итоговый конвейер с оптимальными значениями \n",
    "# гиперпараметров на всех исторических данных\n",
    "pipe.fit(fulldata, y_fulldata)\n",
    "# смотрим значение AUC-ROC\n",
    "print(\"AUC-ROC на всей исторической выборке: {:.3f}\".format(\n",
    "    roc_auc_score(y_fulldata, pipe.predict_proba(fulldata)[:, 1])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "id": "44cy-e_ANwxv"
   },
   "outputs": [],
   "source": [
    "# записываем CSV-файл, содержащий новые данные,\n",
    "# в объект DataFrame\n",
    "newdata = pd.read_csv('Data/cs-test.csv', \n",
    "                      index_col=0)\n",
    "# записываем идентификатор набора новых данных\n",
    "test_id = newdata.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "id": "n9SQ_26sNwxw"
   },
   "outputs": [],
   "source": [
    "# выполняем предварительную обработку\n",
    "# новых данных\n",
    "newdata = preprocessing(newdata)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "LGn9GrH7Nwxw",
    "outputId": "a42c3f8b-8e11-48d0-b48a-ca091ce7a383"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.05478814, 0.0505688 , 0.01713461, 0.09490252, 0.10470266])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# при помощью итогового конвейера с оптимальными значениями \n",
    "# гиперпараметров, обученного на всей исторической выборке, \n",
    "# вычисляем вероятности для новых данных\n",
    "prob = pipe.predict_proba(newdata)[:, 1]\n",
    "# выведем вероятности для первых 5 наблюдений\n",
    "prob[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "id": "XqqAHOQmNwxw"
   },
   "outputs": [],
   "source": [
    "# формируем посылку\n",
    "pd.DataFrame({'Id': test_id, 'Probability': prob}).to_csv(\n",
    "    'subm_giveme.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "# сохраняем модель с помощью dill\n",
    "with open('streamlit_deployment/pipeline_for_deployment.pkl', 'wb') as f:\n",
    "    dill.dump(pipe, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "# сохраняем модель с помощью cloudpickle\n",
    "with open('fastapi_deployment/cloudpickle_pipeline_for_deployment.pkl', 'wb') as f:\n",
    "    cloudpickle.dump(pipe, f)"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "provenance": []
  },
  "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.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
