Построение финансовой модели машинного обучения с помощью инструмента «Что, если» и Vertex AI

1. Обзор

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

Что ты учишь

Вы узнаете, как:

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

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

2. Знакомство с Vertex AI

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

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

Шаг 3. Создайте экземпляр блокнотов

В разделе Vertex облачной консоли нажмите «Ноутбуки»:

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

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

Экземпляр TFE

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

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

Как только ваш экземпляр JupyterLab откроется, вам нужно будет добавить пакет XGBoost.

Для этого выберите Терминал в лаунчере:

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

pip3 install xgboost==1.2

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

Шаг 5. Импортируйте пакеты Python

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

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. Загрузите и обработайте данные

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

Шаг 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, передав ему типы данных, указанные выше. Важно перетасовать наши данные, если исходный набор данных упорядочен определенным образом. Для этого мы используем утилиту sklearn под названием shuffle , которую мы импортировали в первую ячейку:

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 указывает на то, что она отклонена.

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

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

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

Около 66% набора данных содержат одобренные приложения.

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

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

get_dummies принимает столбец с несколькими возможными значениями и преобразует его в серию столбцов, каждый из которых содержит только 0 и 1. Например, если бы у нас был столбец «цвет» с возможными значениями «синий» и «красный», 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. Разделение данных на обучающие и тестовые наборы

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

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

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. Создайте визуализацию инструмента «Что, если»

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

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

Создать экземпляр инструмента «Что если» так же просто, как создать объект WitConfigBuilder и передать ему модель, которую мы хотим проанализировать.

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

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 показывает нам прогноз модели, где 1approved прогноз с высокой степенью достоверности, а 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 тысяч долларов. После 200 тысяч долларов эта функция не влияет на прогноз модели.

Шаг 5. Изучите общую производительность и справедливость

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

Выберите mortgage_status в качестве основной истинной функции, чтобы увидеть матрицу путаницы:

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

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

Затем в раскрывающемся списке слева выберите «Slice by» : loan_purpose_Home_purchase :

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

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

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

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

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

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

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

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

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

Шаг 1. Создайте корзину Cloud Storage для нашей модели.

Давайте сначала определим некоторые переменные среды, которые мы будем использовать на протяжении всей остальной части кода. Введите в приведенные ниже значения имя вашего проекта 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 container-image-uri сообщает Vertex AI, какой предварительно созданный контейнер использовать для обслуживания. После завершения этой команды перейдите в раздел моделей консоли Vertex, чтобы получить идентификатор вашей новой модели. Вы можете найти это здесь:

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

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

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 и щелкните значок удаления:

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