Google Cloud недавно запустил VertexAI, и в рамках этого магазина был выпущен FeatureStore. Согласно официальному определению, Vertex Feature Store (Feature Store) предоставляет централизованное хранилище для организации, хранения и обслуживания функций машинного обучения. Вы можете прочитать больше здесь.

Хранилище функций использует модель данных временных рядов для хранения ряда значений функций, позволяя Хранилищу функций поддерживать значения функций по мере их изменения с течением времени. Магазин возможностей иерархически упорядочивает ресурсы в следующем порядке: Featurestore -> EntityType -> Feature. Вы должны определить и создать эти ресурсы, прежде чем сможете загружать данные в Feature Store.

Давайте возьмем пример и посмотрим, как мы можем настроить хранилище функций с помощью VertexAI. Посмотрим, какими могут быть эти функции:

  1. Заполняется в магазине функций.
  2. Подается онлайн из магазина функций с низкой задержкой.
  3. Пакетный экспорт для обучения модели.
  4. Поиск в магазине функций.

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

user_pseudo_id
country
operating_system
language
cnt_user_engagement
cnt_level_start_quickplay
cnt_level_end_quickplay
cnt_level_complete_quickplay
cnt_level_reset_quickplay
cnt_post_score
cnt_spend_virtual_currency
cnt_ad_reward
cnt_challenge_a_friend
cnt_completed_5_levels
cnt_use_extra_steps
user_first_engagement
month
julianday
dayofweek
timestamp

Примечание. Приведенные выше данные можно ввести в BigQuery, указав этот блокнот.

В нашем примере entityType - это Users, а entityID будет отдельной записью пользователя, идентифицированной user_pseudo_id. Возможности будут всеми атрибутами выше, кроме user_pseudo_id и timestamp. В нашем примере мы загрузим только 2 функции в хранилище функций, то есть cnt_user_engagement и cnt_level_start_quickplay.

Начнем с создания магазина функций.

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
FEATURESTORE_ID="gamingusers"
cat <<EOM > request.json
{
  "online_serving_config": {
    "fixed_node_count": 1
  },
  "labels": {
    "environment": "gamingusers"
  }
}
EOM
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores?featurestoreId=${FEATURESTORE_ID}

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

{
  "name": "projects/<<projectnumber>>/locations/us-central1/featurestores/gamingusers/operations/5740181047589470208",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1beta1.CreateFeaturestoreOperationMetadata",
    "genericMetadata": {
      "createTime": "2021-06-13T19:49:41.432926Z",
      "updateTime": "2021-06-13T19:49:41.432926Z"
    }
  }
}

Отображение Featurestore займет несколько минут. Теперь мы создадим entityType с именем users.

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
FEATURESTORE_ID="gamingusers"
ENTITY_TYPE_ID="users"
cat <<EOM > request.json
{
  "description": "Users Entity Type",
  "monitoringConfig": {
    "snapshotAnalysis": {
      "monitoringInterval": "3600s"
    }
  }
}
EOM
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores/${FEATURESTORE_ID}/entityTypes?entityTypeId=${ENTITY_TYPE_ID}

При успешном создании entitytype вы получите успешный ответ, как показано ниже:

{
  "name": "projects/<<projectid>>/locations/us-central1/featurestores/gamingusers/entityTypes/users/operations/8100067252331610112",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1beta1.CreateEntityTypeOperationMetadata",
    "genericMetadata": {
      "createTime": "2021-06-13T19:56:56.466253Z",
      "updateTime": "2021-06-13T19:56:56.466253Z"
    }
  }
}

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

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
FEATURESTORE_ID="gamingusers"
ENTITY_TYPE_ID="users"
cat <<EOM > request.json
{
  "requests": [
    {
      "feature": {
        "description": "User Engagement",
        "valueType": "INT64",
        "monitoringConfig": {
          "snapshotAnalysis": {
            "monitoringInterval": "3600s"
          }
        }
      },
      "featureId": "cnt_user_engagement"
    },
    {
      "feature": {
        "description": "Level start quickplay",
        "valueType": "INT64",
        "monitoringConfig": {
          "snapshotAnalysis": {
            "monitoringInterval": "3600s"
          }
        }
      },
      "featureId": "cnt_level_start_quickplay"
    }
  ]
}
EOM
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores/${FEATURESTORE_ID}/entityTypes/${ENTITY_TYPE_ID}/features:batchCreate

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

{
  "name": "projects/<<projectid>>/locations/us-central1/featurestores/gamingusers/operations/6888598952568946688",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1beta1.BatchCreateFeaturesOperationMetadata",
    "genericMetadata": {
      "createTime": "2021-06-13T20:07:08.755864Z",
      "updateTime": "2021-06-13T20:07:08.755864Z"
    }
  }
}

Теперь давайте получим данные из нашей таблицы BigQuery. Важно отметить, что ниже мы использовали user_pseudo_id для entityIdField и отметку времени для featureTimeField.

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
FEATURESTORE_ID="gamingusers"
ENTITY_TYPE_ID="users"
cat <<EOM > request.json
{
  "entityIdField": "user_pseudo_id",
  "featureTimeField": "timestamp",
  "bigquerySource": { "inputUri": "bq://<<projectid>>.<<dataset>>.train_tab" },
  "featureSpecs": [{
    "id": "cnt_level_start_quickplay",
    "sourceField": "cnt_level_start_quickplay"
  },{
    "id": "cnt_user_engagement",
    "sourceField": "cnt_user_engagement"
  }],
  "workerCount": 1
}
EOM
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores/${FEATURESTORE_ID}/entityTypes/${ENTITY_TYPE_ID}:importFeatureValues

Это запустит задание по загрузке данных из BigQuery в хранилище функций. Войдите в Google Cloud Console, перейдите в Vertex AI и нажмите «Просмотр заданий приема». Вы увидите, как показано ниже:

Теперь давайте рассмотрим функции из этого магазина функций. Мы будем использовать одно из значений user_pseudo_id для извлечения функций из магазина функций.

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
FEATURESTORE_ID="gamingusers"
ENTITY_TYPE_ID="users"
cat <<EOM > request.json
{
  "entityId": "4AEEE533D8FAED4AD0A9227618CD296B",
  "featureSelector": {
    "idMatcher": {
      "ids": ["cnt_level_start_quickplay", "cnt_user_engagement"]
    }
  }
}
EOM
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores/${FEATURESTORE_ID}/entityTypes/${ENTITY_TYPE_ID}:readFeatureValues

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

{
  "header": {
    "entityType": "projects/<<projectid>>/locations/us-central1/featurestores/gamingusers/entityTypes/users",
    "featureDescriptors": [
      {
        "id": "cnt_level_start_quickplay"
      },
      {
        "id": "cnt_user_engagement"
      }
    ]
  },
  "entityView": {
    "entityId": "4AEEE533D8FAED4AD0A9227618CD296B",
    "data": [
      {
        "value": {
          "int64Value": "111",
          "metadata": {
            "generateTime": "2021-06-08T20:40:03.847Z"
          }
        }
      },
      {
        "value": {
          "int64Value": "294",
          "metadata": {
            "generateTime": "2021-06-08T20:40:03.847Z"
          }
        }
      }
    ]
  }
}

Теперь давайте посмотрим, как эти данные можно извлечь обратно в BigQuery из хранилища функций для обучения модели машинного обучения.

Нам нужно создать CSV-файл, содержащий сведения об объектах, для которых мы хотим получить функции, и соответствующую временную метку, для которой необходимо получить значения функций. Имя заголовка столбца должно быть entityType и timestamp.

Мы создаем образец CSV-файла с user_pseudo_id, для которого мы хотим получить функции.

%%bash
cat <<EOM > csvReadInstances.csv
users,timestamp
"4AEEE533D8FAED4AD0A9227618CD296B",2021-07-15T08:28:14Z
"1BE4F29852B390FC94D2A4E7382CCEBD",2021-07-15T08:28:14Z
EOM

Теперь загружаем его в корзину Google Cloud Storage.

!gsutil cp csvReadInstances.csv gs://<<bucket>>/vertex-ai-pipelines/featurestore/readcsvinstances

Теперь давайте извлечем данные из Featurestore в Bigquery. Нам нужно указать путь BQ для таблицы, в которую данные будут экспортированы в качестве места назначения, а также путь CSV, который мы создали выше как csvReadInstances.

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
FEATURESTORE_ID="gamingusers"
ENTITY_TYPE_ID="users"
cat <<EOM > request.json
{
  "destination": {
    "bigqueryDestination": {
      "outputUri": "bq://<<projectid>>.<<dataset>>.export_features"
    }
  },
  "csvReadInstances": {
    "gcsSource": {
      "uris": ["gs://<<bucket>>/vertex-ai-pipelines/featurestore/readcsvinstances/csvReadInstances.csv"]
    }
  },
  "entityTypeSpecs": [
    {
      "entityTypeId": "users",
      "featureSelector": {
        "idMatcher": {
          "ids": ["cnt_level_start_quickplay", "cnt_user_engagement"]
        }
      }
    }
  ]
}
EOM
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores/${FEATURESTORE_ID}:batchReadFeatureValues

При успешном выполнении будет создана таблица BigQuery в соответствующем наборе данных, как показано ниже:

Со временем магазин функций будет расти, и специалистам по данным потребуется поиск функций. Теперь давайте перейдем к функциям поиска в нашем магазине функций. В приведенном ниже примере мы ищем функции, в названии которых есть «cnt» и которые относятся к типу «INT64».

%%bash
LOCATION="REGIONID"
PROJECT="PROJECTID"
curl -X GET \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT}/locations/${LOCATION}/featurestores:searchFeatures?query="featureId:cnt%20AND%20valueType=INT64"

При успешном выполнении вы увидите результат, как показано ниже:

{
  "features": [
    {
      "name": "projects/<<projectid>>/locations/us-central1/featurestores/gamingusers/entityTypes/users/features/cnt_level_start_quickplay",
      "description": "Level start quickplay",
      "createTime": "2021-06-13T20:07:09.206472Z",
      "updateTime": "2021-06-13T21:15:39.596002Z"
    },
    {
      "name": "projects/<<projectid>>/locations/us-central1/featurestores/gamingusers/entityTypes/users/features/cnt_user_engagement",
      "description": "User Engagement",
      "createTime": "2021-06-13T20:07:09.205050Z",
      "updateTime": "2021-06-13T21:15:39.594700Z"
    }
  ]
}

Это все для этой истории. Следите за новостями о функциях VertexAI.