资讯动态

从判断列表到训练好的 Learning to Rank( LTR )模型

发布时间:2026/8/28 15:32:24 来源:尧图企业网站定制
作者来自 Elastic Jeffrey Rengifo学习如何将判断列表转换为 Learning To Rank LTR 的训练数据设计有效特征并解读模型学到了什么。Elasticsearch 提供了许多新功能帮助你为你的使用场景构建最佳搜索解决方案。通过我们关于构建现代 Search AI 体验的实操 webinar学习如何将这些功能付诸实践。你还可以立即开始免费的 cloud 试用或在本地机器上试用 Elastic。在 “使用判断列表评估搜索查询相关性” 一文中我们构建了判断列表并使用 _rank_eval API 来衡量搜索质量。尽管这种方法为我们提供了一种客观评估变更的方式但提升相关性仍然需要手动进行查询调优。如果判断列表回答的是 “How good is my ranking?”那么 Learning To Rank LTR 回答的是 “How do I systematically make it better?”在本文中我们迈出下一步使用这些判断列表通过 XGBoost、 Eland 和 Elasticsearch 训练一个 LTR 模型。我们将重点理解这一过程而不是具体实现细节。完整代码请参考配套 notebook。什么是 LTRLTR 使用机器学习 ML 为你的搜索引擎构建排序函数。与手动调优查询权重不同你只需提供正确排序的示例你的判断列表让模型学习什么使文档相关。在 Elasticsearch 中LTR 作为第二阶段重排器在从 Elasticsearch 检索文档之后工作第一阶段标准查询 BM25、向量或混合快速检索候选文档。第二阶段LTR 模型使用其学习到的多个信号对顶部结果进行重新排序。更深入的介绍请参见在 Elasticsearch 中引入 Learning To Rank LTR 。从判断列表到模型的过程判断列表告诉我们对于给定查询哪些文档应该排名更高。但模型无法直接从文档 ID 中学习。它需要数值信号来解释为什么某些文档具有潜在相关性。该过程如下从判断开始。查询-文档对带有相关性评分例如你定义 doc1 是 “DiCaprio performance” 搜索词的良好匹配。提取特征。对于每个查询-文档对计算数值信号其中一些仅与文档本身相关例如流行度另一些则与查询和文档的交互相关例如 BM25 分数。训练模型。模型学习哪些特征模式可以预测高评分。部署。将训练好的模型部署到你的 Elasticsearch 集群。查询。使用该模型对搜索结果进行重新排序。关键洞察是特征必须能够捕捉你的判断所衡量的内容。如果你的判断列表偏好热门惊悚电影但你的特征只包含文本匹配分数那么模型就无法学习什么使这些文档相关。什么是特征特征是描述查询-文档对的数值。在 Elasticsearch 中我们使用返回分数的查询来定义特征。主要有三种类型查询-文档特征用于衡量查询与文档的匹配程度。Eland 提供了 QueryFeatureExtractor 工具来定义这些特征它会为每个查询-文档对计算 BM25 相关性分数QueryFeatureExtractor( feature_nametitle_bm25, query{match: {title: {{query}}}} )这会为每个文档提取相对于查询的 title 字段 BM25 分数。文档特征是与查询无关的文档属性。你可以使用 script_score 或 function_score 来提取这些特征QueryFeatureExtractor( feature_namepopularity, query{ script_score: { query: {exists: {field: popularity}}, script: {source: return doc[popularity].value;} } } )查询特征描述查询本身例如术语数量。这类特征较少见但可以帮助模型处理不同类型的查询。设计你的特征集选择特征不是随机的。每个特征都应捕捉可能解释用户为何偏好某些文档的信号。让我们看看 LTR notebook 中的特征并理解其设计逻辑FeatureTypePurposetitle_bm25Query-document标题匹配是强相关信号。例如标题为 Star Wars 的电影在查询 star wars 时应排名靠前。actors_bm25Query-document一些用户按演员姓名搜索。如果搜索 leonardo dicaprio movies应返回主演 Leonardo DiCaprio 的影片。title_all_terms_bm25Query-document标题匹配的更严格版本要求所有查询词都必须出现。它有助于区分完全匹配与部分匹配。actors_all_terms_bm25Query-document与上述严格匹配逻辑相同但专门应用于演员。popularityDocument当相关性相近时用户通常更偏好知名电影。热门 Star Wars 电影应排在低预算、标题包含 Star Wars 的模仿片之上。注意这里的策略同一概念的多重信号。我们同时有 title_bm25宽松和 title_all_terms_bm25严格。宽松版本对至少有一个查询词匹配标题的文档打分严格版本要求所有词都必须出现。对于短查询宽松匹配可能就足够而对于较长、具体的查询严格匹配可能更重要。模型可以学习何时依赖哪种匹配。文本特征加上质量特征。仅靠文本匹配可能返回包含正确词语但无关的文档。popularity 特征允许模型在文本分数相近时提升知名、高质量内容。覆盖不同查询类型。有些查询针对标题如 star wars有些针对演员如 dicaprio movies。为两者提供特征意味着模型可以处理多样化搜索。在设计自己的特征时问自己“一个人会用哪些信号来判断文档是否相关” 这些就是你的候选特征。构建训练数据集一旦定义了特征我们就为判断列表中的每个查询-文档对提取它们。结果是一个训练数据集每行包含查询标识符文档标识符相关性评分来自判断列表所有特征值下面是一个简化示例query_idquerydoc_idgradeqid:1star wars114qid:1star wars121803qid:1star wars2784271qid:2tom hanks movies8574qid:2tom hanks movies133需要注意的几点NaN 值是正常的。当查询未匹配某个字段时该特征不会返回分数。电影 Star Wars 的 title_bm25 很高但 actors_bm25 为空因为查询 star wars 并未匹配任何演员姓名。训练期间查询会被分组。query_id 列告诉模型哪些文档需要相互比较。对于 star wars它会学习文档 11评分 4应排在文档 278427评分 1之前。但重点是模型不会记住这些具体查询。相反它学习一般模式例如 “title_bm25 高且 popularity 高的文档往往评分高”。当遇到新查询时模型会应用这些学习到的模式来排序结果。特征必须能够解释评分差异。看看 qid:1评分 4 的文档比评分 1 的文档具有更高的 title_bm25 和更高的 popularity。这些模式就是模型学习的内容。训练 LTR 模型在准备好训练数据集后我们使用带有 ranking 目标的 XGBoost 模型进行训练。模型构建决策树以学习模式例如“如果 title_bm25 10 且 popularity 50则预测高相关性。”“如果 title_bm25 缺失但 actors_bm25 12仍然预测中等相关性。”实际训练过程如下from xgboost import XGBRanker from sklearn.model_selection import GroupShuffleSplit # Create the ranker model: ranker XGBRanker( objectiverank:ndcg, eval_metric[ndcg10], early_stopping_rounds20, ) # Shaping training and eval data in the expected format. X judgments_with_features[ltr_config.feature_names] y judgments_with_features[grade] groups judgments_with_features[query_id] # Split the dataset in two parts respectively used for training and evaluation of the model. group_preserving_splitter GroupShuffleSplit(n_splits1, train_size0.7).split( X, y, groups ) train_idx, eval_idx next(group_preserving_splitter) train_features, eval_features X.loc[train_idx], X.loc[eval_idx] train_target, eval_target y.loc[train_idx], y.loc[eval_idx] train_query_groups, eval_query_groups groups.loc[train_idx], groups.loc[eval_idx] # Training the model ranker.fit( Xtrain_features, ytrain_target, grouptrain_query_groups.value_counts().sort_index().values, eval_set[(eval_features, eval_target)], eval_group[eval_query_groups.value_counts().sort_index().values], verboseTrue, )在训练过程中模型尝试这些规则的不同组合并衡量生成的排序与判断评分的匹配程度。它使用一个称为归一化折扣累积增益Normalized Discounted Cumulative Gain, NDCG的指标进行评分。NDCG 达到 1.0 表示模型的排序完全匹配你的判断。分数较低意味着一些相关文档排在了它们本应出现的位置之下。训练过程中还使用了一种称为早停early stopping的技术。如果模型的分数在若干轮中不再提升训练会自动停止。这可以防止模型过度记忆训练数据从而影响其对新查询的泛化能力。配套 notebook 包含完整的训练代码。理解你的 LTR 模型学到了什么训练完成后XGBoost 可以显示模型最依赖的特征。你可以使用 XGBoost 内置可视化生成特征重要性图from xgboost import plot_importance plot_importance(ranker, importance_typeweight)参数 importance_typeweight 显示每个特征在决策树分裂中被使用的频率。下面是生成的图表F 分数统计每个特征在模型所有决策树中用于分裂决策的次数。值越高说明模型越依赖该特征。在此示例中popularity (2178)最重要的特征。模型经常使用 popularity 来区分相关与非相关文档。title_bm25 (1642)第二重要特征。标题匹配在电影搜索中非常关键。actors_bm25 (565)中等重要。对于包含演员的查询很有用。title_all_terms_bm25 (211)偶尔有用。严格匹配对某些查询有帮助。actors_all_terms_bm25 (63)很少使用。模型发现此特征预测能力较低。该图表有助于你迭代特征集。如果某个预期重要的特征显示几乎为零的重要性需要调查原因。可能是特征提取未按预期工作或者该信号在你的判断数据中实际上不能预测相关性。部署和使用 LTR 模型训练完成后使用 Eland 将模型上传到 ElasticsearchMLModel.import_ltr_model( es_clientes_client, modelranker, model_idltr-model-xgboost, ltr_model_configltr_config, es_if_existsreplace, )上传后该模型可以作为重评分重检器rescorer retriever使用并可与其他重检索器retrievers器结合用于多阶段搜索管道GET movies/_search { retriever: { rescorer: { rescore: { window_size: 50, learning_to_rank: { model_id: ltr-model-xgboost, params: { query: star wars } } }, retriever: { standard: { query: { multi_match: { fields: [title, overview, actors, director, tags, characters], query: star wars } } } } } } }响应简化版hits: { total: { value: 852, relation: eq }, max_score: 25.165691, hits: [ { _index: movies, _id: 11, _score: 25.165691, _source: { title: Star Wars } }, { _index: movies, _id: 12180, _score: 25.092865, _source: { title: Star Wars: The Clone Wars } }, { _index: movies, _id: 181812, _score: 23.456198, _source: { title: Star Wars: The Rise of Skywalker } }, { _index: movies, _id: 140607, _score: 23.320757, _source: { title: Star Wars: The Force Awakens } }, ...第一阶段查询使用 BM25 检索候选文档。然后 LTR 模型使用它学到的所有特征对前 50 个结果进行重新排序。在此示例中仅使用 multi_match 查询可能会在前几个位置返回一些相关性较低的结果而 LTR 帮助修正了这些问题{ hits: [ { _index: movies, _id: 11, _score: 10.971989, _source: { title: Star Wars } }, { _index: movies, _id: 12180, _score: 9.923633, _source: { title: Star Wars: The Clone Wars } }, { _index: movies, _id: 1022100, _score: 8.9880295, _source: { title: Andor: A Disney Day Special Look } }, { _index: movies, _id: 278427, _score: 8.845748, _source: { title: Family Guy Presents: Its a Trap! } }, ... ] }结论从判断列表到可用的 LTR 模型的路径包括三个关键步骤设计捕捉相关性信号的特征、构建将这些特征与判断评分配对的训练数据集以及训练能够学习模式的模型。我们之前的文章成为这个过程的起点。你的评分定义了 “相关” 的含义以及如何衡量而你的特征为模型提供了预测所需的信号。有关完整实现及包含 9,750 部电影和 384,755 条判断记录的数据集请参见 LTR notebook。对于高级用例如个性化搜索请参见使用 LTR 的个性化搜索。原文https://www.elastic.co/search-labs/blog/learning-to-rank-models-judgment-lists

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价