

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 教程：构建多类别分类模型
<a name="tutorial_multi-class_classification"></a>

在本教程中，您使用 Amazon Redshift ML 创建机器学习模型来解决多类别分类问题。多类别分类算法将数据点划分为三个或更多类别中的一个类别。然后，您可以使用 CREATE MODEL 命令生成的 SQL 函数来实施查询。

您可以使用 CREATE MODEL 命令导出训练数据、训练模型、导入模型以及准备 Amazon Redshift 预测函数。使用 CREATE MODEL 操作将训练数据指定为表或 SELECT 语句。

要继续学习本教程，您可以使用公用数据集[电子商务销售额预测](https://www.kaggle.com/allunia/e-commerce-sales-forecast)，其中包括一家英国在线零售商的销售数据。您生成的模型将为一个特殊的客户忠诚度计划找出最活跃的客户。通过多类别分类，您可以使用该模型预测客户在 13 个月期间内将有多少个月处于活跃状态。预测函数会指定据预测将活跃 7 个月或更多月数的客户，以便将这些客户加入该计划。

## 使用案例示例
<a name="tutorial_multi-class_classification_tasks"></a>

您可以使用 Amazon Redshift ML 解决其他多类别分类问题，例如预测某个产品系列中最畅销的商品。您还可以预测图像中包含哪些水果，例如选择苹果、梨或橘子。

**任务**：
+ 先决条件
+ 步骤 1：将数据从 Amazon S3 加载到 Amazon Redshift
+ 步骤 2：创建机器学习模型
+ 步骤 3：使用模型执行预测

## 先决条件
<a name="tutorial_multi-class_classification_prereqs"></a>

要完成此教程，必须完成 Amazon Redshift ML 的[管理设置](https://docs.aws.amazon.com/redshift/latest/dg/admin-setup.html)。

## 步骤 1：将数据从 Amazon S3 加载到 Amazon Redshift
<a name="tutorial_multi-class_classification_step_load"></a>

使用 [Amazon Redshift 查询器 v2](https://docs.aws.amazon.com/redshift/latest/mgmt/query-editor-v2-using.html) 运行以下查询。这些查询会将示例数据加载到 Amazon Redshift 中。

1. 下面的查询创建一个名为 `ecommerce_sales` 的表。

   ```
   CREATE TABLE IF NOT EXISTS ecommerce_sales (
       invoiceno VARCHAR(30),
       stockcode VARCHAR(30),
       description VARCHAR(60),
       quantity DOUBLE PRECISION,
       invoicedate VARCHAR(30),
       unitprice DOUBLE PRECISION,
       customerid BIGINT,
       country VARCHAR(25)
   );
   ```

1. 以下查询将[电子商务销售预测数据集](https://www.kaggle.com/allunia/e-commerce-sales-forecast)中的示例数据复制到 `ecommerce_sales` 表中。

   ```
   COPY ecommerce_sales
   FROM
       's3://redshift-ml-multiclass/ecommerce_data.txt' 
   IAM_ROLE default 
   DELIMITER '\t' 
   IGNOREHEADER 1 
   REGION 'us-east-1' 
   MAXERROR 100;
   ```

### 拆分数据
<a name="tutorial_multi-class_classification_split_data"></a>

当您在 Amazon Redshift ML 中创建模型时，SageMaker AI 会自动将您的数据拆分为训练集和测试集，以便 SageMaker AI 可以确定模型的准确性。通过在此步骤中手动拆分数据，您将能够通过分配额外的预测集来验证模型的准确性。

使用以下 SQL 语句将数据拆分为三个用于训练、验证和预测的集。

```
--creates table with all data
CREATE TABLE ecommerce_sales_data AS (
    SELECT
        t1.stockcode,
        t1.description,
        t1.invoicedate,
        t1.customerid,
        t1.country,
        t1.sales_amt,
        CAST(RANDOM() * 100 AS INT) AS data_group_id
    FROM
        (
            SELECT
                stockcode,
                description,
                invoicedate,
                customerid,
                country,
                SUM(quantity * unitprice) AS sales_amt
            FROM
                ecommerce_sales
            GROUP BY
                1,
                2,
                3,
                4,
                5
        ) t1
);

--creates training set
CREATE TABLE ecommerce_sales_training AS (
    SELECT
        a.customerid,
        a.country,
        a.stockcode,
        a.description,
        a.invoicedate,
        a.sales_amt,
        (b.nbr_months_active) AS nbr_months_active
    FROM
        ecommerce_sales_data a
        INNER JOIN (
            SELECT
                customerid,
                COUNT(
                    DISTINCT(
                        DATE_PART(y, CAST(invoicedate AS DATE)) || '-' || LPAD(
                            DATE_PART(mon, CAST(invoicedate AS DATE)),
                            2,
                            '00'
                        )
                    )
                ) AS nbr_months_active
            FROM
                ecommerce_sales_data
            GROUP BY
                1
        ) b ON a.customerid = b.customerid
    WHERE
        a.data_group_id < 80
);

--creates validation set
CREATE TABLE ecommerce_sales_validation AS (
    SELECT
        a.customerid,
        a.country,
        a.stockcode,
        a.description,
        a.invoicedate,
        a.sales_amt,
        (b.nbr_months_active) AS nbr_months_active
    FROM
        ecommerce_sales_data a
        INNER JOIN (
            SELECT
                customerid,
                COUNT(
                    DISTINCT(
                        DATE_PART(y, CAST(invoicedate AS DATE)) || '-' || LPAD(
                            DATE_PART(mon, CAST(invoicedate AS DATE)),
                            2,
                            '00'
                        )
                    )
                ) AS nbr_months_active
            FROM
                ecommerce_sales_data
            GROUP BY
                1
        ) b ON a.customerid = b.customerid
    WHERE
        a.data_group_id BETWEEN 80
        AND 90
);

--creates prediction set
CREATE TABLE ecommerce_sales_prediction AS (
    SELECT
        customerid,
        country,
        stockcode,
        description,
        invoicedate,
        sales_amt
    FROM
        ecommerce_sales_data
    WHERE
        data_group_id > 90);
```

## 步骤 2：创建机器学习模型
<a name="tutorial_multi-class_classification_step_create_model"></a>

在此步骤中，您使用 CREATE MODEL 语句通过多类别分类来创建机器学习模型。

以下查询使用 CREATE MODEL 操作通过训练集来创建多类别分类模型。将 amzn-s3-demo-bucket 替换为您自己的 Amazon S3 存储桶。

```
CREATE MODEL ecommerce_customer_activity
FROM
    (
        SELECT
            customerid,
            country,
            stockcode,
            description,
            invoicedate,
            sales_amt,
            nbr_months_active
        FROM
            ecommerce_sales_training
    ) TARGET nbr_months_active FUNCTION predict_customer_activity IAM_ROLE default PROBLEM_TYPE MULTICLASS_CLASSIFICATION SETTINGS (
        S3_BUCKET 'amzn-s3-demo-bucket',
        S3_GARBAGE_COLLECT OFF
    );
```

在此查询中，您可以将问题类型指定为 `Multiclass_Classification`。您为模型预测的目标是 `nbr_months_active`。当 SageMaker AI 完成模型训练后，它会创建 `predict_customer_activity` 函数，您将使用该函数在 Amazon Redshift 中进行预测。

### 显示模型训练的状态（可选）
<a name="tutorial_multi-class_classification_show_status"></a>

您可以使用 SHOW MODEL 命令来了解模型何时准备就绪。

使用以下查询返回模型的各种指标，包括模型状态和准确性。

```
SHOW MODEL ecommerce_customer_activity;
```

当模型准备就绪时，上一个操作的输出应显示 `Model State` 为 `Ready`。以下是 SHOW MODEL 操作的输出示例。

```
+--------------------------+-----------------------------------------------------------------------------------------------+
|        Model Name        |                                  ecommerce_customer_activity                                  |
+--------------------------+-----------------------------------------------------------------------------------------------+
|       Schema Name        |                                            public                                             |
|          Owner           |                                            awsuser                                            |
|      Creation Time       |                                   Fri, 17.06.2022 19:02:15                                    |
|       Model State        |                                             READY                                             |
|   Training Job Status    |                                  MaxAutoMLJobRuntimeReached                                   |
|   validation:accuracy    |                                           0.991280                                            |
|      Estimated Cost      |                                           7.897689                                            |
|                          |                                                                                               |
|      TRAINING DATA:      |                                                                                               |
|          Query           | SELECT CUSTOMERID, COUNTRY, STOCKCODE, DESCRIPTION, INVOICEDATE, SALES_AMT, NBR_MONTHS_ACTIVE |
|                          |                                 FROM ECOMMERCE_SALES_TRAINING                                 |
|      Target Column       |                                       NBR_MONTHS_ACTIVE                                       |
|                          |                                                                                               |
|       PARAMETERS:        |                                                                                               |
|        Model Type        |                                            xgboost                                            |
|       Problem Type       |                                   MulticlassClassification                                    |
|        Objective         |                                           Accuracy                                            |
|     AutoML Job Name      |                                redshiftml-20220617190215268770                                |
|      Function Name       |                                   predict_customer_activity                                   |
|   Function Parameters    |                customerid country stockcode description invoicedate sales_amt                 |
| Function Parameter Types |                          int8 varchar varchar varchar varchar float8                          |
|         IAM Role         |                                     default-aws-iam-role                                      |
|        S3 Bucket         |                                         amzn-s3-demo-bucket                                    |
|       Max Runtime        |                                             5400                                              |
+--------------------------+-----------------------------------------------------------------------------------------------+
```

## 步骤 3：使用模型执行预测
<a name="tutorial_multi-class_classification_step_perform_predictions"></a>

以下查询显示哪些客户有资格加入您的客户忠诚度计划。如果模型预测客户将活跃至少七个月，则模型将选择该客户加入忠诚度计划。

```
SELECT
    customerid,
    predict_customer_activity(
        customerid,
        country,
        stockcode,
        description,
        invoicedate,
        sales_amt
    ) AS predicted_months_active
FROM
    ecommerce_sales_prediction
WHERE
    predicted_months_active >= 7
GROUP BY
    1,
    2
LIMIT
    10;
```

### 对验证数据运行预测查询（可选）
<a name="tutorial_multi-class_classification_run_validation_prediction"></a>

针对验证数据运行以下预测查询，以查看模型的准确性级别。

```
SELECT
    CAST(SUM(t1.match) AS decimal(7, 2)) AS predicted_matches,
    CAST(SUM(t1.nonmatch) AS decimal(7, 2)) AS predicted_non_matches,
    CAST(SUM(t1.match + t1.nonmatch) AS decimal(7, 2)) AS total_predictions,
    predicted_matches / total_predictions AS pct_accuracy
FROM
    (
        SELECT
            customerid,
            country,
            stockcode,
            description,
            invoicedate,
            sales_amt,
            nbr_months_active,
            predict_customer_activity(
                customerid,
                country,
                stockcode,
                description,
                invoicedate,
                sales_amt
            ) AS predicted_months_active,
            CASE
                WHEN nbr_months_active = predicted_months_active THEN 1
                ELSE 0
            END AS match,
            CASE
                WHEN nbr_months_active <> predicted_months_active THEN 1
                ELSE 0
            END AS nonmatch
        FROM
            ecommerce_sales_validation
    )t1;
```

### 预测有多少客户错过了加入机会（可选）
<a name="tutorial_multi-class_classification_run_missed_entries"></a>

以下查询比较据预测仅活跃 5 个月或 6 个月的客户数量。该模型预测这些客户将错失忠诚度计划。然后，此查询将几乎可以不错过该计划的数量与预测有资格加入忠诚度计划的数量进行比较。此查询可用于决定是否降低忠诚度计划的门槛。您还可以确定是否有大量客户据预测几乎可以不错过该计划。然后，您可以鼓励这些客户增加其活动以获得忠诚度计划会员资格。

```
SELECT
    predict_customer_activity(
        customerid,
        country,
        stockcode,
        description,
        invoicedate,
        sales_amt
    ) AS predicted_months_active,
    COUNT(customerid)
FROM
    ecommerce_sales_prediction
WHERE
    predicted_months_active BETWEEN 5 AND 6
GROUP BY
    1
ORDER BY
    1 ASC
LIMIT
    10)
UNION
(SELECT
      NULL AS predicted_months_active,
    COUNT (customerid)
FROM 
    ecommerce_sales_prediction
WHERE
    predict_customer_activity(
        customerid,
        country,
        stockcode,
        description,
        invoicedate,
        sales_amt
    ) >=7);
```

## 相关主题
<a name="tutorial_multi-class_classification_related_topics"></a>

有关 Amazon Redshift ML 的更多信息，请参阅以下文档：
+ [使用 Amazon Redshift ML 的成本](https://docs.aws.amazon.com/redshift/latest/dg/cost.html)
+ [CREATE MODEL 操作](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_MODEL.html)
+ [EXPLAIN\$1MODEL 函数](https://docs.aws.amazon.com/redshift/latest/dg/r_explain_model_function.html)

有关机器学习的更多信息，请参阅以下文档：
+ [机器学习概览](https://docs.aws.amazon.com/redshift/latest/dg/machine_learning_overview.html)
+ [面向新手和专家的机器学习](https://docs.aws.amazon.com/redshift/latest/dg/novice_expert.html)
+ [机器学习预测的公平性和模型可解释性是什么？](https://docs.aws.amazon.com/sagemaker/latest/dg/clarify-fairness-and-explainability.html)