Link Search Menu Expand Document Documentation Menu

上传训练模型

虽然模型训练发生在学习排序 (Learning to Rank) 插件之外,但您可以使用该插件来记录特征分数。训练好模型后,您可以将其上传到插件,支持的序列化格式包括 RankLib 和 XGBoost。

RankLib 模型训练

特征日志记录过程会生成一个 RankLib 可用的判断文件。在以下判断文件中,ID 为 1 的查询 rambo 包含针对一组文档记录的特征 1(标题 TF*IDF 分数)和特征 2(描述 TF*IDF 分数)。

4   qid:1   1:9.8376875     2:12.318446     # 7555 rambo
3   qid:1   1:10.7808075    2:9.510193      # 1370 rambo
3   qid:1   1:10.7808075    2:6.8449354     # 1369 rambo
3   qid:1   1:10.7808075    2:0.0           # 1368 rambo

可以使用以下命令调用 RankLib 库

 cmd = "java -jar RankLib-2.8.jar -ranker %s -train%rs -save %s -frate 1.0" % (whichModel, judgmentsWithFeaturesFile, modelOutput)

judgmentsWithFeatureFile 是提供给 RankLib 进行训练的输入。可以传递其他参数。有关更多信息,请参阅 RankLib 文档

RankLib 以其自己的序列化格式输出模型。如下例所示,LambdaMART 模型是回归树的集合。

## LambdaMART
## No. of trees = 1000
## No. of leaves = 10
## No. of threshold candidates = 256
## Learning rate = 0.1
## Stop early = 100

    <ensemble>
       <tree id="1" weight="0.1">
           <split>
               <feature> 2 </feature>
               ...

在 RankLib 模型中,集成中的每棵树都会检查特征值,根据这些特征值做出决策,并输出相关性分数。特征按其序号位置引用,从 1 开始,对应于原始特征集中的第 0 个特征。RankLib 在模型训练期间不使用特征名称。

其他 RankLib 模型

RankLib 是一个库,除了 LambdaMART 之外,它还实现了其他几种模型类型,例如 MART、RankNet、RankBoost、AdaRank、Coordinate Ascent、ListNet 和 Random Forests。这些模型中的每一种都有自己的一组参数和训练过程。

例如,RankNet 模型是一个神经网络,它学习预测一个文档比另一个文档更相关的概率。该模型使用配对损失函数进行训练,该函数将两个文档的预测相关性与实际相关性进行比较。该模型以类似于以下示例的格式序列化:

## RankNet
## Epochs = 100
## No. of features = 5
## No. of hidden layers = 1
...
## Layer 1: 10 neurons
1 2
1
10
0 0 -0.013491530393429608 0.031183180961270988 0.06558792020112071 -0.006024092627087733 0.05729619574181734 -0.0017010373987742411 0.07684848696852313 -0.06570387602230028 0.04390491141617467 0.013371636736099578
...

所有这些模型都可以与学习排序 (Learning to Rank) 插件一起使用,前提是模型以 RankLib 格式序列化。

XGBoost 模型训练

与 RankLib 模型不同,XGBoost 模型以梯度提升决策树特有的格式序列化,如下例所示。

    [  { "nodeid": 0, "depth": 0, "split": "tmdb_multi", "split_condition": 11.2009, "yes": 1, "no": 2, "missing": 1, "children": [
        { "nodeid": 1, "depth": 1, "split": "tmdb_title", "split_condition": 2.20631, "yes": 3, "no": 4, "missing": 3, "children": [
        { "nodeid": 3, "leaf": -0.03125 },
        ...

XGBoost 参数

可以为 XGBoost 模型指定可选参数。这些参数以对象形式指定,决策树在 splits 字段中指定。支持的参数包括 objective,它定义了模型学习目标,如 XGBoost 文档 中所述。此参数可以转换最终的模型预测。支持的值包括 binary:logisticbinary:logitrawrank:ndcgrank:maprank:pairwisereg:linearreg:logistic

简单线性模型

机器学习 (ML) 模型,例如支持向量机 (SVM),会为每个特征输出线性权重。LTR 模型支持以简单格式表示这些线性权重,例如从 SVM 或线性回归模型中学习到的权重。在以下示例输出中,权重表示特征在模型预测中的相对重要性:

{
    "title_query" : 0.3,
    "body_query" : 0.5,
    "recency" : 0.1
}

特征归一化

特征归一化用于将特征值转换到一致的范围,通常在 0 到 1 或 -1 到 1 之间。这在训练阶段完成,以便更好地理解每个特征的相对影响。某些模型,特别是像 SVMRank 这样的线性模型,依赖于归一化才能正常运行。

模型上传过程

训练完模型后,下一步是使其可用于搜索操作。这涉及将模型上传到学习排序 (Learning to Rank) 插件。上传模型时,您必须提供以下信息:

  • 训练期间使用的特征集
  • 模型类型,例如 RankLib 或 XGBoost
  • 模型内容

以下示例请求展示了如何上传一个使用 more_movie_features 特征集训练的 RankLib 模型:

    POST _ltr/_featureset/more_movie_features/_createmodel
    {
        "model": {
            "name": "my_ranklib_model",
            "model": {
                "type": "model/ranklib",
                "definition": "## LambdaMART\n
                                ## No. of trees = 1000
                                ## No. of leaves = 10
                                ## No. of threshold candidates = 256
                                ## Learning rate = 0.1
                                ## Stop early = 100

                                <ensemble>
                                    <tree id="1" weight="0.1">
                                        <split>
                                            <feature> 2 </feature>
                                            ...
                            "
            }
        }
    }

以下示例请求展示了如何上传一个使用 more_movie_features 特征集训练的 XGBoost 模型:

    POST _ltr/_featureset/more_movie_features/_createmodel
    {
        "model": {
            "name": "my_xgboost_model",
            "model": {
                "type": "model/xgboost+json",
                "definition": "[  { \"nodeid\": 0, \"depth\": 0, \"split\": \"tmdb_multi\", \"split_condition\": 11.2009, \"yes\": 1, \"no\": 2, \"missing\": 1, \"children\": [
                                    { \"nodeid\": 1, \"depth\": 1, \"split\": \"tmdb_title\", \"split_condition\": 2.20631, \"yes\": 3, \"no\": 4, \"missing\": 3, \"children\": [
                                      { \"nodeid\": 3, \"leaf\": -0.03125 },
                                    ..."
            }
        }
    }

以下示例请求展示了如何上传一个使用 more_movie_features 特征集并带参数训练的 XGBoost 模型:

    POST _ltr/_featureset/more_movie_features/_createmodel
    {
        "model": {
            "name": "my_xgboost_model",
            "model": {
                "type": "model/xgboost+json",
                "definition": "{
                                 \"objective\": \"reg:logistic\",
                                 \"splits\": [  { \"nodeid\": 0, \"depth\": 0, \"split\": \"tmdb_multi\", \"split_condition\": 11.2009, \"yes\": 1, \"no\": 2, \"missing\": 1, \"children\": [
                                                  { \"nodeid\": 1, \"depth\": 1, \"split\": \"tmdb_title\", \"split_condition\": 2.20631, \"yes\": 3, \"no\": 4, \"missing\": 3, \"children\": [
                                                    { \"nodeid\": 3, \"leaf\": -0.03125 },
                                                  ...
                                             ]
                               }"
            }
        }
    }

以下示例请求展示了如何上传一个使用 more_movie_features 特征集训练的简单线性模型:

    POST _ltr/_featureset/more_movie_features/_createmodel
    {
        "model": {
            "name": "my_linear_model",
            "model": {
                "type": "model/linear",
                "definition": """
                                {
                                    "title_query" : 0.3,
                                    "body_query" : 0.5,
                                    "recency" : 0.1
                                }
                            """
            }
        }
    }

创建带有特征归一化的模型

特征归一化是在模型评估之前可以应用的关键预处理步骤。LTR 支持两种类型的特征归一化:最小-最大归一化和标准归一化。

标准归一化

标准归一化按如下方式转换特征:

  • 将平均值映射到 0
  • 将高于平均值的一个标准差映射到 1
  • 将低于平均值的一个标准差映射到 -1

以下示例请求展示了如何创建带有标准特征归一化的模型:

    POST _ltr/_featureset/more_movie_features/_createmodel
    {
        "model": {
            "name": "my_linear_model",
            "model": {
                "type": "model/linear",
                "feature_normalizers": {
                               "release_year": {
                                  "standard": {
                                    "mean": 1970,
                                    "standard_deviation": 30
                                  }
                               }
                            },
                "definition": """
                                {
                                    "release_year" : 0.3,
                                    "body_query" : 0.5,
                                    "recency" : 0.1
                                }
                            """
            }
        }
    }

最小-最大归一化

最小-最大归一化将特征缩放到固定范围,通常在 0 到 1 之间。最小-最大归一化按如下方式转换特征:

  • 将指定最小值映射到 0
  • 将指定最大值映射到 1
  • 将值在 0 到 1 之间线性缩放

以下示例请求展示了如何实现最小-最大归一化:

    "feature_normalizers": {
        "vote_average": {
            "min_max": {
                "minimum": 0,
                "maximum": 10
            }
        }
    }

模型与特征集的独立性

模型最初是参照特征集创建的。创建后,它们作为独立的顶级实体存在。

访问模型

要检索模型,请使用 GET 请求

GET _ltr/_model/my_linear_model

要删除模型,请使用 DELETE 请求

DELETE _ltr/_model/my_linear_model

模型名称在所有特征集中必须是全局唯一的。

模型持久性

创建模型时,其特征会被复制。这可以防止对原始特征的更改影响现有模型或模型生产。例如,如果用于创建模型的特征集被删除,您仍然可以访问和使用该模型。

模型响应

检索模型时,您会收到一个响应,其中包含用于创建模型的特征,如下例所示:

    {
    "_index": ".ltrstore",
    "_type": "store",
    "_id": "model-my_linear_model",
    "_version": 1,
    "found": true,
    "_source": {
        "name": "my_linear_model",
        "type": "model",
        "model": {
            "name": "my_linear_model",
            "feature_set": {
                "name": "more_movie_features",
                "features": [
                {
                    "name": "body_query",
                    "params": [
                        "keywords"
                        ],
                     "template": {
                        "match": {
                            "overview": ""
                        }
                    }
                },
                {
                    "name": "title_query",
                    "params": [
                        "keywords"
                    ],
                    "template": {
                        "match": {
                            "title": ""
                        }
                    }
                }
        ]}}}

后续步骤

了解如何使用 LTR 进行搜索