

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

# Neptune ML 中的特征编码
<a name="machine-learning-feature-encoding"></a>

属性值有不同的格式和数据类型。为了在机器学习中获得良好的性能，务必将这些值转换为称为*特征*的数字编码。

作为数据导出和数据处理步骤的一部分，Neptune ML 使用此处描述的特征编码技术来执行特征提取和编码。

**注意**  
如果您计划在自定义模型实现中实现自己的特征编码，则可以在数据预处理阶段，通过选择 `none` 作为特征编码类型来禁用自动特征编码。然后，在该节点或边缘属性上不会进行任何特征编码，而是解析原始属性值并将其保存在字典中。数据预处理仍会根据导出的数据集创建 DGL 图形，但是构造的 DGL 图形没有用于训练的预处理特征。  
仅当您计划在自定义模型训练过程中执行自定义特征编码时，才应使用此选项。有关详细信息，请参阅[Neptune ML 中的自定义模型](machine-learning-custom-models.md)。

## Neptune ML 中的分类特征
<a name="machine-learning-categorical-features"></a>

可以从可能值的固定列表中提取一个或多个不同值的属性是分类特征。在 Neptune ML 中，分类特征使用[独热码编码](https://en.wikipedia.org/wiki/One-hot)进行编码。以下示例显示了不同食物的属性名称是如何根据其类别进行独热码编码的：

```
    Food        Veg.   Meat   Fruit    Encoding
   ---------    ----   ----   -----    --------
    Apple         0      0      1         001
    Chicken       0      1      0         010
    Broccoli      1      0      0         100
```

**注意**  
任何类别特征中的最大类别数为 100。如果一个属性的值类别超过 100 个，则只有其中最常见的 99 个被归入不同的类别，其余的则归入名为 `OTHER` 的特殊类别。

## Neptune ML 中的数值特征
<a name="machine-learning-numerical-features"></a>

在 Neptune ML 中，任何值为实数的属性都可以编码为数值特征。数值特征使用浮点数进行编码。

您可以指定在对数值特征进行编码时要使用的数据规范化方法，如下所示：`"norm": "normalization technique"`。支持以下规范化技术：
+ **“none”**- 在编码过程中不对数值进行规范化。
+ **“min-max”**– 通过从每个值中减去最小值，然后将其除以最大值和最小值之间的差值来规范化每个值。
+ **“standard”**- 通过将每个值除以所有值的总和来对其进行规范化。

## Neptune ML 中的桶数值特征
<a name="machine-learning-bucket_numerical-features"></a>

与其使用原始数字表示数值属性，不如将数值压缩成类别。例如，您可以将人们的年龄分为几个类别，例如儿童 (0-20)、年轻人 (20-40)、中年人 (40-60) 和老年人（从 60 岁起）。使用这些数值桶，您可以将数值属性转换为一种分类特征。

在 Neptune ML 中，您可以将数值属性编码为桶数值特征，您必须提供两项内容：
+ 以 ` "range": [a, b] ` 形式表示的数值范围，其中 `a` 和 `b` 是整数。
+ 桶计数，形式为 ` "bucket_cnt": c `，其中 `c` 是桶的数量，也是一个整数。

然后，Neptune ML 将每个桶的大小计算为 ` ( b - a ) / c `，并将每个数值编码为它归入的任何桶的数量。任何小于 `a` 的值都被视为属于第一个桶，任何大于 `b` 的值都被视为属于最后一个桶。

您也可以选择通过指定滑动窗口大小将数值归入多个桶中，如下所示：` "slide_window_size": s `，其中 `s` 是一个数字。然后，Neptune ML 将属性的每个数值 `v` 转换为从 ` v - s/2 ` 到 ` v + s/2 ` 的范围，并将值 `v` 分配给该范围涵盖的每个桶。

最后，您还可以选择提供一种填充数值特征和桶数值特征的缺失值的方法。为此，您可以使用 ` "imputer": "imputation technique "`，其中插补技术为 `"mean"`、`"median"` 或 `"most-frequent"` 之一。如果不指定插补器，则缺失值可能会导致处理停止。

## Neptune ML 中的文本特征编码
<a name="machine-learning-text-features"></a>

对于自由格式文本，Neptune ML 可以使用几种不同的模型将属性值字符串中的令牌序列转换为固定大小的实值向量：
+ [`text_fasttext`](#machine-learning-fasttext-features) – 使用 [fastText](https://fasttext.cc/) 编码。对于使用 fastText 支持的五种语言中的一种且仅一种的特征，推荐使用这种编码。
+ [`text_sbert`](#machine-learning-sbert-features)– 使用[句子 BERT](https://www.sbert.net/docs/pretrained_models.html#sentence-embedding-models) (SBERT) 编码模型。对于 `text_fasttext` 不支持的文本，建议使用这种编码。
+ [`text_word2vec`](#machine-learning-word2vec-features)– 使用最初由 [Google](https://code.google.com/archive/p/word2vec/) 发布的 [Word2Vec](https://wikipedia.org/wiki/Word2vec) 算法对文本进行编码。Word2Vec 仅支持英语。
+ [`text_tfidf`](#machine-learning-tfidf-features)– 使用[术语频率 - 反向文档频率](https://wikipedia.org/wiki/Tf-idf) (TF-IDF) 向量器对文本进行编码。TF-IDF 编码支持其它编码不支持的统计特征。

### Neptune ML 中文本属性值的 *fastText* 编码
<a name="machine-learning-fasttext-features"></a>

Neptune ML 可以使用 [fastText](https://fasttext.cc/) 模型将文本属性值转换为固定大小的实值向量。以下是 fastText 支持的五种语言中任意一种的文本属性值的推荐编码方法：
+ `en`（英语）
+ `zh`（中文）
+ `hi`（印地语）
+ `es`（西班牙语）
+ `fr`（法语）

请注意，fastText 无法处理包含多种语言字词的句子。

`text_fasttext` 方法可以选择使用一个 `max_length` 字段，该字段指定要编码的文本属性值中的最大令牌数，之后字符串将被截断。当文本属性值包含长字符串时，这可以提高性能，因为如果未指定 `max_length`，则无论字符串长度如何，fastText 都会对所有令牌进行编码。

此示例指定法语电影标题使用 fastText 进行编码：

```
{
    "file_name" : "nodes/movie.csv",
    "separator" : ",",
    "node" : ["~id", "movie"],
    "features" : [
      {
        "feature": ["title", "title", "text_fasttext"],
        "language": "fr",
        "max_length": 1024
      }
    ]
  }
```

### Neptune ML 中文本特征的句子 BERT (SBERT) 编码
<a name="machine-learning-sbert-features"></a>

Neptune ML 可以使用[句子 BERT](https://www.sbert.net/docs/pretrained_models.html#sentence-embedding-models) (SBERT) 模型将字符串属性值中的令牌序列转换为固定大小的实值向量。Neptune 支持两种 SBERT 方法：`text_sbert128`（如果您只指定 `text_sbert`，则这是默认方法）和 `text_sbert512`。两者的区别在于编码后的文本属性值字符串的最大长度。`text_sbert128` 编码在编码 128 个令牌后截断文本字符串，而 `text_sbert512` 在编码 512 个令牌后截断文本字符串。因此，`text_sbert512` 所需的处理时间比 `text_sbert128` 更多。两种方法都慢于 `text_fasttext`。

SBERT 编码是多语言的，因此，无需为正在编码的属性值文本指定语言。SBERT 支持多种语言，并且可以对包含多种语言的句子进行编码。如果您使用 fastText 不支持的一种或多种语言对包含文本的属性值进行编码，则推荐使用 SBERT 编码方法。

以下示例指定将电影标题编码为 SBERT，最多 128 个令牌：

```
{
    "file_name" : "nodes/movie.csv",
    "separator" : ",",
    "node" : ["~id", "movie"],
    "features" : [
      { "feature": ["title", "title", "text_sbert128"] }
    ]
  }
```

### Neptune ML 中文本特征的 Word2Vec 编码
<a name="machine-learning-word2vec-features"></a>

Neptune ML 可以将字符串属性值编码为 Word2Vec 特征（[Word2Vec 算法](https://wikipedia.org/wiki/Word2vec)最初由 [Google](https://code.google.com/archive/p/word2vec/) 发布）。`text_word2vec` 方法使用 [spaCy 训练模型](https://spacy.io/models)之一将字符串中的令牌编码为密集向量。这仅支持使用 [en\$1core\$1web\$1lg](https://spacy.io/models/en#en_core_web_lg) 模型的“英语”语言。

以下示例指定电影标题使用 Word2Vec 进行编码：

```
{
    "file_name" : "nodes/movie.csv",
    "separator" : ",",
    "node" : ["~id", "movie"],
    "features" : [
      {
        "feature": ["title", "title", "text_word2vec"],
        "language": "en_core_web_lg"
      }
    ]
  }
```

请注意，语言字段是可选的，因为英语 `en_core_web_lg` 模型是 Neptune 唯一支持的模型。

### Neptune ML 中文本特征的 TF-IDF 编码
<a name="machine-learning-tfidf-features"></a>

Neptune ML 可以将文本属性值编码为 `text_tfidf` 特征。这种编码使用[术语频率 - 反向文档频率](https://wikipedia.org/wiki/Tf-idf) (TF-IDF) 向量器将文本中的字词序列转换为数字向量，然后进行降维操作。

[TF-IDF](https://en.wikipedia.org/wiki/Tf%E2%80%93idf)（术语频率 – 反向文档频率）是一个数值，旨在衡量字词在文档集中的重要性。它的计算方法是将字词在给定属性值中出现的次数除以该词出现在此类属性值中的总次数。

例如，如果“kiss”一词在给定的电影标题中出现两次（比如“kiss kiss bang bang”），并且“kiss”总共出现在 4 部电影的标题中，那么“kiss kiss bang bang”标题中“kiss”的 TF-IDF 值将为 ` 2 / 4 `。

最初创建的向量具有 ***d*** 个维度，其中 ***d*** 是该类型的所有属性值中唯一术语的数量。降维操作使用随机稀疏投影将该数字减少到最大值 100。然后，通过合并图形中的所有 `text_tfidf` 特征来生成图形的词汇表。

您可以通过多种方式控制 TF-IDF 向量器：
+ **`max_features`** – 使用 `max_features` 参数，您可以将 `text_tfidf` 特征中的术语数量限制为最常见的术语。例如，如果您将 `max_features` 设置为 100，则仅包括前 100 个最常用的术语。如果您未显式设置 `max_features`，则其默认值为 5000。
+ **`min_df`** – 使用 `min_df` 参数，您可以将 `text_tfidf` 特征中的术语数量限制为至少具有指定文档频率的术语数量。例如，如果您将 `min_df` 设置为 5，则仅使用出现在至少 5 个不同属性值中的术语。如果您未显式设置 `min_df`，则其默认值为 2。
+ **`ngram_range`** – `ngram_range` 参数确定将哪些字词组合视为术语。例如，如果您将 `ngram_range` 设置为 `[2, 4]`，则可以在“kiss kiss bang bang”标题中找到以下 6 个术语：
  + *2 个字词的术语*：“kiss kiss”、“kiss bang”和“bang bang”。
  + *3 个字词的术语*：“kiss kiss bang”和“kiss bang bang”。
  + *4 个字词的术语*：“kiss kiss bang bang”。

  `ngram_range` 的默认设置是 `[1, 1]`。

## Neptune ML 中的日期时间特征
<a name="machine-learning-datetime-features"></a>

Neptune ML 可以通过将部分 `datetime` 属性值编码为[独热码数组](https://en.wikipedia.org/wiki/One-hot)来将它们转换为分类特征。使用 `datetime_parts` 参数指定要编码的以下一个或多个部分：`["year", "month", "weekday", "hour"]`。如果未设置 `datetime_parts`，则默认情况下，所有四个部分均编码。

例如，如果日期时间值的范围跨越 2010 年到 2012 年，则日期时间条目 `2011-04-22 01:16:34` 的四个部分如下所示：
+ **year** – `[0, 1, 0]`。

  由于这段时间跨度只有 3 年（2010 年、2011 年和 2012 年），因此独热码数组有三个条目，每年一个。
+ **month** – `[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]`。

  在这里，独热码数组对于一年中的每个月份有一个条目。
+ **weekday** – `[0, 0, 0, 0, 1, 0, 0]`。

  ISO 8601 标准规定，星期一是一周的第一天，由于 2011 年 4 月 22 日是星期五，因此相应的独热码工作日数组在第五个位置是热的。
+ **hour** – `[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`。

  凌晨 1 点是在具有 24 个成员的独热码数组中设置的。

月份中的某天、分钟和秒没有明确编码。

如果所讨论的总 `datetime` 范围仅包括一年内的日期，则不对 `year` 数组进行编码。

您可以使用 `imputer` 参数和一种可用于数值特征的策略来指定填补缺失 `datetime` 值的插补策略。

## Neptune ML 中的自动特征编码
<a name="machine-learning-auto-encoding"></a>

您可以将 `auto` 设置为特征编码方法，而不必手动指定要用于图形中属性的特征编码方法。然后，Neptune ML 尝试根据每个属性的底层数据类型推理其最佳特征编码。

以下是 Neptune ML 在选择相应的特征编码时使用的一些启发式方法：
+ 如果该属性只有数值并且可以转换为数值数据类型，那么 Neptune ML 通常将其编码为数值。但是，如果该属性的唯一值数量小于值总数的 10%，并且这些唯一值的基数小于 100，则 Neptune ML 将使用分类编码。
+ 如果可以将属性值强制转换为 `datetime` 类型，则 Neptune ML 将它们编码为 `datetime` 特征。
+ 如果可以将属性值强制为布尔值（1/0 或 True/False），那么 Neptune ML 将使用类别编码。
+ 如果属性是一个字符串，其值的 10% 以上是唯一的，并且每个值的平均令牌数大于或等于 3，则 Neptune ML 推断属性类型为文本，并自动检测所使用的语言。如果检测到的语言是 [fastText](#machine-learning-fasttext-features) 支持的语言之一，即英语、中文、印地语、西班牙语和法语，则 Neptune ML 使用 `text_fasttext` 对文本进行编码。否则，Neptune ML 使用 [`text_sbert`](#machine-learning-sbert-features)。
+ 如果该属性是未归类为文本特征的字符串，则 Neptune ML 会将其假定为分类特征并使用类别编码。
+ 如果每个节点对推理为类别特征的属性都有其自己的唯一值，则 Neptune ML 会将该属性从训练图形中删除，因为它可能是一个无法提供学习信息的 ID。
+ 如果已知该属性包含有效的 Neptune 分隔符，例如分号 (";")，则 Neptune ML 只能将该属性视为 `MultiNumerical` 或 `MultiCategorical`。
  + Neptune ML 首先尝试将值编码为数字特征。如果成功，Neptune ML 将使用数字编码来创建数字向量特征。
  + 否则，Neptune ML 会将这些值编码为多类别。
+ 如果 Neptune ML 无法推理属性值的数据类型，则 Neptune ML 会从训练图形中删除该属性。