

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# K-Means 算法
<a name="k-means"></a>

K-means 是一种自主学习算法。它尝试在数据中寻找离散组，其中一个组的成员尽可能彼此相似，而与其他组的成员尽可能互不相同。您定义想要该算法用来确定相似性的属性。

Amazon SageMaker AI 使用网络规模 k 均值聚类算法的修改版本。与该算法的原始版本相比，Amazon A SageMaker I 使用的版本更为准确。与原始算法类似，它可扩展到大规模数据集并在训练时间方面加以改进。为此，Amazon A SageMaker I 使用的版本会流式传输训练数据的小批量（小批量、随机子集）。有关小批量 k-means 的更多信息，请参阅[网络规模 k-means 聚类](https://dl.acm.org/doi/10.1145/1772690.1772862)。

k-means 算法预计生成表格数据，其中的行代表您要聚类的观察结果，而列代表观察结果的属性。每行中的 *n* 属性表示 *n* 维空间的一个点。这些点之间的欧几里得距离表示相应观察结果的相似度。该算法将具有类似属性值的观察结果分为一组 (与这些观察结果对应的点彼此离得更近)。有关 k-means 在 Amazon A SageMaker I 中的工作原理的更多信息，请参阅[K-Means 聚类的工作原理](algo-kmeans-tech-notes.md)。

**Topics**
+ [K-Means 算法的输入/输出接口](#km-inputoutput)
+ [K-Means 算法的 EC2 实例建议](#km-instances)
+ [K-Means 示例笔记本](#kmeans-sample-notebooks)
+ [K-Means 聚类的工作原理](algo-kmeans-tech-notes.md)
+ [K-Means 超参数](k-means-api-config.md)
+ [优化 K-Means 模型](k-means-tuning.md)
+ [K-Means 响应格式](km-in-formats.md)

## K-Means 算法的输入/输出接口
<a name="km-inputoutput"></a>

在训练中，k-means 算法预计将在*训练* 通道（建议使用 `S3DataDistributionType=ShardedByS3Key`）中提供数据，并使用可选的*测试* 通道（建议使用 `S3DataDistributionType=FullyReplicated`）对数据计分。`recordIO-wrapped-protobuf` 和 `CSV` 格式均支持用于训练。您可以使用文件模式或管道模式，针对格式为 `recordIO-wrapped-protobuf` 或 `CSV` 的数据训练模型。

对于推理，支持 `text/csv`、`application/json` 和 `application/x-recordio-protobuf`。k-means 会为每个观察返回 `closest_cluster` 标签以及 `distance_to_cluster`。

有关输入和输出文件格式的更多信息，请参阅[K-Means 响应格式](km-in-formats.md)（对于推理）和[K-Means 示例笔记本](#kmeans-sample-notebooks)。k-means 算法不支持多实例学习，在这种学习中，训练集由标记的“包”组成，每个包就是一个未标记实例的集合。

## K-Means 算法的 EC2 实例建议
<a name="km-instances"></a>

建议在 CPU 实例上训练 k-means。您可以在 GPU 实例上进行训练，但 GPU 训练应限制为单 GPU 实例（例如 ml.g4dn.xlarge），因为每个实例只使用一个 GPU。k-means 算法支持使用 P2、P3、G4dn 和 G5 实例进行训练和推理。

## K-Means 示例笔记本
<a name="kmeans-sample-notebooks"></a>

有关使用 SageMaker AI K-means 算法按使用主成分分析确定的属性对美国各县人口进行细分的示例笔记本，请参阅[使用 Amazon A SageMaker I 分析美国人口普查数据以进行人口细分](https://sagemaker-examples.readthedocs.io/en/latest/introduction_to_applying_machine_learning/US-census_population_segmentation_PCA_Kmeans/sagemaker-countycensusclustering.html)。有关如何创建和访问可用于在 SageMaker AI 中运行示例的 Jupyter 笔记本实例的说明，请参阅。[Amazon SageMaker 笔记本实例](nbi.md)创建并打开笔记本实例后，选择 “**SageMaker AI 示例**” 选项卡以查看所有 SageMaker AI 示例的列表。要打开笔记本，请单击**使用** 选项卡，然后选择**创建副本**。

# K-Means 聚类的工作原理
<a name="algo-kmeans-tech-notes"></a>

K-means 是一种训练模型的算法，可将相似对象组合在一起。k-means 算法通过将输入数据集中的每个观察结果映射到 *n* 维空间的某个点 (其中 *n* 是观察结果的属性数量) 来完成此操作。例如，您的数据集可能包含某个特定位置的温度和湿度的观察结果，这些观察结果映射到 2 维空间的某些点 (*t, h*)。



**注意**  
聚类算法为自主型。在自主学习中，不使用可能与训练数据集中的对象相关联的标签。有关更多信息，请参阅 [无监督学习](algorithms-choose.md#algorithms-choose-unsupervised-learning)。

在 k-means 聚类中，每个聚类都有一个中心。在模型训练期间，k-means 算法使用对应于数据集中每个观察结果的点与聚类中心之间的距离作为聚类的基础。您选择要创建的聚类数量 (*k*)。

例如，假设您要创建一个可识别手写数字的模型，并且您选择 MNIST 数据集用于训练。该数据集提供了数千个手写数字 (0 到 9) 的图像。在本例中，您可以选择创建 10 个聚类，每个数字 (0、1、...、9) 一个聚类。作为模型训练的一部分，k-means 算法将输入图像划分为 10 个聚类。

MNIST 数据集中的每张图就是一个 28x28 像素的图像，总共 784 像素。每个图像对应于 784 维空间里的一个点，类似于 2 维空间的点 (x, y)。要查找某个点所属的聚类，k-means 算法会查找该点与所有聚类中心之间的距离。然后，它会选择最靠近中心的聚类作为图像所属的聚类。

**注意**  
Amazon SageMaker AI 使用算法的自定义版本，您可以选择通过指定额外的聚类中心 *(*K* = k\$1x) 来提高模型精度，而不是指定算法创建 k* 个集群。但是，该算法最终会将其减少为 *k* 个聚类。

在 SageMaker AI 中，您可以在创建训练作业时指定集群的数量。有关更多信息，请参阅 [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html)。在请求正文中，您添加 `HyperParameters` 字符串映射以指定 `k` 和 `extra_center_factor` 字符串。

以下是 k-means 如何在 SageMaker AI 中进行模型训练的摘要：

1. 它确定初始 *K* 个聚类中心。
**注意**  
在以下主题中，*K* 个聚类指的是 *k \$1 x*，您将在创建模型训练作业时指定其中的 *k* 和 *x*。

1. 它将迭代输入训练数据并重新计算聚类中心。

1. 这样可将生成的聚类数量减少至 *k* (如果数据科学家已在请求中指定创建 *k\$1x* 个聚类)。

下面几节也介绍了数据科学家可能指定的一些参数，这些参数用于配置模型训练作业以作为 `HyperParameters` 字符串映射的一部分。

**Topics**
+ [步骤 1：确定初始聚类中心](#kmeans-step1)
+ [步骤 2：迭代训练数据集并计算聚类中心](#kmeans-step2)
+ [步骤 3：将聚类数量从 *K* 减少至 *k*](#kmeans-step3)

## 步骤 1：确定初始聚类中心
<a name="kmeans-step1"></a>

在 SageMaker AI 中使用 k-means 时，初始聚类中心是在随机抽样的小批量中从观测值中选择的。选择下列策略之一来确定这些初始聚类中心的选择方式：
+ 随机方法 – 在您的输入数据集中随机选择 *K* 个观察数据作为聚类中心。例如，您可以选择一个指向 784 维空间的聚类中心 (对应于 MNIST 训练数据集中的任意 10 个图像)。
+ k-means\$1\$1 方法，其工作原理如下所示：

  1. 从一个聚类开始，并确定其中心。您从训练数据集中随机选择一个观察结果，并将对应于该观察结果的点用作聚类中心。例如，在 MNIST 数据集中，随机选择一个手写数字图像。然后，在 784 维空间中选择与该图像对应的点作为聚类中心。这是聚类中心 1。

  1. 确定聚类 2 的中心。从训练数据集的剩余观察结果中随机选择一个观察结果。选择一个不同于之前所选的观察结果。此观察结果对应于远离聚类中心 1 的一个点。以 MNIST 数据集为例，您需要执行以下操作：
     + 对于每张剩余的图像，找出相应点与聚类中心 1 之间的距离。对距离求平方，并分配一个与距离平方成正比的概率。这样一来，不同于之前所选的图像被选作聚类中心 2 的概率更高。
     + 基于上一步中分配的概率，随机选择一个镜像。对应于该图像的点便是聚类中心 2。

  1. 重复步骤 2 找到聚类中心 3。这次，找出剩余图像与聚类中心 2 之间的距离。

  1. 重复该过程，直到您拥有 *K* 个聚类中心。

要在 SageMaker AI 中训练模型，您需要创建一个训练作业。在请求中，您通过指定以下 `HyperParameters` 字符串映射来提供配置信息：
+ 要指定待创建的聚类数量，请添加 `k` 字符串。
+ 为提高准确性，请添加可选的 `extra_center_factor` 字符串。
+ 要指定希望用于确定初始聚类中心的策略，请添加 `init_method` 字符串并将其值设置为 `random` 或 `k-means++`。

有关 SageMaker AI k 均值估算器的更多信息，请参阅 Amaz [on Python SageMaker ](https://sagemaker.readthedocs.io/en/stable) S [DK 文档中的 k-](https://sagemaker.readthedocs.io/en/stable/algorithms/unsupervised/kmeans.html) means。

现在，您拥有一组初始聚类中心。

## 步骤 2：迭代训练数据集并计算聚类中心
<a name="kmeans-step2"></a>

您在上一步创建的聚类中心大多数是随机的，并且有一些关于训练数据集的考量。在此步骤中，您使用训练数据集将这些中心移向真正的聚类中心。该算法将迭代训练数据集，并重新计算 *K* 个聚类中心。

1. 从训练数据集读取小批量观察结果 (从所有记录中随机选择的小型子集)，然后执行以下操作。
**注意**  
创建模型训练作业时，请在 `mini_batch_size` 字符串映射的 `HyperParameters` 字符串中指定批次大小。

   1. 将小批量中的所有观察结果分配到其中一个具有最近聚类中心的聚类。

   1. 计算分配到每个聚类的观察结果的数量。然后，计算每个聚类分配的新点比例。

      例如，考虑以下聚类：

      聚类 c1 = 100 个之前分配的点。您在此步骤中从小批量添加了 25 个点。

      聚类 c2 = 150 个之前分配的点。您在此步骤中从小批量添加了 40 个点。

      聚类 c3 = 450 个之前分配的点。您在此步骤中从小批量添加了 5 个点。

      按如下方式计算分配给每个聚类的新点比例：

      ```
      p1 = proportion of points assigned to c1 = 25/(100+25)
      p2 = proportion of points assigned to c2 = 40/(150+40)
      p3 = proportion of points assigned to c3 = 5/(450+5)
      ```

   1. 计算添加到每个聚类的新点的中心：

      ```
      d1 = center of the new points added to cluster 1
      d2 = center of the new points added to cluster 2
      d3 = center of the new points added to cluster 3
      ```

   1. 按如下方式计算加权平均数，以查找更新后的聚类中心：

      ```
      Center of cluster 1 = ((1 - p1) * center of cluster 1) + (p1 * d1)
      Center of cluster 2 = ((1 - p2) * center of cluster 2) + (p2 * d2)
      Center of cluster 3 = ((1 - p3) * center of cluster 3) + (p3 * d3)
      ```

1. 读取下一个小批量，并重复步骤 1 以重新计算聚类中心。

1. 有关小批量 *k*-means 的更多信息，请参阅[网络规模 k-means 聚类](https://citeseerx.ist.psu.edu/document?repid=rep1type=pdf&doi=b452a856a3e3d4d37b1de837996aa6813bedfdcf)。

## 步骤 3：将聚类数量从 *K* 减少至 *k*
<a name="kmeans-step3"></a>

如果该算法创建了 *K* 个聚类 *(K = k\$1x)*，其中 *x* 大于 1，那么这会将 *K* 个聚类减少至 *k* 个聚类。(有关更多信息，请参阅之前讨论的 `extra_center_factor`。) 它通过对 *K* 个聚类中心应用 Lloyd 的方法（具有 `kmeans++` 初始化）来执行此操作。有关 Lloyd 的方法的更多信息，请参阅 [k-means 聚类](https://pdfs.semanticscholar.org/0074/4cb7cc9ccbbcdadbd5ff2f2fee6358427271.pdf)。

# K-Means 超参数
<a name="k-means-api-config"></a>

在 [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html) 请求中，您指定要使用的训练算法。您也可以将特定于算法的超参数指定为地图。 string-to-string下表列出了 Ama SageMaker zon AI 提供的 k 均值训练算法的超参数。有关 k-means 聚类工作原理的更多信息，请参阅[K-Means 聚类的工作原理](algo-kmeans-tech-notes.md)。


| 参数名称 | 说明 | 
| --- | --- | 
| feature\$1dim | 输入数据中的特征数。 **必填** 有效值：正整数  | 
| k |  所需聚类的数量。 **必填** 有效值：正整数  | 
| epochs | 对训练数据完成的扫描次数。 **可选** 有效值：正整数 默认值：1  | 
| eval\$1metrics | 一个用于报告模型分数的指标类型的 JSON 列表。对于均方差，允许的值为 `msd`；对于平方距离和，允许的值为 `ssd`。如果提供了测试数据，则会针对所请求的每个指标报告分数。 **可选** 有效值：`[\"msd\"]`、`[\"ssd\"]` 或 `[\"msd\",\"ssd\"]`。 默认值：`[\"msd\"]`  | 
| extra\$1center\$1factor | 该算法会在运行时创建 K 个中心 = `num_clusters` \$1 `extra_center_factor`，并在最终生成模型时将中心数量从 K 减少至 `k`。 **可选** 有效值：正整数或 `auto`。 默认值：`auto`  | 
| half\$1life\$1time\$1size | 用于确定计算聚类均值时赋予观察的权重。随着观察到的点越来越多，此权重呈指数倍衰减。当首次观察到一个点的情况下，在计算聚类均值时，它的权重为 1。选择指数衰减函数的衰减常数，以便在观察 `half_life_time_size` 个点后，其权重为 1/2。如果设置为 0，则没有衰减。 **可选** 有效值：非负整数 默认值：0  | 
| init\$1method | 算法选择初始聚类中心的方法。标准 k-means 方法会随机选择这些方法。备用 k-means\$1\$1 方法会随机选择第一个聚类中心。然后，它通过加权中心选择来扩展其余初始聚类的位置，其概率分布与其余数据点到现有中心的距离的平方成比例。 **可选** 有效值：`random` 或 `kmeans++`。 默认值：`random`  | 
| local\$1lloyd\$1init\$1method | 用于构建包含 `k` 个中心的最终模型的劳埃德最大期望算法 (EM) 过程的初始化方法。 **可选** 有效值：`random` 或 `kmeans++`。 默认值：`kmeans++`  | 
| local\$1lloyd\$1max\$1iter | 用于构建包含 `k` 个中心的最终模型的劳埃德最大期望算法 (EM) 过程的最大迭代次数。 **可选** 有效值：正整数 默认值：300  | 
| local\$1lloyd\$1num\$1trials | 在构建包含 `k` 个中心的最终模型时，运行具有最小损失的劳埃德最大期望算法 (EM) 过程的次数。 **可选** 有效值：正整数或 `auto`。 默认值：`auto`  | 
| local\$1lloyd\$1tol | 用于构建包含 `k` 个中心的最终模型的劳埃德最大期望算法 (EM) 过程的提前停止损失变化的容忍度。 **可选** 有效值：浮点值。范围为 [0, 1]。 默认值：0.0001  | 
| mini\$1batch\$1size | 用于数据迭代器的每个小批量的观察次数。 **可选** 有效值：正整数 默认值：5000  | 

# 优化 K-Means 模型
<a name="k-means-tuning"></a>

*自动模型优化*（也称作超参数优化）通过运行很多在数据集上测试一系列超参数的作业来查找模型的最佳版本。您可以选择可优化超参数、每个超参数的值范围和一个目标指标。您可以从算法计算的指标中选择目标指标。自动模型优化将搜索所选超参数以找到导致优化目标指标的模型的值组合。

Amazon SageMaker AI k-means 算法是一种无监督算法，它将数据分组到成员尽可能相似的集群中。因为它是非自主型的，所以不使用可优化超参数的验证数据集。但是，它确实接受测试数据集并发出指标，这些指标取决于每次训练结束时数据点与最终聚类中心之间的距离平方值。要找到报告有关测试数据集的最紧密聚类的模型，可以使用超参数优化作业。聚类可优化其成员的相似性。

有关模型优化的更多信息，请参阅[使用 SageMaker AI 自动调整模型](automatic-model-tuning.md)。

## K-Means 算法计算的指标
<a name="km-metrics"></a>

k-means 算法在训练期间计算以下指标。在优化模型时，选择这些指标之一作为目标指标。


| 指标名称 | 说明 | 优化方向 | 
| --- | --- | --- | 
| test:msd | 测试集中每个记录与模型最近中心之间的均方距离。 | 最小化 | 
| test:ssd | 测试集中每个记录与模型最近中心之间的平方距离总和。 | 最小化 | 



## 可优化的 K-Means 超参数
<a name="km-tunable-hyperparameters"></a>

使用以下超参数调整 SageMaker Amazon AI k-means 模型。对 k-means 目标指标影响最大的超参数为：`mini_batch_size`、`extra_center_factor` 和 `init_method`。优化超参数 `epochs` 通常会得到较小的改进。


| 参数名称 | 参数类型 | 建议的范围 | 
| --- | --- | --- | 
| epochs | IntegerParameterRanges | MinValue: 1，:10 MaxValue | 
| extra\$1center\$1factor | IntegerParameterRanges | MinValue: 4, MaxValue :10 | 
| init\$1method | CategoricalParameterRanges | ['kmeans\$1\$1', 'random'] | 
| mini\$1batch\$1size | IntegerParameterRanges | MinValue: 3000, MaxValue :15000 | 

# K-Means 响应格式
<a name="km-in-formats"></a>

所有 SageMaker AI 内置算法都遵循通用[数据格式-推理中描述的通用输入推理格式](https://docs.aws.amazon.com/sagemaker/latest/dg/cdf-inference.html)。本主题包含 A SageMaker I k-means 算法的可用输出格式列表。

## JSON 响应格式
<a name="km-json"></a>

```
{
    "predictions": [
        {
            "closest_cluster": 1.0,
            "distance_to_cluster": 3.0,
        },
        {
            "closest_cluster": 2.0,
            "distance_to_cluster": 5.0,
        },

        ....
    ]
}
```

## JSONLINES 响应格式
<a name="km-jsonlines"></a>

```
{"closest_cluster": 1.0, "distance_to_cluster": 3.0}
{"closest_cluster": 2.0, "distance_to_cluster": 5.0}
```

## RECORDIO 响应格式
<a name="km-recordio"></a>

```
[
    Record = {
        features = {},
        label = {
            'closest_cluster': {
                keys: [],
                values: [1.0, 2.0]  # float32
            },
            'distance_to_cluster': {
                keys: [],
                values: [3.0, 5.0]  # float32
            },
        }
    }
]
```

## CSV 响应格式
<a name="km-csv"></a>

每行中的第一个值对应于 `closest_cluster`。

每行中的第二个值对应于 `distance_to_cluster`。

```
1.0,3.0
2.0,5.0
```