Создание финансовой модели МО с помощью инструмента «Что если» и Vertex AI

1. Обзор

В этой лабораторной работе вы будете использовать инструмент What-if для анализа модели XGBoost , обученной на финансовых данных. После анализа модели вы развернете ее в новой облачной платформе Vertex AI.

Чему вы научитесь

Вы научитесь:

  • Обучите модель XGBoost на общедоступном наборе данных по ипотечным кредитам в размещенном ноутбуке.
  • Проанализируйте модель с помощью инструмента «Что если...».
  • Разверните модель XGBoost в Vertex AI.

Общая стоимость запуска этой лабораторной работы в Google Cloud составляет около 1 доллара .

2. Введение в Vertex AI

В этой лабораторной работе используется новейший продукт для искусственного интеллекта, доступный в Google Cloud. Vertex AI интегрирует предложения машинного обучения в Google Cloud в единый процесс разработки. Ранее модели, обученные с помощью AutoML, и пользовательские модели были доступны через отдельные сервисы. Новое предложение объединяет оба варианта в единый API, а также включает другие новые продукты. Вы также можете перенести существующие проекты в Vertex AI. Если у вас есть какие-либо замечания, пожалуйста, посетите страницу поддержки .

Vertex AI предлагает множество различных продуктов для поддержки комплексных рабочих процессов машинного обучения. В этой лабораторной работе мы сосредоточимся на продуктах, перечисленных ниже: прогнозирование и блокноты.

Обзор продукции Vertex

3. Краткое введение в XGBoost.

XGBoost — это фреймворк машинного обучения, использующий деревья решений и градиентный бустинг для построения прогностических моделей. Он работает путем объединения нескольких деревьев решений на основе оценок, связанных с различными листовыми узлами в дереве.

Приведенная ниже диаграмма представляет собой визуализацию простой модели дерева решений, которая оценивает, следует ли проводить спортивный матч, исходя из прогноза погоды:

Пример древовидной модели

Почему мы используем XGBoost для этой модели? Хотя традиционные нейронные сети, как было показано, лучше всего работают с неструктурированными данными, такими как изображения и текст, деревья решений часто демонстрируют чрезвычайно хорошие результаты на структурированных данных, таких как набор данных по ипотеке, который мы будем использовать в этом практическом занятии.

4. Настройте свою среду.

Для выполнения этого практического задания вам потребуется проект Google Cloud Platform с включенной оплатой. Чтобы создать проект, следуйте инструкциям здесь .

Шаг 1: Включите API Compute Engine.

Перейдите в Compute Engine и выберите «Включить», если эта опция еще не включена. Она понадобится для создания экземпляра ноутбука.

Шаг 2: Включите API Vertex AI

Перейдите в раздел Vertex в вашей облачной консоли и нажмите «Включить API Vertex AI» .

Панель управления Vertex

Шаг 3: Создайте экземпляр Notebooks.

В разделе Vertex вашей облачной консоли нажмите на «Блокноты»:

Выберите блокноты

Затем выберите «Создать экземпляр» . После этого выберите тип экземпляра TensorFlow Enterprise 2.3 без графических процессоров :

экземпляр TFE

Используйте параметры по умолчанию, а затем нажмите «Создать ». После создания экземпляра выберите «Открыть JupyterLab» .

Шаг 4: Установите XGBoost

После запуска экземпляра JupyterLab вам потребуется добавить пакет XGBoost.

Для этого выберите «Терминал» в меню запуска:

Затем выполните следующие действия, чтобы установить последнюю версию XGBoost, поддерживаемую Vertex AI:

pip3 install xgboost==1.2

После завершения этого процесса откройте экземпляр Python 3 Notebook из панели запуска. Теперь вы готовы начать работу в своем блокноте!

Шаг 5: Импорт пакетов Python

В первой ячейке вашего блокнота добавьте следующие импорты и запустите ячейку. Вы можете запустить её, нажав кнопку со стрелкой вправо в верхнем меню или нажав комбинацию клавиш Command+Enter:

import pandas as pd
import xgboost as xgb
import numpy as np
import collections
import witwidget

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.utils import shuffle
from witwidget.notebook.visualization import WitWidget, WitConfigBuilder

5. Загрузка и обработка данных

Для обучения модели XGBoost мы будем использовать набор данных по ипотечным кредитам с сайта ffiec.gov . Мы провели предварительную обработку исходного набора данных и создали уменьшенную версию, которую вы можете использовать для обучения модели. Модель будет предсказывать , будет ли одобрена конкретная заявка на ипотечный кредит .

Шаг 1: Загрузите предварительно обработанный набор данных.

Мы предоставили вам версию набора данных в Google Cloud Storage. Вы можете загрузить его, выполнив следующую команду gsutil в своем блокноте Jupyter:

!gsutil cp 'gs://mortgage_dataset_files/mortgage-small.csv' .

Шаг 2: Прочитайте набор данных с помощью Pandas.

Прежде чем создавать DataFrame Pandas, мы создадим dict с типами данных каждого столбца, чтобы Pandas корректно считывал наш набор данных:

COLUMN_NAMES = collections.OrderedDict({
 'as_of_year': np.int16,
 'agency_code': 'category',
 'loan_type': 'category',
 'property_type': 'category',
 'loan_purpose': 'category',
 'occupancy': np.int8,
 'loan_amt_thousands': np.float64,
 'preapproval': 'category',
 'county_code': np.float64,
 'applicant_income_thousands': np.float64,
 'purchaser_type': 'category',
 'hoepa_status': 'category',
 'lien_status': 'category',
 'population': np.float64,
 'ffiec_median_fam_income': np.float64,
 'tract_to_msa_income_pct': np.float64,
 'num_owner_occupied_units': np.float64,
 'num_1_to_4_family_units': np.float64,
 'approved': np.int8
})

Далее мы создадим DataFrame, передав ему указанные выше типы данных. Важно перемешать данные на случай, если исходный набор данных упорядочен определенным образом. Для этого мы используем утилиту shuffle из sklearn , которую мы импортировали в первой ячейке:

data = pd.read_csv(
 'mortgage-small.csv',
 index_col=False,
 dtype=COLUMN_NAMES
)
data = data.dropna()
data = shuffle(data, random_state=2)
data.head()

data.head() позволяет предварительно просмотреть первые пять строк нашего набора данных в Pandas. После выполнения приведенной выше строки вы должны увидеть что-то подобное:

Предварительный просмотр набора данных по ипотеке

Это те признаки, которые мы будем использовать для обучения нашей модели. Если вы прокрутите страницу до конца, вы увидите последний столбец approved , который и является тем, что мы прогнозируем. Значение 1 означает, что конкретная заявка была одобрена, а 0 — что она была отклонена.

Чтобы увидеть распределение одобренных/отклоненных значений в наборе данных и создать массив numpy с метками, выполните следующую команду:

# Class labels - 0: denied, 1: approved
print(data['approved'].value_counts())

labels = data['approved'].values
data = data.drop(columns=['approved'])

Примерно 66% набора данных содержат утвержденные заявки.

Шаг 3: Создание фиктивного столбца для категориальных значений

Этот набор данных содержит смесь категориальных и числовых значений, но XGBoost требует, чтобы все признаки были числовыми. Вместо представления категориальных значений с помощью one-hot кодирования , для нашей модели XGBoost мы воспользуемся функцией Pandas get_dummies .

get_dummies принимает столбец с несколькими возможными значениями и преобразует его в последовательность столбцов, каждый из которых содержит только нули и единицы. Например, если у нас есть столбец "color" с возможными значениями "blue" и "red", get_dummies преобразует его в два столбца, названные "color_blue" и "color_red", со всеми логическими значениями 0 и 1.

Для создания фиктивных столбцов для наших категориальных признаков выполните следующий код:

dummy_columns = list(data.dtypes[data.dtypes == 'category'].index)
data = pd.get_dummies(data, columns=dummy_columns)

data.head()

При предварительном просмотре данных вы увидите, что отдельные признаки (например, purchaser_type показанный ниже) разделены на несколько столбцов:

Вспомогательные колонки Pandas

Шаг 4: Разделение данных на обучающую и тестовую выборки.

Важным понятием в машинном обучении является разделение данных на обучающую и тестовую выборки. Мы берем большую часть данных для обучения модели, а остальную часть оставляем для тестирования модели на данных, которые она никогда раньше не видела.

Добавьте в свой блокнот следующий код, который использует функцию train_test_split из библиотеки Scikit-learn для разделения данных:

x,y = data.values,labels
x_train,x_test,y_train,y_test = train_test_split(x,y)

Теперь вы готовы создать и обучить свою модель!

6. Создайте, обучите и оцените модель XGBoost.

Шаг 1: Определить и обучить модель XGBoost.

Создать модель в XGBoost очень просто. Мы будем использовать класс XGBClassifier для создания модели и нам нужно лишь передать правильный параметр objective для нашей конкретной задачи классификации. В данном случае мы используем reg:logistic поскольку у нас задача бинарной классификации, и мы хотим, чтобы модель выдавала одно значение в диапазоне (0,1): 0 для «не одобрено», 1 для «одобрено».

Следующий код создаст модель XGBoost:

model = xgb.XGBClassifier(
    objective='reg:logistic'
)

Вы можете обучить модель всего одной строкой кода, вызвав метод fit() и передав ему обучающие данные и метки.

model.fit(x_train, y_train)

Шаг 2: Оцените точность вашей модели.

Теперь мы можем использовать нашу обученную модель для генерации прогнозов на тестовых данных с помощью функции predict() .

Затем мы воспользуемся функцией accuracy_score() из библиотеки Scikit-learn для вычисления точности нашей модели на основе её работы на тестовых данных. Мы передадим ей истинные значения вместе с предсказанными моделью значениями для каждого примера в нашем тестовом наборе:

y_pred = model.predict(x_test)
acc = accuracy_score(y_test, y_pred.round())
print(acc, '\n')

Вы должны получить точность около 87% , но ваши результаты могут немного отличаться, поскольку в машинном обучении всегда присутствует элемент случайности.

Шаг 3: Сохраните свою модель

Для развертывания модели выполните следующий код, чтобы сохранить ее в локальный файл:

model.save_model('model.bst')

7. Используйте инструмент «Что если», чтобы интерпретировать вашу модель.

Шаг 1: Создайте визуализацию с помощью инструмента «Что если».

Чтобы подключить инструмент What-if к вашей локальной модели, вам необходимо передать ему подмножество тестовых примеров вместе с истинными значениями для этих примеров. Давайте создадим массив Numpy из 500 наших тестовых примеров вместе с их истинными метками:

num_wit_examples = 500
test_examples = np.hstack((x_test[:num_wit_examples],y_test[:num_wit_examples].reshape(-1,1)))

Создать экземпляр инструмента What-if Tool очень просто: достаточно создать объект WitConfigBuilder и передать ему модель, которую мы хотим проанализировать.

Поскольку инструмент What-If ожидает список оценок для каждого класса в нашей модели (в данном случае 2), мы будем использовать метод predict_proba из XGBoost с инструментом What-If:

config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
  .set_custom_predict_fn(model.predict_proba)
  .set_target_feature('mortgage_status')
  .set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)

Обратите внимание, что загрузка визуализации займет минуту. После загрузки вы должны увидеть следующее:

Первоначальный вид инструмента «Что если»

По оси Y отображается предсказание модели, где 1 означает предсказание с высокой степенью approved , а 0 — предсказание, denied с высокой степенью достоверности. По оси X показано распределение всех загруженных точек данных.

Шаг 2: Изучение отдельных точек данных

По умолчанию в инструменте «Что если» используется вкладка «Редактор точек данных» . Здесь вы можете щелкнуть по любой отдельной точке данных, чтобы просмотреть ее характеристики, изменить значения характеристик и увидеть, как это изменение влияет на прогноз модели для данной точки данных.

В приведенном ниже примере мы выбрали точку данных, близкую к пороговому значению 0,5. Заявка на ипотеку, связанная с этой конкретной точкой данных, поступила от CFPB (Бюро финансовой и потребительской информации США). Мы изменили значение этого параметра на 0, а также изменили значение agency_code_Department of Housing and Urban Development (HUD) на 1, чтобы посмотреть, что произойдет с прогнозом модели, если этот кредит поступит от HUD:

Как видно в левой нижней части инструмента «Что если», изменение этой функции значительно снизило прогнозируемую моделью вероятность approved на 32%. Это может указывать на то, что организация, выдавшая кредит, оказывает сильное влияние на результаты модели, но для подтверждения этого необходимы дополнительные исследования.

В левой нижней части пользовательского интерфейса также можно увидеть истинное значение для каждой точки данных и сравнить его с предсказанием модели:

Шаг 3: Контрфактический анализ

Далее, щелкните по любой точке данных и переместите ползунок «Показать ближайшую контрфактическую точку данных» вправо:

Выбрав этот пункт, вы увидите точку данных, значения признаков которой наиболее близки к исходной точке, но имеют противоположное предсказание. Затем вы можете просмотреть значения признаков, чтобы увидеть, в чем заключаются различия между двумя точками данных (различия выделены зеленым цветом и жирным шрифтом).

Шаг 4: Изучите графики частичной зависимости.

Чтобы увидеть, как каждая функция влияет на общие прогнозы модели, установите флажок «График частичной зависимости» и убедитесь, что выбран параметр «Глобальный график частичной зависимости» :

Здесь мы видим, что вероятность отказа в выдаче кредитов, предоставляемых HUD, несколько выше. График имеет такую ​​форму, потому что код агентства является логическим параметром, поэтому значения могут быть только равны 0 или 1.

applicant_income_thousands — это числовой показатель, и на графике частичной зависимости видно, что более высокий доход немного увеличивает вероятность одобрения заявки, но только до суммы около 200 000 долларов. После 200 000 долларов этот показатель не влияет на прогноз модели.

Шаг 5: Оценка общей эффективности и справедливости.

Далее перейдите на вкладку «Производительность и справедливость» . Здесь отображаются общие статистические данные о производительности модели на предоставленном наборе данных, включая матрицы ошибок, кривые PR и ROC-кривые.

Выберите mortgage_status в качестве эталонного признака, чтобы увидеть матрицу ошибок:

Эта матрица ошибок показывает правильные и неправильные прогнозы нашей модели в процентах от общего числа . Если сложить квадраты « Фактическое «Да» / «Прогнозируемое «Да»» и «Фактическое «Нет» / «Прогнозируемое «Нет»» , то сумма должна дать ту же точность, что и у вашей модели (в данном случае около 87%, хотя точность вашей модели может немного отличаться, поскольку в обучении моделей машинного обучения присутствует элемент случайности).

Вы также можете поэкспериментировать с ползунком порогового значения, повышая и понижая оценку положительной классификации, которую модель должна вернуть, прежде чем принять решение о прогнозируемом approved кредита, и посмотреть, как это повлияет на точность, количество ложных срабатываний и ложных отрицаний. В этом случае точность наиболее высока при пороговом значении около 0,55 .

Далее, в раскрывающемся списке «Срез по» слева выберите loan_purpose_Home_purchase :

Теперь вы увидите результаты работы на двух подмножествах ваших данных: срез «0» показывает случаи, когда кредит не предназначен для покупки жилья, а срез «1» — случаи, когда кредит предназначен для покупки жилья. Проверьте точность, количество ложноположительных и ложноотрицательных результатов для обоих срезов, чтобы выявить различия в производительности.

Если вы развернете строки, чтобы посмотреть на матрицы ошибок, вы увидите, что модель предсказывает одобрение примерно для 70% заявок на кредиты для покупки жилья и только для 46% кредитов, не связанных с покупкой жилья (точные проценты будут варьироваться в зависимости от вашей модели):

Если вы выберете «Демографическое равенство» в переключателях слева, два пороговых значения будут скорректированы таким образом, чтобы модель прогнозировала approved для аналогичного процента заявителей в обоих сегментах. Как это повлияет на точность, количество ложных срабатываний и ложных отрицаний для каждого сегмента?

Шаг 6: Изучение распределения функций

Наконец, перейдите на вкладку «Признаки» в инструменте «Что если». Здесь вы увидите распределение значений для каждого признака в вашем наборе данных:

Вы можете использовать эту вкладку, чтобы убедиться в сбалансированности вашего набора данных. Например, похоже, что очень мало кредитов в наборе данных было выдано Агентством сельскохозяйственных услуг. Для повышения точности модели мы могли бы рассмотреть возможность добавления большего количества кредитов от этого агентства, если данные доступны.

Здесь мы описали лишь несколько идей для исследования вариантов развития событий с помощью этого инструмента. Не стесняйтесь продолжать экспериментировать с ним, есть еще много областей для изучения!

8. Разверните модель в Vertex AI

Наша модель работает локально, но было бы здорово, если бы мы могли делать прогнозы на её основе из любого места (а не только из этого ноутбука!). На этом этапе мы развернем её в облаке.

Шаг 1: Создайте сегмент облачного хранилища для нашей модели.

Для начала определим несколько переменных окружения, которые мы будем использовать на протяжении всего остального практического занятия. Заполните приведенные ниже значения именем вашего проекта Google Cloud, именем хранилища в облаке, которое вы хотите создать (оно должно быть уникальным для всего мира), и именем версии первой версии вашей модели:

# Update the variables below to your own Google Cloud project ID and GCS bucket name. You can leave the model name we've specified below:
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
MODEL_NAME = 'xgb_mortgage'

Теперь мы готовы создать хранилище для файла нашей модели XGBoost. Мы укажем Vertex AI на этот файл при развертывании.

Выполните следующую команду gsutil в своем ноутбуке, чтобы создать региональное хранилище:

!gsutil mb -l us-central1 $MODEL_BUCKET

Шаг 2: Скопируйте файл модели в облачное хранилище.

Далее мы скопируем сохраненный файл модели XGBoost в облачное хранилище. Выполните следующую команду gsutil:

!gsutil cp ./model.bst $MODEL_BUCKET

Перейдите в браузер хранилища в вашей облачной консоли, чтобы убедиться, что файл скопирован:

Шаг 3: Создайте модель и разверните ее на конечной точке.

Мы почти готовы развернуть модель в облаке! В Vertex AI модель может содержать несколько конечных точек. Сначала мы создадим модель, затем создадим конечную точку внутри этой модели и развернем её.

Сначала воспользуйтесь интерфейсом командной строки gcloud для создания вашей модели:

!gcloud beta ai models upload \
--display-name=$MODEL_NAME \
--artifact-uri=$MODEL_BUCKET \
--container-image-uri=us-docker.pkg.dev/cloud-aiplatform/prediction/xgboost-cpu.1-2:latest \
--region=us-central1

Параметр artifact-uri указывает на местоположение хранилища, где вы сохранили свою модель XGBoost. Параметр container-image-uri сообщает Vertex AI, какой предварительно созданный контейнер использовать для запуска. После завершения этой команды перейдите в раздел моделей в консоли Vertex, чтобы получить идентификатор вашей новой модели. Вы можете найти его здесь:

Получить идентификатор модели из консоли

Скопируйте этот ID и сохраните его в переменную:

MODEL_ID = "your_model_id"

Теперь пришло время создать конечную точку в рамках этой модели. Мы можем сделать это с помощью следующей команды gcloud:

!gcloud beta ai endpoints create \
--display-name=xgb_mortgage_v1 \
--region=us-central1

После завершения процесса в выводе блокнота должно отобразиться местоположение вашей конечной точки. Найдите строку, в которой указано, что конечная точка была создана с путем, похожим на следующий: projects/project_ID/locations/us-central1/endpoints/endpoint_ID. Затем замените значения ниже на идентификаторы вашей конечной точки, созданной выше:

ENDPOINT_ID = "your_endpoint_id"

Для развертывания конечной точки выполните следующую команду gcloud:

!gcloud beta ai endpoints deploy-model $ENDPOINT_ID \
--region=us-central1 \
--model=$MODEL_ID \
--display-name=xgb_mortgage_v1 \
--machine-type=n1-standard-2 \
--traffic-split=0=100

Развертывание конечной точки займет примерно 5-10 минут. Пока развертывается конечная точка, перейдите в раздел моделей в консоли. Щелкните по своей модели, и вы увидите, как развертывается ваша конечная точка:

После успешного завершения развертывания вы увидите зеленую галочку на месте индикатора загрузки.

Шаг 4: Тестирование развернутой модели

Чтобы убедиться в работоспособности развернутой модели, протестируйте ее с помощью gcloud для выполнения прогнозирования. Сначала сохраните JSON-файл с примером из нашего тестового набора:

%%writefile predictions.json
{
  "instances": [
    [2016.0, 1.0, 346.0, 27.0, 211.0, 4530.0, 86700.0, 132.13, 1289.0, 1408.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0]
  ]
}

Проверьте свою модель, выполнив следующую команду gcloud:

!gcloud beta ai endpoints predict $ENDPOINT_ID \
--json-request=predictions.json \
--region=us-central1

В выходных данных вы должны увидеть предсказание вашей модели. Этот конкретный пример был одобрен, поэтому вы должны увидеть значение, близкое к 1.

9. Уборка

Если вы хотите продолжить использование этого блокнота, рекомендуется выключать его, когда он не используется. В интерфейсе блокнотов в вашей облачной консоли выберите блокнот, а затем выберите «Остановить» :

Если вы хотите удалить все ресурсы, созданные в этой лабораторной работе, просто удалите экземпляр блокнота, а не останавливайте его.

Чтобы удалить развернутую конечную точку, перейдите в раздел «Конечные точки» в консоли Vertex и нажмите значок удаления:

Чтобы удалить сегмент хранилища, воспользуйтесь меню навигации в консоли Cloud Console, перейдите в раздел «Хранилище», выберите свой сегмент и нажмите «Удалить».