使用适用于 Google Cloud 的 ABAP SDK 在 SAP 中读取 BigQuery ML 预测结果

1. 简介

在此 Codelab 中,您将在 BigQuery 中创建一个机器学习 (ML) 模型,并使用适用于 Google Cloud 的 ABAP SDK 通过该模型获取预测结果。

您将利用以下 Google Cloud 服务:

  • BigQuery
  • Cloud Shell

构建内容

您将创建以下内容:

  • BigQuery 机器学习 (ML) 模型。
  • 具有 BigQuery Job User 角色的服务账号,用于调用 BigQuery API。
  • 用于调用 BigQuery API 并通过机器学习模型获取预测结果的 ABAP 程序。

2. 要求

  • 一个浏览器,例如 ChromeFirefox
  • 启用了结算功能的 Google Cloud 项目,或者为 Google Cloud Platform 创建 90 天免费试用账号
  • 您的系统中已安装 SAP GUI(Windows 或 Java)。如果您的笔记本电脑上已经安装了 SAP GUI,请使用虚拟机外部 IP 地址作为应用服务器 IP 地址连接到 SAP。如果您使用的是 Mac,还可以安装链接中提供的适用于 Java 的 SAP GUI。

3. 准备工作

6757b2fb50ddcc2d.png

  • 在 Cloud Shell 中运行以下命令以对您的账号进行身份验证,并将默认项目设置为 abap-sdk-poc。以可用区 us-west4-b 为例。如果需要,请根据您的偏好在以下命令中更改项目和可用区。
gcloud auth login
gcloud config set project abap-sdk-poc
gcloud config set compute/zone us-west4-b
  • 您必须有权访问安装了适用于 Google Cloud 的 ABAP SDK 的 SAP 系统。
  • 您必须先完成 Codelab 1(在 Google Cloud Platform 上安装 ABAP 平台试用版 1909 并安装适用于 Google Cloud 的 ABAP SDK)和 Codelab 2(使用在 Compute Engine 虚拟机上托管的 SAP 的令牌配置 ABAP SDK 身份验证),然后再继续此 Codelab。
  • 如果您已完成 Codelab 1 和 Codelab 2,则会在 Google Cloud 上为您预配一个 ABAP 平台试用 1909 系统,以及所需的身份验证和连接设置。
  • 如果您尚未完成 Codelab 1 和 Codelab 2,则将无法获得执行此 Codelab 中提供的步骤所需的基础架构和连接。因此,您必须先完成 Codelab 1 和 Codelab 2,然后才能继续学习此 Codelab。

4. 在 Google Cloud 项目中启用 BigQuery API V2

  1. 在 Cloud 控制台中,点击右上角的激活 Cloud Shell

6757b2fb50ddcc2d.png

  1. 在 Cloud Shell 中运行以下命令以启用 BigQuery API:
gcloud services enable bigquery.googleapis.com

成功执行后,您应该会看到如下所示的消息

b5f52859df2c2f56.png

现在,您应该已在 Google Cloud 项目中启用 BigQuery API。

5. 创建服务账号以确保安全的 BigQuery 访问

为了安全地从 BigQuery ML 模型获取机器学习预测结果,您需要创建一个具有 BigQuery Job UserBigQuery Data Viewer 角色的服务账号,以便您的程序在项目中运行查询(作为作业),并从表中读取数据。此角色仅授予创建作业和读取数据所需的权限,从而最大限度地降低安全风险。

创建服务账号

如需创建具有所需角色的服务账号,请执行以下步骤:

  1. 在 Cloud Shell 终端中运行以下命令:
gcloud iam service-accounts create abap-sdk-bigquery-jobuser --display-name="Service Account for BigQuery Job user"
  1. 现在,将所需的角色添加到上一步中创建的服务账号:
gcloud projects add-iam-policy-binding abap-sdk-poc --member='serviceAccount:abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com' --role='roles/bigquery.jobUser'

gcloud projects add-iam-policy-binding abap-sdk-poc --member='serviceAccount:abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com' --role='roles/bigquery.dataViewer'

上述命令使用 abap-sdk-poc 作为 Google Cloud 项目的占位符。将 abap-sdk-poc 替换为您的项目 ID。

  1. 如需验证是否已添加此角色,请前往 IAM 页面。您创建的服务账号应连同分配给该账号的角色一起列出。

6. 创建 BigQuery 机器学习模型

在此 Codelab 中,我们将创建一个 k-means 模型,对伦敦自行车租赁数据集进行聚类。您可以应用 k-means 算法,将数据按聚类进行分组。监督式机器学习与预测分析有关,而非监督式学习则与描述性分析有关。而是要了解数据,以便做出数据驱动型决策。

创建数据集

如需创建 BigQuery 数据集来存储机器学习模型,请执行以下步骤:

  1. 在 Google Cloud 控制台中,前往 BigQuery 页面。转到 BigQuery 页面
  2. 探索器窗格中,点击您的项目名称。
  3. 点击 5cf3b742649f1e2c 查看操作 >创建数据集

3fbc072041bfa313

  1. 创建数据集 页面上,执行以下操作:
  • 数据集 ID 部分,输入 bqml_tutorial
  • 对于位置类型,选择多区域,然后选择欧盟(欧盟的多个区域)。伦敦自行车租赁公共数据集存储在欧盟多区域位置。您的数据集必须位于同一位置。
  • 将其余默认设置保持原样,然后点击创建数据集创建数据集页面。

创建 k-means 模型

现在您的数据集已设置完毕,下一步是使用数据创建 k-means 模型。您可以使用带有 model_type=kmeans 选项的 CREATE MODEL 语句创建和训练 k-means 模型。

如需运行查询并创建 k-means 模型,请执行以下步骤:

  1. 前往 BigQuery 页面。前往 BigQuery
  2. 在编辑器窗格中,运行以下 SQL 语句:
CREATE OR REPLACE MODEL `bqml_tutorial.london_station_clusters`
  OPTIONS(model_type='kmeans', num_clusters=4) AS
WITH
  hs AS (
  SELECT
    h.start_station_name AS station_name,
  IF
    (EXTRACT(DAYOFWEEK
      FROM
        h.start_date) = 1
      OR EXTRACT(DAYOFWEEK
      FROM
        h.start_date) = 7,
      "weekend",
      "weekday") AS isweekday,
    h.duration,
    ST_DISTANCE(ST_GEOGPOINT(s.longitude,
        s.latitude),
      ST_GEOGPOINT(-0.1,
        51.5))/1000 AS distance_from_city_center
  FROM
    `bigquery-public-data.london_bicycles.cycle_hire` AS h
  JOIN
    `bigquery-public-data.london_bicycles.cycle_stations` AS s
  ON
    h.start_station_id = s.id
  WHERE
    h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP)
    AND CAST('2016-01-01 00:00:00' AS TIMESTAMP) ),
  stationstats AS (
  SELECT
    station_name,
    isweekday,
    AVG(duration) AS duration,
    COUNT(duration) AS num_trips,
    MAX(distance_from_city_center) AS distance_from_city_center
  FROM
    hs
  GROUP BY
    station_name, isweekday)
SELECT
  * EXCEPT(station_name, isweekday)
FROM
  stationstats
  1. 在导航面板的资源部分,展开项目名称,点击 bqml_tutorial,然后点击 london_station_clusters
  2. 点击架构标签页。模型架构列出了 BigQuery ML 用于执行聚类的三个车站属性。架构应如下所示:

5f1feb313bd0f6a5

  1. 点击评估标签页。此标签页显示 k-means 模型标识的聚类的可视化。在数值特征下,条形图最多可显示每个形心的 10 个最重要的数值特征值。您可以从下拉菜单中选择要直观呈现的功能。

8f9b53971e33dc08

7. 使用适用于 Google Cloud 的 ABAP SDK 获取 BigQuery ML 预测结果

现在,您已经在 Google Cloud 端设置了前提条件,接下来可以在 SAP 系统中完成相关步骤,使用适用于 Google Cloud 的 ABAP SDK 从机器学习模型获取预测结果。

创建客户端密钥配置

对于身份验证和连接相关配置,适用于 Google Cloud 的 ABAP SDK 使用表 /GOOG/CLIENT_KEY/GOOG/SERVIC_MAP.

如需保留 /GOOG/CLIENT_KEY 表中的配置,请执行以下步骤:

  1. 在 SAP GUI 中,输入事务代码 SPRO
  2. 点击 SAP 参考 IMG
  3. 点击 ABAP SDK for Google Cloud >基本设置 >配置客户端密钥

25871e639293b9ee

  1. 请保留所列字段的以下值,并将其他所有字段留空:

字段

Google Cloud 密钥名称

BIGQUERY_ML

Google Cloud 服务账号名称

abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com

Google Cloud 范围

https://www.googleapis.com/auth/cloud-platform

项目 ID

abap-sdk-poc

授权类

/GOOG/CL_AUTH_GOOGLE

构建 ABAP 报告以通过 BigQuery ML 模型获取预测结果

如需生成 ABAP 报告,请按以下步骤操作:

  1. 在 SAP GUI 中,找到交易代码 SE38 并创建一个名为 ZDEMO_BIGQUERY_ML_PREDICT. 的报告程序
  2. 在打开的弹出式窗口中,提供详细信息,如下图所示:

4cb32d50427df294.png

  1. 在下一个弹出式窗口中,选择本地对象或提供适当的软件包名称。
  2. 在 ABAP 编辑器中,添加以下代码:
REPORT zdemo_bigquery_ml_predict.

types:
  begin of lty_query_result,
    centroid_id     type i,
    station_name    type string,
    isweekday       type string,
    num_trips       type i,
    distance_from_city type string,
  end of lty_query_result,
  ltt_query_result type standard table of lty_query_result.

DATA:
  lv_project_id TYPE string,
  ls_input      TYPE /goog/cl_bigquery_v2=>ty_103,
  ls_output     TYPE lty_query_result,
  lt_output     TYPE ltt_query_result.

CONSTANTS:
  lc_newline TYPE c VALUE cl_abap_char_utilities=>newline.

TRY.
    "Initialize Bigquery object, pass the client key name that you have configured in /GOOG/CLIENT_KEY table
    DATA(lo_bq) = NEW /goog/cl_bigquery_v2( iv_key_name = 'BIGQUERY_ML' ).

    "Populate relevant parameters
    lv_project_id = lo_bq->gv_project_id.

    ls_input-default_dataset-project_id = 'abap-sdk-poc'.
    ls_input-default_dataset-dataset_id = 'bqml_tutorial'.

    "This query gets predictions from
    ls_input-query =
                | WITH | && lc_newline &&
                | hs AS ( | && lc_newline &&
                | SELECT | && lc_newline &&
                | h.start_station_name AS station_name, | && lc_newline &&
                | IF | && lc_newline &&
                | (EXTRACT(DAYOFWEEK | && lc_newline &&
                | FROM | && lc_newline &&
                | h.start_date) = 1 | && lc_newline &&
                | OR EXTRACT(DAYOFWEEK | && lc_newline &&
                | FROM | && lc_newline &&
                | h.start_date) = 7, | && lc_newline &&
                | "weekend", | && lc_newline &&
                | "weekday") AS isweekday, | && lc_newline &&
                | h.duration, | && lc_newline &&
                | ST_DISTANCE(ST_GEOGPOINT(s.longitude, | && lc_newline &&
                | s.latitude), | && lc_newline &&
                | ST_GEOGPOINT(-0.1, | && lc_newline &&
                | 51.5))/1000 AS distance_from_city_center | && lc_newline &&
                | FROM | && lc_newline &&
                | `bigquery-public-data.london_bicycles.cycle_hire` AS h | && lc_newline &&
                | JOIN | && lc_newline &&
                | `bigquery-public-data.london_bicycles.cycle_stations` AS s | && lc_newline &&
                | ON | && lc_newline &&
                | h.start_station_id = s.id | && lc_newline &&
                | WHERE | && lc_newline &&
                | h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP) | && lc_newline &&
                | AND CAST('2016-01-01 00:00:00' AS TIMESTAMP) ), | && lc_newline &&
                | stationstats AS ( | && lc_newline &&
                | SELECT | && lc_newline &&
                | station_name, | && lc_newline &&
                | isweekday, | && lc_newline &&
                | AVG(duration) AS duration, | && lc_newline &&
                | COUNT(duration) AS num_trips, | && lc_newline &&
                | MAX(distance_from_city_center) AS distance_from_city_center | && lc_newline &&
                | FROM | && lc_newline &&
                | hs | && lc_newline &&
                | GROUP BY | && lc_newline &&
                | station_name, isweekday ) | && lc_newline &&
                | SELECT | && lc_newline &&
                | * EXCEPT(nearest_centroids_distance) | && lc_newline &&
                | FROM | && lc_newline &&
                | ML.PREDICT( MODEL `bqml_tutorial.london_station_clusters`, | && lc_newline &&
                | ( | && lc_newline &&
                | SELECT | && lc_newline &&
                | * | && lc_newline &&
                | FROM | && lc_newline &&
                | stationstats | && lc_newline &&
                | WHERE | && lc_newline &&
                | REGEXP_CONTAINS(station_name, 'Kennington'))) |.

    "Call API method: bigquery.jobs.query
    CALL METHOD lo_bq->query_jobs
      EXPORTING
        iv_p_project_id = lv_project_id
        is_input        = ls_input
      IMPORTING
        es_output       = DATA(ls_response)
        ev_ret_code     = DATA(lv_ret_code)
        ev_err_text     = DATA(lv_err_text)
        es_err_resp     = DATA(ls_err_resp).

    IF lo_bq->is_success( lv_ret_code ).
      "API Call successful, loop through the data & display the result
      IF ls_response-job_complete = abap_true.
        LOOP AT ls_response-rows ASSIGNING FIELD-SYMBOL(<ls_row>).
          LOOP AT <ls_row>-f ASSIGNING FIELD-SYMBOL(<ls_value>).
            ASSIGN <ls_value>-v->* TO FIELD-SYMBOL(<ls_field_value>).
            CASE sy-tabix.
              WHEN 1.
                ls_output-centroid_id = <ls_field_value>.
              WHEN 2.
                ls_output-station_name = <ls_field_value>.
              WHEN 3.
                ls_output-isweekday = <ls_field_value>.
              WHEN 4.
                ls_output-num_trips = <ls_field_value>.
              WHEN 5.
                ls_output-distance_from_city = <ls_field_value>.
            ENDCASE.
          ENDLOOP.
          APPEND ls_output TO lt_output.
          CLEAR ls_output.
        ENDLOOP.
        IF lt_output IS NOT INITIAL.
          cl_demo_output=>new( )->begin_section( 'ML.Predict Query Details'
                               )->write_text( ls_input-query
                               )->write_text( 'Dataset: bigquery-public-data.london_bicycles'
                               )->end_section(
                               )->begin_section( 'ML.Predict Query Results'
                               )->write_data( lt_output
                               )->end_section(
                               )->display( ).
        ENDIF.
      ENDIF.
    ELSE.
      "Display error message in case the API call fails
      MESSAGE lv_err_text TYPE 'E'.
    ENDIF.

    "Close HTTP Connection
    lo_bq->close( ).

  CATCH /goog/cx_sdk INTO DATA(lo_exception).
    MESSAGE lo_exception->get_text( ) TYPE 'E'.
ENDTRY.
  1. 保存并激活报告。
  2. 执行报告 (F8)。

成功执行后,您应该会看到如下所示的报告输出:

739e5685511fc9fc.png

6405542a597ed09f

8. 恭喜

出色完成“使用 Google Cloud 的 ABAP SDK 通过 BigQuery 机器学习 (ML) 模型获取预测结果”codelab!

您已成功从 SAP 系统内检索到 BigQuery 机器学习模型的预测结果!您已解锁 ABAP 与 Google Cloud 服务之间的集成的新高度。学习其他激动人心的 ABAP SDK for Google Cloud Codelab,拓宽视野:

  • 将 Translation API 与适用于 Google Cloud 的 ABAP SDK 搭配使用
  • 使用分块将大型对象上传到 Cloud Storage 存储分区
  • 使用适用于 Google Cloud 的 ABAP SDK 从 Secret Manager 检索凭据/Secret
  • 从 ABAP 调用 Vertex AI test-bison

9. 清理

如果您不想继续学习与 ABAP SDK for Google Cloud 相关的其他 Codelab,请继续进行清理。

删除项目

  • 删除 Google Cloud 项目:
gcloud projects delete abap-sdk-poc

删除个别资源

  1. 删除计算实例:
gcloud compute instances delete abap-trial-docker
  1. 删除防火墙规则:
gcloud compute firewall-rules delete sapmachine
  1. 删除服务账号:
gcloud iam service-accounts delete \
    abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com