

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

# Neptune ML 中的 Gremlin 节点分类查询
<a name="machine-learning-gremlin-vertex-classification-queries"></a>

对于 Neptune ML 中的 Gremlin 节点分类：
+ 模型是在顶点的一个属性上训练的。此属性的唯一值集合称为一组节点类，或者简称为类。
+ 可以从节点分类模型中推理顶点属性的节点类或分类属性值。当此属性尚未附加到顶点时，这很有用。
+ 要从节点分类模型中获取一个或多个类，您需要使用带有谓词 `Neptune#ml.classification` 的 `with()` 步骤来配置 `properties()` 步骤。如果这些是顶点属性，则输出格式与您期望的格式类似。

**注意**  
节点分类仅适用于字符串属性值。这意味着不支持诸如 `0` 或 `1` 之类的数值属性值，但支持等同的字符串 `"0"` 和 `"1"`。同样，布尔属性值 `true` 和 `false` 不起作用，但 `"true"` 和 `"false"` 起作用。

以下是一个示例节点分类查询：

```
g.with( "Neptune#ml.endpoint","node-classification-movie-lens-endpoint" )
 .with( "Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role" )
 .with( "Neptune#ml.limit", 2 )
 .with( "Neptune#ml.threshold", 0.5D )
 .V( "movie_1", "movie_2", "movie_3" )
 .properties("genre").with("Neptune#ml.classification")
```

此查询的输出如下所示：

```
==>vp[genre->Action]
==>vp[genre->Crime]
==>vp[genre->Comedy]
```

在上面的查询中，`V()` 和 `properties()` 步骤的使用方式如下：

`V()` 步骤包含要从节点分类模型中获取类的一组顶点：

```
 .V( "movie_1", "movie_2", "movie_3" )
```

`properties()` 步骤包含训练模型所依据的键，并具有 `.with("Neptune#ml.classification")` 以表明这是节点分类机器学习推理查询。

目前不支持在 `properties().with("Neptune#ml.classification")` 步骤中使用多个属性键。例如，以下查询会导致异常：

```
g.with("Neptune#ml.endpoint", "node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" )
 .properties("genre", "other_label").with("Neptune#ml.classification")
```

有关具体的错误消息，请参阅 [Neptune ML 异常列表](machine-learning-gremlin-exceptions.md)。

`properties().with("Neptune#ml.classification")` 步骤可以与以下任何步骤结合使用：
+ `value()`
+ `value().is()`
+ `hasValue()`
+ `has(value,"")`
+ `key()`
+ `key().is()`
+ `hasKey()`
+ `has(key,"")`
+ `path()`

## 其它节点分类查询
<a name="machine-learning-gremlin-node-class-other-queries"></a>

如果推理端点和相应的 IAM 角色均已保存在数据库集群参数组中，则节点分类查询可以像这样简单：

```
g.V("movie_1", "movie_2", "movie_3").properties("genre").with("Neptune#ml.classification")
```

您可以使用 `union()` 步骤在查询中混用顶点属性和类：

```
g.with("Neptune#ml.endpoint","node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" )
 .union(
   properties("genre").with("Neptune#ml.classification"),
   properties("genre")
 )
```

您也可以进行无界查询，如下所示：

```
g.with("Neptune#ml.endpoint","node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V()
 .properties("genre").with("Neptune#ml.classification")
```

您可以使用 `select()` 步骤以及 `as()` 步骤一起检索节点类和顶点：

```
g.with("Neptune#ml.endpoint","node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" ).as("vertex")
 .properties("genre").with("Neptune#ml.classification").as("properties")
 .select("vertex","properties")
```

还可以按节点类进行筛选，如以下示例所示：

```
g.with("Neptune#ml.endpoint", "node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" )
 .properties("genre").with("Neptune#ml.classification")
 .has(value, "Horror")

g.with("Neptune#ml.endpoint","node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" )
 .properties("genre").with("Neptune#ml.classification")
 .has(value, P.eq("Action"))

g.with("Neptune#ml.endpoint","node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" )
 .properties("genre").with("Neptune#ml.classification")
 .has(value, P.within("Action", "Horror"))
```

您可以使用 `Neptune#ml.score` 谓词获得节点分类置信度分数：

```
 g.with("Neptune#ml.endpoint","node-classification-movie-lens-endpoint")
 .with("Neptune#ml.iamRoleArn","arn:aws:iam::0123456789:role/sagemaker-role")
 .V( "movie_1", "movie_2", "movie_3" )
 .properties("genre", "Neptune#ml.score").with("Neptune#ml.classification")
```

响应将如下所示：

```
==>vp[genre->Action]
==>vp[Neptune#ml.score->0.01234567]
==>vp[genre->Crime]
==>vp[Neptune#ml.score->0.543210]
==>vp[genre->Comedy]
==>vp[Neptune#ml.score->0.10101]
```

## 在节点分类查询中使用归纳推理
<a name="machine-learning-gremlin-node-class-inductive"></a>

假设您要在 Jupyter 笔记本的现有图形中添加一个新节点，如下所示：

```
%%gremlin
g.addV('label1').property(id,'101').as('newV')
 .V('1').as('oldV1')
 .V('2').as('oldV2')
 .addE('eLabel1').from('newV').to('oldV1')
 .addE('eLabel2').from('oldV2').to('newV')
```

然后，您可以使用归纳推理查询来获得反映了新节点的流派和置信度分数：

```
%%gremlin
g.with("Neptune#ml.endpoint", "nc-ep")
 .with("Neptune#ml.iamRoleArn", "arn:aws:iam::123456789012:role/NeptuneMLRole")
 .V('101').properties("genre", "Neptune#ml.score")
 .with("Neptune#ml.classification")
 .with("Neptune#ml.inductiveInference")
```

但是，如果您多次运行此查询，您得到的结果可能会有所不同：

```
# First time
==>vp[genre->Action]
==>vp[Neptune#ml.score->0.12345678]

# Second time
==>vp[genre->Action]
==>vp[Neptune#ml.score->0.21365921]
```

您可以将同样的查询设定为确定性：

```
%%gremlin
g.with("Neptune#ml.endpoint", "nc-ep")
 .with("Neptune#ml.iamRoleArn", "arn:aws:iam::123456789012:role/NeptuneMLRole")
 .V('101').properties("genre", "Neptune#ml.score")
 .with("Neptune#ml.classification")
 .with("Neptune#ml.inductiveInference")
 .with("Neptune#ml.deterministic")
```

在这种情况下，每次的结果都大致相同：

```
# First time
==>vp[genre->Action]
==>vp[Neptune#ml.score->0.12345678]
# Second time
==>vp[genre->Action]
==>vp[Neptune#ml.score->0.12345678]
```