使用回归预测数值
Elastic Stack Serverless
回归是一种监督式机器学习过程,用于估算数据中不同字段之间的关系,然后基于这些关系对数值数据进行进一步预测。例如,您可以根据历史数据预测 Web 请求的响应时间,或者服务器与客户端交换的数据量。
执行回归分析时,您必须识别一组您要用于创建模型来预测其他字段的字段。特征变量是用于创建模型的字段。因变量是要预测的字段。
回归使用一种类似于极端梯度提升 (XGBoost) 的集成学习技术,该技术将决策树与梯度提升方法相结合。XGBoost 训练一系列决策树,并且每棵决策树都能从到目前为止整个森林的错误中学习。在每次迭代中,添加到森林中的树都会提高已组合决策森林的决策质量。默认情况下,回归算法会针对称为均方误差损失的损失函数进行优化。
这些算法支持三种类型的特征变量:数值型、类别型或布尔型。不支持数组。
在需要预测连续量的情况下,回归会很有用。回归分析可以预测的值是数值。如果您的用例需要预测连续的数值,那么回归可能是适合您的选择。
在使用 Elastic Stack 机器学习功能之前,需要解决一些配置要求(例如安全权限)。请参阅设置和安全。
回归是一种监督式机器学习方法,这意味着您需要提供一个已标记的训练数据集。该数据集必须包含用于训练模型的特征变量和因变量的值。在训练期间,这些信息用于识别数据各种特征与预测值之间的关系。此已标记数据集在模型评估中也起着关键作用。
您可能还需要转换您的数据以创建可作为回归源的数据框。
要了解有关如何准备数据的更多信息,请参阅监督式学习概述的相关部分。
数据框分析作业包含执行分析任务所需的配置信息和元数据。您可以通过 Kibana 或使用创建数据框分析作业 API 来创建数据框分析作业。
选择回归作为作业的分析类型,然后选择您要预测的字段(因变量)。您还可以包含和排除字段以进行分析。
您可以在数据框分析向导中查看可选择字段的统计信息。在弹出窗口中显示的字段统计信息提供了更有意义的上下文,以帮助您选择相关字段。
您可以通过 Kibana 或使用启动数据框分析作业 API 来启动作业。回归作业有以下阶段:
reindexing:文档从源索引复制到目标索引。loading_data:作业从目标索引获取所需数据。feature_selection:该过程识别用于预测因变量的最相关的分析字段。coarse_parameter_search:该过程识别未定义超参数的初始值。fine_tuning_parameters:该过程识别未定义超参数的最终值。请参阅超参数优化。final_training:模型训练发生。writing_results:作业将结果与目标索引中的数据行匹配,合并它们,然后将其索引回目标索引。inference:作业根据数据集的测试分割验证训练好的模型。
最后一个阶段完成后,作业停止,结果即可进行评估。
创建数据框分析作业时,如果模型太大无法放入 JVM,则该过程的推理步骤可能会失败。有关解决方法,请参阅此 GitHub 问题。
使用数据框分析功能从数据集中获取见解是一个迭代过程。在定义了要解决的问题并选择了可以帮助您解决问题的分析类型之后,您需要生成高质量的数据集并创建相应的数据框分析作业。在获得令您满意的结果之前,您可能需要尝试不同的配置、参数和数据转换方法。此过程的一个有价值的辅助工具是评估数据框分析 API,它使您能够评估数据框分析性能。它帮助您理解误差分布,并识别数据框分析模型表现良好或不那么可信的点。
要使用此 API 评估分析,您需要注释包含分析结果的索引,其中包含一个字段,该字段为每个文档标记真实值。评估数据框分析 API 会根据手动提供的真实值评估数据框分析的性能。
您可以使用评估数据框分析 API 的 regression 评估类型来衡量模型在训练数据上的表现。评估在训练数据集上提供的均方误差 (MSE) 值是训练误差。迭代训练和评估模型意味着找到产生最低训练误差的模型参数组合。
另一个关键测量是模型在未见过的数据上的表现。要评估训练好的模型在从未见过的数据上的表现,您必须将一部分训练集留作测试(测试数据)。模型训练完成后,您可以让它预测它从未见过的数据点的值,并将其预测与实际值进行比较。此测试提供了对称为模型泛化误差的量估算。
回归评估类型提供了以下指标来评估模型性能:
- 均方误差 (MSE)
- 均方对数误差 (MSLE)
- 伪 Huber 损失
- R 方 (R2)
MSE 是真实值与预测值之差的平均平方和。(平均 (预测值-实际值)2)。
MSLE 是均方误差的一个变体。它可以用于目标值是正数且具有长尾分布的情况,例如价格或人口数据。有关损失函数的更多信息,请参阅回归分析的损失函数页面。
伪 Huber 损失指标在误差大于预定值(默认为 1)时表现为平均绝对误差 (MAE),在误差小于预定值时表现为均方误差 (MSE)。此损失函数使用 delta 参数定义 MAE 和 MSE 之间的过渡点。有关损失函数的更多信息,请参阅回归分析的损失函数页面。
R 方 (R2) 表示拟合优度,衡量预测能够解释数据中多少比例的变化。R2 的值小于或等于 1,其中 1 表示预测值与真实值相等。当所有预测值都设置为真实值的平均值时,得到的值为 0。R2 值为 0.5 表示预测值比其平均值更接近真实值 1 - 0.5 (1/2)(约 30%)。
特征重要性提供了有关分析结果的更多信息,并有助于更精细地解释结果。如果您想了解更多关于特征重要性的信息,请点击此处。
您创建的模型存储为 Elasticsearch 文档,位于内部索引中。换句话说,训练好的模型的特性会保存下来,可以随时部署和用作函数。推理功能使您能够将模型用在摄取管道的预处理器中,或者用在搜索查询的管道聚合中,以对您的数据进行预测。
要在管道中部署数据框分析模型,请在主菜单中导航到 **机器学习** > **模型管理** > **已训练模型**,或者使用 Kibana 中的全局搜索字段。
在列表中找到您要部署的模型,然后单击“**操作**”菜单中的“**部署模型**”。
创建一个推理管道,以便通过管道使用模型针对新数据进行预测。添加名称和描述,或使用默认值。
配置管道处理器或使用默认设置。
配置以处理摄取失败,或使用默认设置。
(可选) 通过运行管道模拟来测试您的管道,以确认其产生预期结果。
查看设置并单击“**创建管道**”。
模型已部署,并通过推理管道即可使用。
推理使您能够以连续的方式将已训练的机器学习模型应用于传入数据。
例如,假设您有一个在线服务,并且您希望预测客户是否可能流失。您有一个包含历史数据的索引 — 关于您公司客户多年行为的信息 — 以及一个在该数据上训练的分类模型。新信息进入连续转换的目标索引。通过推理,您可以对新数据执行分类分析,使用与训练模型相同的输入字段,并获得预测。
推理可用作 摄取管道中指定的处理器。它使用已训练的模型对管道中正在摄取的数据进行推理。模型在摄取节点上使用。推理通过模型预处理数据,并提供预测。处理完成后,管道继续执行(如果管道中还有其他处理器),最后,新数据以及结果将索引到目标索引中。
请查看推理处理器和机器学习数据框分析 API 文档以了解更多信息。
推理也可以用作管道聚合。您可以在聚合中引用已训练的模型,以对父存储桶聚合的结果字段进行推理。推理聚合使用模型对结果进行预测。此聚合使您能够在搜索时运行分类或回归分析。如果您想对少量数据进行分析,此聚合使您能够生成预测,而无需在摄取管道中设置处理器。
请查看推理存储桶聚合和机器学习数据框分析 API 文档以了解更多信息。
如果您使用已训练的模型别名在推理处理器或推理聚合中引用您的已训练模型,则可以替换您的已训练模型,而无需更新处理器或聚合。通过使用创建或更新已训练模型别名 API,将您使用的别名重新分配给新的已训练模型 ID。新的已训练模型需要使用与旧模型相同的 DataFrame 分析类型。
让我们尝试使用示例航班数据来预测航班延误。该数据集包含天气状况、航班目的地和始发地、航班距离、航空公司以及每趟航班延误的分钟数等信息。创建回归作业时,它会学习数据字段之间的关系,以预测因变量的值,在此情况下,即数值型 FlightDelayMins 字段。有关这些概念的概述,请参阅使用回归预测数值和监督式学习入门。
数据集中每个文档都包含单次航班的详细信息,因此此数据已准备好进行分析;它已经是一个二维的、基于实体的数据结构。通常,您需要先将数据转换为以实体为中心索引,然后才能对其进行分析。
要进行分析,文档必须包含至少一个具有受支持数据类型(numeric、boolean、text、keyword 或 ip)的字段,并且不得包含超过一项的数组。如果您的源数据包含一些包含因变量的文档和一些不包含的文档,则模型将在包含因变量的文档子集上进行训练。
示例源文档
{
"_index": "kibana_sample_data_flights",
"_type": "_doc",
"_id": "S-JS1W0BJ7wufFIaPAHe",
"_version": 1,
"_seq_no": 3356,
"_primary_term": 1,
"found": true,
"_source": {
"FlightNum": "N32FE9T",
"DestCountry": "JP",
"OriginWeather": "Thunder & Lightning",
"OriginCityName": "Adelaide",
"AvgTicketPrice": 499.08518599798685,
"DistanceMiles": 4802.864932998549,
"FlightDelay": false,
"DestWeather": "Sunny",
"Dest": "Chubu Centrair International Airport",
"FlightDelayType": "No Delay",
"OriginCountry": "AU",
"dayOfWeek": 3,
"DistanceKilometers": 7729.461862731618,
"timestamp": "2019-10-17T11:12:29",
"DestLocation": {
"lat": "34.85839844",
"lon": "136.8049927"
},
"DestAirportID": "NGO",
"Carrier": "ES-Air",
"Cancelled": false,
"FlightTimeMin": 454.6742272195069,
"Origin": "Adelaide International Airport",
"OriginLocation": {
"lat": "-34.945",
"lon": "138.531006"
},
"DestRegion": "SE-BD",
"OriginAirportID": "ADL",
"OriginRegion": "SE-BD",
"DestCityName": "Tokoname",
"FlightTimeHour": 7.577903786991782,
"FlightDelayMin": 0
}
}
在此示例中使用了示例航班数据,因为它易于访问。但是,数据包含一些不一致之处。例如,航班可能同时延误和取消。这很好地提醒我们,输入数据的质量会影响结果的质量。
预测每趟航班延误的分钟数
- 验证您的环境是否已正确设置以使用机器学习功能。Elastic Stack 安全功能需要一个有权创建和管理数据框分析作业的用户。请参阅设置和安全。
- 创建数据框分析作业。您可以使用 Kibana 中“**机器学习**”>“**数据框分析**”选项卡上的向导,或使用创建数据框分析作业 API。
- 选择
kibana_sample_data_flights作为源索引。 - 选择
regression作为作业类型。 - 通过添加一个查询来移除错误数据,从而可以选择性地提高分析质量。在此案例中,我们省略距离为 0 公里或更少的航班。
- 选择
FlightDelayMin作为因变量,即我们要预测的字段。 - 将
Cancelled、FlightDelay和FlightDelayType添加到排除字段列表中。这些字段将被排除在分析之外。建议排除包含错误数据或描述因变量的字段。该向导包含一个散点图矩阵,它使您能够探索数值字段之间的关系。每个点的颜色会受到该文档的因变量值的影响,如图例所示。您可以突出显示其中一个图表中的区域,相应的区域也会在其他图表中高亮显示。您可以使用此矩阵来帮助您决定要包含或排除哪些字段进行分析。
如果您希望这些图表代表来自更大样本量或随机选择文档的数据,则可以更改默认行为。但是,更大的样本量可能会减慢矩阵的性能,而随机选择由于更密集的查询可能会给集群带来更多负载。6. 选择90的训练百分比,这意味着它随机选择 90% 的源数据进行训练。7. 如果您想尝试特征重要性,请在高级配置选项中指定一个值。在此示例中,我们选择为每个文档返回最多 5 个特征重要性值。此选项会影响分析速度,因此默认情况下它是禁用的。8. 使用至少 50 MB 的模型内存限制。如果作业需要超过此内存量,则会失败。如果节点上的可用内存有限,此设置可以防止作业执行。9. 添加作业 ID(例如model-flight-delay-regression)和可选的作业描述。10. 添加将包含分析结果的目标索引的名称。在 Kibana 中,索引名称默认与作业 ID 匹配。它将包含源索引数据的副本,其中每个文档都已标注分析结果。如果索引不存在,它将自动创建。 - 选择
API 示例
PUT _ml/data_frame/analytics/model-flight-delays-regression {
"source": {
"index": [
"kibana_sample_data_flights"
],
"query": {
"range": {
"DistanceKilometers": {
"gt": 0
}
}
}
},
"dest": {
"index": "model-flight-delays-regression"
},
"analysis": {
"regression": {
"dependent_variable": "FlightDelayMin",
"training_percent": 90,
"num_top_feature_importance_values": 5,
"randomize_seed": 1000
}
},
"model_memory_limit": "50mb",
"analyzed_fields": {
"includes": [],
"excludes": [
"Cancelled",
"FlightDelay",
"FlightDelayType"
]
}
}
配置完作业后,配置详细信息将自动验证。如果检查成功,您可以继续并启动作业。如果配置无效,则会显示警告消息。该消息包含改进配置以进行验证的建议。
- 在 Kibana 中启动作业,或使用启动数据框分析作业 API。
作业运行需要几分钟。运行时间取决于本地硬件以及分析的文档和字段的数量。字段和文档越多,作业运行时间越长。分析完成后,它会自动停止。
API 示例
POST _ml/data_frame/analytics/model-flight-delays-regression/_start
- 在 Kibana 中查看作业统计信息以跟踪进度,或使用获取数据框分析作业统计信息 API。
作业停止后,结果即可查看和评估。有关作业阶段的更多信息,请参阅数据框分析作业的工作原理。
API 示例
GET _ml/data_frame/analytics/model-flight-delays-regression/_stats
API 调用返回以下响应:
{
"count" : 1,
"data_frame_analytics" : [
{
"id" : "model-flight-delays-regression",
"state" : "stopped",
"progress" : [
{
"phase" : "reindexing",
"progress_percent" : 100
},
{
"phase" : "loading_data",
"progress_percent" : 100
},
{
"phase" : "feature_selection",
"progress_percent" : 100
},
{
"phase" : "coarse_parameter_search",
"progress_percent" : 100
},
{
"phase" : "fine_tuning_parameters",
"progress_percent" : 100
},
{
"phase" : "final_training",
"progress_percent" : 100
},
{
"phase" : "writing_results",
"progress_percent" : 100
},
{
"phase" : "inference",
"progress_percent" : 100
}
],
"data_counts" : {
"training_docs_count" : 11210,
"test_docs_count" : 1246,
"skipped_docs_count" : 0
},
"memory_usage" : {
"timestamp" : 1599773614155,
"peak_usage_bytes" : 50156565,
"status" : "ok"
},
"analysis_stats" : {
"regression_stats" : {
"timestamp" : 1599773614155,
"iteration" : 18,
"hyperparameters" : {
"alpha" : 19042.721566629778,
"downsample_factor" : 0.911884068909842,
"eta" : 0.02331774683318904,
"eta_growth_rate_per_tree" : 1.0143154178910303,
"feature_bag_fraction" : 0.5504020748926737,
"gamma" : 53.373570122718846,
"lambda" : 2.94058933878574,
"max_attempts_to_add_tree" : 3,
"max_optimization_rounds_per_hyperparameter" : 2,
"max_trees" : 894,
"num_folds" : 4,
"num_splits_per_feature" : 75,
"soft_tree_depth_limit" : 2.945317520946171,
"soft_tree_depth_tolerance" : 0.13448633124842999
},
"timing_stats" : {
"elapsed_time" : 302959,
"iteration_time" : 13075
},
"validation_loss" : {
"loss_type" : "mse"
}
}
}
}
]
}
现在,您有了一个新索引,其中包含源数据的副本以及针对您因变量的预测。
在 Kibana 中查看结果时,它以表格格式显示目标索引的内容。它还提供有关分析详细信息、模型评估指标、总特征重要性值和散点图矩阵的信息。让我们从查看结果表开始。
在此示例中,表显示了因变量(FlightDelayMin)的列,其中包含我们要预测的真实值。它还显示了预测值(ml.FlightDelayMin_prediction)的列,以及指示文档是否用于训练集的列(ml.is_training)。您可以过滤该表以仅显示测试数据或训练数据,并且可以选择在表中显示的字段。您还可以启用直方图以更好地理解数据值的分布。
如果您选择计算特征重要性,目标索引还将包含 ml.feature_importance 对象。包含在回归分析中的每个字段(称为数据点的特征)都会被分配一个特征重要性值。此值既有大小又有方向(正或负),它指示每个字段如何影响特定预测。索引中只存储最显著的值(在本例中为前 5 个)。但是,已训练的模型元数据还包含每个字段在所有训练数据上的平均特征重要性值。您可以在 Kibana 中查看此汇总信息。
您还可以以决策图的形式查看每个单独预测的特征重要性值。
决策路径从一个基线开始,该基线是训练数据集所有数据点的预测值的平均值。从那里,将特征重要性值添加到决策路径,直到达到最终预测。影响最显著的正向或负向影响的特征出现在顶部。因此,在此示例中,与航班距离相关的特征对此特定预测航班延误的影响最为显著。此类型的信息可以帮助您理解模型如何得出其预测。它还可以指示在训练和调整模型时,数据集中哪些方面最重要或最有用。
如果您不使用 Kibana,您可以通过获取已训练模型 API 查看汇总的特征重要性值,并通过搜索目标索引来查看各个值。
API 示例
GET _ml/inference/model-flight-delays-regression*?include=total_feature_importance,feature_importance_baseline
下面的代码片段显示了已训练模型元数据中总特征重要性详细信息的示例。
{
"count" : 1,
"trained_model_configs" : [
{
"model_id" : "model-flight-delays-regression-1601312043770",
...
"metadata" : {
...
"feature_importance_baseline" : {
"baseline" : 47.43643652716527
},
"total_feature_importance" : [
{
"feature_name" : "dayOfWeek",
"importance" : {
"mean_magnitude" : 0.38674590521018903,
"min" : -9.42823116446923,
"max" : 8.707461689065173
}
},
{
"feature_name" : "OriginWeather",
"importance" : {
"mean_magnitude" : 0.18548393012368913,
"min" : -9.079576266629092,
"max" : 5.142479101907649
}
...
- 特征重要性决策路径的基线。它是所有训练数据中预测值的平均值。
- 在所有训练数据中,
dayOfWeek字段的绝对特征重要性值的平均值。 - 此字段在所有训练数据中的最小特征重要性值。
- 此字段在所有训练数据中的最大特征重要性值。
要查看每次预测的顶级特征重要性值,请搜索目标索引。例如
GET model-flight-delays-regression/_search
下面的摘要显示了带有注释结果的文档的一部分
...
"DestCountry" : "CH",
"DestRegion" : "CH-ZH",
"OriginAirportID" : "VIE",
"DestCityName" : "Zurich",
"ml": {
"FlightDelayMin_prediction": 277.5392150878906,
"feature_importance": [
{
"feature_name": "DestCityName",
"importance": 0.6285966753441136
},
{
"feature_name": "DistanceKilometers",
"importance": 84.4982943868267
},
{
"feature_name": "DistanceMiles",
"importance": 103.90011847132116
},
{
"feature_name": "FlightTimeHour",
"importance": 3.7119156097309345
},
{
"feature_name": "FlightTimeMin",
"importance": 38.700587425831365
}
],
"is_training": true
}
...
最后,Kibana 在结果中提供散点图矩阵。它具有您在作业向导中看到的矩阵的相同功能。其目的是帮助您可视化和探索数据中数值字段与因变量之间的关系。
虽然您可以查看单个结果并将预测值(ml.FlightDelayMin_prediction)与实际值(FlightDelayMins)进行比较,但通常需要评估整个回归模型的成功程度。
Kibana 提供训练误差指标,这些指标表示模型在训练数据集上的表现如何。它还提供泛化误差指标,这些指标表示模型在测试数据上的表现如何。
均方误差 (MSE) 为零意味着模型能够精确预测因变量。这是理想情况,但通常不可行。同样,R 方值为 1 表示因变量中的所有方差都可以通过特征变量来解释。通常,您会将多个回归模型的 MSE 和 R 方值进行比较,以找到最适合您数据的平衡点或拟合度。
有关解释评估指标的更多信息,请参阅 6. 评估结果。
您也可以使用 数据帧分析评估 API 来生成这些指标。
API 示例
POST _ml/data_frame/_evaluate {
"index": "model-flight-delays-regression",
"query": {
"bool": {
"filter": [{ "term": { "ml.is_training": true } }]
}
},
"evaluation": {
"regression": {
"actual_field": "FlightDelayMin",
"predicted_field": "ml.FlightDelayMin_prediction",
"metrics": {
"r_squared": {},
"mse": {},
"msle": {},
"huber": {}
}
}
}
}
- 通过仅评估训练数据来计算训练误差。
- 包含实际(真实)值的字段。
- 包含预测值的字段。
API 返回类似如下的响应
{
"regression" : {
"huber" : {
"value" : 30.216037330465102
},
"mse" : {
"value" : 2847.2211476422967
},
"msle" : {
"value" : "NaN"
},
"r_squared" : {
"value" : 0.6956530017255125
}
}
}
接下来,我们计算泛化误差
POST _ml/data_frame/_evaluate {
"index": "model-flight-delays-regression",
"query": {
"bool": {
"filter": [{ "term": { "ml.is_training": false } }]
}
},
"evaluation": {
"regression": {
"actual_field": "FlightDelayMin",
"predicted_field": "ml.FlightDelayMin_prediction",
"metrics": {
"r_squared": {},
"mse": {},
"msle": {},
"huber": {}
}
}
}
}
- 仅评估不属于训练数据的文档。
当您训练了一个满意的模型后,您可以 部署它 以对新数据进行预测。
如果您不想保留数据帧分析作业,可以将其删除。例如,使用 Kibana 或 删除数据帧分析作业 API。当您在 Kibana 中删除数据帧分析作业时,可以选择同时删除目标索引和数据视图。