机器学习管道
1. 节点分类
本节概述了如何使用 Python 客户端构建、配置和训练节点分类管道,以及如何使用训练产生的模型进行预测。
1.1. 管道
要创建一个新的节点分类管道,需要进行以下调用
pipe = gds.nc_pipe("my-pipe")
其中 pipe
是一个管道对象。
然后继续构建、配置和训练管道,我们将直接在节点分类管道对象上调用方法。以下是此类对象上的方法描述
名称 | 参数 | 返回类型 | 描述 |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回管道中选定的特征属性列表。 |
|
|
|
如果模型存在于 GDS 管道目录中,则为 |
|
|
|
管道在管道目录中显示的名称。 |
|
|
|
管道的类型。 |
|
|
|
创建管道的时间。 |
|
|
|
返回管道的节点属性步骤。 |
|
|
|
返回为数据集的特征-训练-测试拆分设置的配置。 |
|
|
|
返回训练时为模型选择设置的模型参数空间。 |
|
|
|
返回为自动调整设置的配置。 |
|
|
|
|
1. 范围也可以作为长度为 2 的 |
比较上面映射到 Cypher API 过程的方法时,有两个主要区别
-
由于 Python 方法是在管道对象上调用的,因此在调用它们时不需要提供名称。
-
Cypher 调用中的配置参数由 Python 方法调用中的命名关键字参数表示。
有关方法期望的输入类型的更多信息,请参阅节点分类 Cypher 文档。
1.1.1. 示例
下面是一个如何配置和训练非常基本的节点分类管道的示例。请注意,我们没有显式配置拆分,而是使用默认值。
为了举例说明,我们引入了一个小型人员图
gds.run_cypher(
"""
CREATE
(a:Person {name: "Bob", fraudster: 0}),
(b:Person {name: "Alice", fraudster: 0}),
(c:Person {name: "Eve", fraudster: 1}),
(d:Person {name: "Chad", fraudster: 1}),
(e:Person {name: "Dan", fraudster: 0}),
(f:UnknownPerson {name: "Judy"}),
(a)-[:KNOWS]->(b),
(a)-[:KNOWS]->(c),
(a)-[:KNOWS]->(d),
(b)-[:KNOWS]->(d),
(c)-[:KNOWS]->(d),
(c)-[:KNOWS]->(e),
(d)-[:KNOWS]->(e),
(d)-[:KNOWS]->(f),
(e)-[:KNOWS]->(f)
"""
)
G, project_result = gds.graph.project("person_graph", {"Person": {"properties": ["fraudster"]}}, "KNOWS")
assert G.node_labels() == ["Person"]
pipe, _ = gds.beta.pipeline.nodeClassification.create("my-pipe")
# Add Degree centrality as a property step producing "rank" node properties
pipe.addNodeProperty("degree", mutateProperty="rank")
# Select our "rank" property as a feature for the model training
pipe.selectFeatures("rank")
# Verify that the features to be used in model training are what we expect
feature_properties = pipe.feature_properties()
assert len(feature_properties) == 1
assert feature_properties[0]["feature"] == "rank"
# Configure the model training to do cross-validation over logistic regression
pipe.addLogisticRegression(tolerance=(0.01, 0.1))
pipe.addLogisticRegression(penalty=1.0)
# Train the pipeline targeting node property "class" as label and "ACCURACY" as only metric
fraud_model, train_result = pipe.train(
G,
modelName="fraud-model",
targetProperty="fraudster",
metrics=["ACCURACY"],
randomSeed=111
)
assert train_result["trainMillis"] >= 0
生成了一个在GDS 模型目录中称为“fraud-model”的模型。在下一节中,我们将介绍如何使用该模型进行预测。
1.2. 模型
正如我们在上一节中看到的,节点分类模型是在训练节点分类管道时创建的。除了继承所有模型对象共有的方法外,节点分类模型还具有以下方法
名称 | 参数 | 返回类型 | 描述 |
---|---|---|---|
|
|
|
用于训练分类模型的类列表。 |
|
|
|
用作输入模型特征的节点属性。 |
|
|
|
管道用于在训练之前计算节点属性的算法列表。 |
|
|
|
训练时指定指标的值。 |
|
|
|
在所有验证集上表现最佳的训练方法参数。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
需要注意的是,这些 predict 方法确实与其 Cypher 对应方法非常相似。三个主要区别是
1.2.1. 示例(续)
现在,我们将继续使用我们在上面示例中训练的节点分类模型 trained_pipe_model
。
# Make sure we indeed obtained an accuracy score
metrics = fraud_model.metrics()
assert "ACCURACY" in metrics
H, project_result = gds.graph.project("full_person_graph", ["Person", "UnknownPerson"], "KNOWS")
# Predict on `H` and stream the results with a specific concurrency of 2
predictions = fraud_model.predict_stream(H, concurrency=2)
assert len(predictions) == H.node_count()
2. 链接预测
本节概述了如何使用 Python 客户端构建、配置和训练链接预测管道,以及如何使用训练产生的模型进行预测。
2.1. 管道
要创建一个新的链接预测管道,可以进行以下调用
pipe = gds.lp_pipe("my-pipe")
其中 pipe
是一个管道对象。
然后继续构建、配置和训练管道,我们可以直接在链接预测管道对象上调用方法。以下是此类对象上的方法描述
名称 | 参数 | 返回类型 | 描述 |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回管道中选择的特征步骤列表。 |
|
|
|
如果模型存在于 GDS 管道目录中,则为 |
|
|
|
管道在管道目录中显示的名称。 |
|
|
|
管道的类型。 |
|
|
|
创建管道的时间。 |
|
|
|
返回管道的节点属性步骤。 |
|
|
|
返回为数据集的特征-训练-测试拆分设置的配置。 |
|
|
|
返回训练时为模型选择设置的模型参数空间。 |
|
|
|
返回为自动调整设置的配置。 |
|
|
|
|
2. 范围也可以作为长度为 2 的 |
比较上面映射到 Cypher API 过程的方法时,有两个主要区别
-
由于 Python 方法是在管道对象上调用的,因此在调用它们时不需要提供名称。
-
Cypher 调用中的配置参数由 Python 方法调用中的命名关键字参数表示。
有关方法期望的输入类型的信息,请参阅链接预测 Cypher 文档。
2.1.1. 示例
以下是如何配置和训练一个非常基本的链接预测管道的示例。请注意,我们没有明确配置训练参数,而是使用默认值。
为了举例说明,我们引入了一个小型人员图
gds.run_cypher(
"""
CREATE
(a:Person {name: "Bob"}),
(b:Person {name: "Alice"}),
(c:Person {name: "Eve"}),
(d:Person {name: "Chad"}),
(e:Person {name: "Dan"}),
(f:Person {name: "Judy"}),
(a)-[:KNOWS]->(b),
(a)-[:KNOWS]->(c),
(a)-[:KNOWS]->(d),
(b)-[:KNOWS]->(d),
(c)-[:KNOWS]->(d),
(c)-[:KNOWS]->(e),
(d)-[:KNOWS]->(e),
(d)-[:KNOWS]->(f),
(e)-[:KNOWS]->(f)
"""
)
G, project_result = gds.graph.project("person_graph", "Person", {"KNOWS": {"orientation":"UNDIRECTED"}})
assert G.relationship_types() == ["KNOWS"]
pipe, _ = gds.beta.pipeline.linkPrediction.create("lp-pipe")
# Add FastRP as a property step producing "embedding" node properties
pipe.addNodeProperty("fastRP", embeddingDimension=128, mutateProperty="embedding", randomSeed=1337)
# Combine our "embedding" node properties with Hadamard to create link features for training
pipe.addFeature("hadamard", nodeProperties=["embedding"])
# Verify that the features to be used in model training are what we expect
steps = pipe.feature_steps()
assert len(steps) == 1
assert steps["name"][0] == "HADAMARD"
# Specify the fractions we want for our dataset split
pipe.configureSplit(trainFraction=0.2, testFraction=0.2, validationFolds=2)
# Add a random forest model with tuning over `maxDepth`
pipe.addRandomForest(maxDepth=(2, 20))
# Train the pipeline and produce a model named "friend-recommender"
friend_recommender, train_result = pipe.train(
G,
modelName="friend-recommender",
targetRelationshipType="KNOWS",
randomSeed=42
)
assert train_result["trainMillis"] >= 0
在GDS 模型目录中生成一个名为“my-model”的模型。在下一节中,我们将介绍如何使用该模型进行预测。
2.2. 模型
如上一节所述,在训练链接预测管道时会创建链接预测模型。除了继承所有模型对象共有的方法外,链接预测模型还有以下方法
名称 | 参数 | 返回类型 | 描述 |
---|---|---|---|
|
|
|
用于训练模型的输入链接特征。 |
|
|
|
管道用于在训练之前计算节点属性的算法列表。 |
|
|
|
训练时指定指标的值。 |
|
|
|
在所有验证集上表现最佳的训练方法参数。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
需要注意的是,这些 predict 方法确实与其 Cypher 对应方法非常相似。三个主要区别是
2.2.1. 示例(续)
现在,我们将继续使用我们在上面示例中训练的链接预测模型 trained_pipe_model
。
# Make sure we indeed obtained an AUCPR score
metrics = friend_recommender.metrics()
assert "AUCPR" in metrics
# Predict on `G` and mutate it with the relationship predictions
mutate_result = friend_recommender.predict_mutate(G, topN=5, mutateRelationshipType="PRED_REL")
assert mutate_result["relationshipsWritten"] == 5 * 2 # Undirected relationships
3. 节点回归
本节概述了如何使用 Python 客户端构建、配置和训练节点回归管道,以及如何使用训练产生的模型进行预测。
3.1. 管道
要创建一个新的节点回归管道,可以进行以下调用
pipe = gds.nr_pipe("my-pipe")
其中 pipe
是一个管道对象。
然后继续构建、配置和训练管道,我们可以直接在节点回归管道对象上调用方法。以下是此类对象上的方法描述
名称 | 参数 | 返回类型 | 描述 |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回管道中选定的特征属性列表。 |
|
|
|
如果模型存在于 GDS 管道目录中,则为 |
|
|
|
管道在管道目录中显示的名称。 |
|
|
|
管道的类型。 |
|
|
|
创建管道的时间。 |
|
|
|
返回管道的节点属性步骤。 |
|
|
|
返回为数据集的特征-训练-测试拆分设置的配置。 |
|
|
|
返回训练时为模型选择设置的模型参数空间。 |
|
|
|
返回为自动调整设置的配置。 |
|
|
|
|
3. 范围也可以作为长度为 2 的 |
比较上面映射到 Cypher API 过程的方法时,有两个主要区别
-
由于 Python 方法是在管道对象上调用的,因此在调用它们时不需要提供名称。
-
Cypher 调用中的配置参数由 Python 方法调用中的命名关键字参数表示。
有关方法期望的输入类型的信息,请参阅节点回归 Cypher 文档。
3.1.1. 示例
以下是如何配置和训练一个非常基本的节点回归管道的示例。请注意,我们没有明确配置分割,而是使用默认值。
为了举例说明,我们引入了一个小型人员图
gds.run_cypher(
"""
CREATE
(a:Person {name: "Bob", age: 22}),
(b:Person {name: "Alice", age: 5}),
(c:Person {name: "Eve", age: 53}),
(d:Person {name: "Chad", age: 44}),
(e:Person {name: "Dan", age: 60}),
(f:UnknownPerson {name: "Judy"}),
(a)-[:KNOWS]->(b),
(a)-[:KNOWS]->(c),
(a)-[:KNOWS]->(d),
(b)-[:KNOWS]->(d),
(c)-[:KNOWS]->(d),
(c)-[:KNOWS]->(e),
(d)-[:KNOWS]->(e),
(d)-[:KNOWS]->(f),
(e)-[:KNOWS]->(f)
"""
)
G, project_result = gds.graph.project("person_graph", {"Person": {"properties": ["age"]}}, "KNOWS")
assert G.relationship_types() == ["KNOWS"]
pipe, _ = gds.alpha.pipeline.nodeRegression.create("nr-pipe")
# Add Degree centrality as a property step producing "rank" node properties
pipe.addNodeProperty("degree", mutateProperty="rank")
# Select our "rank" property as a feature for the model training
pipe.selectFeatures("rank")
# Verify that the features to be used in model training are what we expect
feature_properties = pipe.feature_properties()
assert len(feature_properties) == 1
assert feature_properties[0]["feature"] == "rank"
# Configure the model training to do cross-validation over linear regression
pipe.addLinearRegression(tolerance=(0.01, 0.1))
pipe.addLinearRegression(penalty=1.0)
# Train the pipeline targeting node property "age" as label and "MEAN_SQUARED_ERROR" as only metric
age_predictor, train_result = pipe.train(
G,
modelName="age-predictor",
targetProperty="age",
metrics=["MEAN_SQUARED_ERROR"],
randomSeed=42
)
assert train_result["trainMillis"] >= 0
在GDS 模型目录中生成一个名为“my-model”的模型。在下一节中,我们将介绍如何使用该模型进行预测。
3.2. 模型
如上一节所述,在训练节点回归管道时会创建节点回归模型。除了继承所有模型对象共有的方法外,节点回归模型还有以下方法
名称 | 参数 | 返回类型 | 描述 |
---|---|---|---|
|
|
|
返回用作输入模型特征的节点属性。 |
|
|
|
管道用于在训练之前计算节点属性的算法列表。 |
|
|
|
训练时指定指标的值。 |
|
|
|
在所有验证集上表现最佳的训练方法参数。 |
|
|
|
|
|
|
|
需要注意的是,这些 predict 方法确实与其 Cypher 对应方法非常相似。三个主要区别是
3.2.1. 示例(续)
现在,我们将继续使用我们在上面示例中训练的节点回归模型 age_predictor
。假设我们有一个新的图 H
,我们希望对其运行预测。
# Make sure we indeed obtained an MEAN_SQUARED_ERROR score
metrics = age_predictor.metrics()
assert "MEAN_SQUARED_ERROR" in metrics
H, project_result = gds.graph.project("full_person_graph", ["Person", "UnknownPerson"], "KNOWS")
# Predict on `H` and stream the results with a specific concurrency of 2
predictions = age_predictor.predict_stream(H, concurrency=2)
assert len(predictions) == H.node_count()
4. 管道目录
使用管道对象的主要方式是训练模型。此外,管道对象可以用作GDS 管道目录操作的输入。例如,假设我们有一个管道对象 pipe
,我们可以
exists_result = gds.beta.pipeline.exists(pipe.name())
if exists_result["exists"]:
gds.beta.pipeline.drop(pipe) # same as pipe.drop()
已经创建并存在于管道目录中的管道对象可以通过使用其名称调用 get
方法来检索。例如,我们可以从目录中列出并使用找到的第一个管道名称来获取表示该管道的管道对象,这将是我们上面示例中创建的节点分类管道。
list_result = gds.beta.pipeline.list()
first_pipeline_name = list_result["pipelineName"][0]
pipe = gds.pipeline.get(first_pipeline_name)
assert pipe.name() == "my-pipe"