[Search Engines笔记] 16: Ranked retrieval: Feature-based models

本文介绍了学习排序(Learning to Rank)技术的基本概念及其在搜索引擎中的应用。解释了为何需要使用学习排序方法,并对比了点对点、配对和列表级三种主要的学习排序方法。
参考文档:
Jamie的课件:http://boston.lti.cs.cmu.edu/classes/11-642/
阿衡的SE笔记:http://www.shuang0420.com/categories/NLP/Search-Engines/

为啥要Learning to Rank:
    我们已经学习了很多的检索方法:
  •  Retrieval Models:Vector Space,BM25,language models…
  •  Representations: Title, body, url, inlink…
  •  Query templates: Sequential dependency models…
  •  Query-independent evidence: PR, url depth….
    这些不同方法的evidence可以combine起来提高SE的accuracy 因为潜在的combinations很多,而且有很多paraneters需要调整,所以人工combine这些方法是不切实际的。于是Learning to Rank 应运而生~

Main idea:  
    Learn a model that combines many types of evidence (each type as a feature). 
    类似ML的其他问题:
  •  给training data,从feature vectors->desired scores,学一个model Y=f(X; w)
  •  对一个new data x, 带入model得到y=f(x; w)。

Introduction:
    LeToR是个supervised learning。熟悉的任务是classification(难,因为分错了就全完了)和regression(简单,因为和target的差值是loss,就算很大也不算全错)。ranking task是要 find the best ranking (order)of given documents,但一般问题被转化为finding ranking scores。

大型SE中,检索通过一系列的检索模型完成:
  • exact match boolean:form a set of docs。为了快,而且刚开始文档质量参差不齐,差一点的算法就能搞定了;
  • best-match retrieval:rank the set,选出一部分。
  • L2R:reranking,选出一部分。因为此时文档少,而且质量差不多了,需要用复杂的方法去区分他们的差别。
LeToR在大型SE中被用在高层(reranking少量文档)以平衡efficient和effective。


L2R主要包括三个dimensions:
  • document representation — features
  • type of training data
  • ML算法

L2R Framework:
S1: 对于每个query,对docs做feature extraction,把doc d表示为
S2: 用training data学一个model
        这个model给每篇docs一个对于qry的分数。



Document representation — features:
  • VSM
  • coordinationMatch:number of query terms matching doc d
  • BM25 for either doc or url, body, inlink, title, keywords…..
  • Indri
  • PageRank
  • Spam
  • URLDepth
  • Wiki score
  • Avg word length
  • …..

Training data 种类:
  • binary assessments 相关、不相关 or 二值
  • document scores 实数score或者几个level
  • preferences (di > dj)
  • rankings (di > dj > dk > dm > …..)
    
L2R Approaches:
  • Pointwise
    • Training data是一个document的class或者score
    • Accurate score不等于accurate ranking
    • position information ignored 
  • Pairwise
    • Training data是一个preference among一对文档
    • Accurate preference不等于accurate ranking
    • position information ignored
  • Listwise
    • Training data是一个docs的ranking
    • 直接optimize ranking metrics很难

相同点:
    都用一个trained model h去estimate the score of x(doc的feature vector);
    都用h算出来的分排序。
不同点:
    不同的training方法;
    不同的training data。

Pointwise是最弱的。
  •  优点:简单
  • 缺点:focus on 错误的任务,影响了effectiveness
Pairwise和listwise差不多useful:
  • Pairwise的学习目标不完美,但是容易实现
    • 它minimize misordering errors,但想要的是best ranking
    • simpler learning problem,有theoretical guarantees
                -------------
    • 结果中rel和non-rel的文档数差不多的qry占领了training data里的大多数位置;
    • 对noisy label更敏感。它怎么合并结果的?
  • Listwise的学习目标很棒, 但是很难实现
    • perfect learning target
    • harder learning problem

Pointwise:
Training a model using individual documents。

Doc的score: 可以是二值的,也可以是relevance levels, 也可以是实数?

Score learning 方法假设training data中每个doc的score都是desired scores。Scores可以是任意的,只要保证order正确就好~ (一点都不会影响?)

Pairwise:


通过data里文章的分数/等级高低,生成di>dj的pairs作为training data。


目标: minimize number of misclassified doc pairs
用所有的pair算分嘛?

Listwise:


生成Trainin data:按照relevance score排序。 training data里也有metrics吗?

挑战:很多metrics是不连续的或者not convex,很难做optimization
解决方案:
  • 找其他容易optimize的metrics,比如likelihood of best ranking
  • optimize an approximation of the metric
  • bound the objective function ???

ListMLE:看纸质课件!!
大思路:
  • 建立一个ranking的概率P(x1, x2, x3, ...)
  • 找到一个model h(x)使得training data里best rankings的概率最大
  • 用h(x)的分对新data进行排序

如何建立概率P(x1, x2, x3, …)?
    直接建立不实际,因为space太大!
    所以ListMLE借助了independence的假设,缩小了space

    
假设独立的话是不是就不能直接用在diversification?是!
<think>我们正在解决一个Python脚本执行时出现的参数解析错误:`unrecognized arguments: --build-engines` 错误信息表明在运行脚本`deepseek_python_20251031_116acc (1).py`时,传递了一个不被识别的命令行参数`--build-engines`。 根据引用[1][3][5]中提到的类似问题,这通常是由于以下原因之一: 1. 脚本没有正确解析命令行参数,即`argparse`模块没有为`--build-engines`定义对应的参数。 2. 脚本中使用了`argparse`,但未添加`--build-engines`这个参数选项。 解决方案: 步骤1:检查脚本中`argparse`的使用 我们需要检查脚本中是否定义了`--build-engines`参数。如果没有定义,那么当命令行传入该参数时,就会报错。 步骤2:修改脚本以支持`--build-engines`参数(如果确实需要) 如果脚本确实需要使用`--build-engines`参数,那么应该在脚本中添加对应的参数定义。 步骤3:检查命令行调用 如果脚本并不需要`--build-engines`参数,那么可能是命令行调用时多写了这个参数,去掉即可。 具体操作: 情况一:脚本中未定义`--build-engines`参数,但调用时传入了 例如,脚本中可能只有如下定义: ```python import argparse parser = argparse.ArgumentParser() parser.add_argument('--data_path', type=str, default='./data') args = parser.parse_args() ``` 而调用命令为: ```bash python deepseek_python_20251031_116acc.py --build-engines --data_path ./my_data ``` 那么就会报错,因为`--build-engines`没有被定义。 解决方法: 1. 如果不需要这个参数,则从命令行中移除`--build-engines`。 2. 或者,在脚本中为这个参数添加定义,例如: ```python parser.add_argument('--build-engines', action='store_true', help='Build engines flag') ``` 情况二:脚本中定义了该参数,但可能拼写错误或位置错误 检查脚本中`add_argument`的调用,确保参数名称一致(注意大小写和短横线)。 情况三:参数定义在子解析器中 如果脚本使用了子命令,那么参数可能需要放在特定的子命令后面。例如: ```python parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() parser_build = subparsers.add_parser('build') parser_build.add_argument('--build-engines', action='store_true') ``` 那么调用应该是: ```bash python script.py build --build-engines ``` 步骤4:检查是否有其他程序干扰 根据引用[1][5]中提到的,有时在Jupyter环境中运行可能会遇到类似问题,因为Jupyter会传递一些额外的参数(如`-f`后面跟一个kernel文件)。但是,这里的错误信息明确是`--build-engines`未被识别,所以重点还是检查脚本本身。 根据引用[3]的示例,我们可以通过检查`argparse`的使用来修正。 因此,针对这个错误的解决方案总结如下: 1. 打开脚本`deepseek_python_20251031_116acc (1).py`,查找`argparse.ArgumentParser`的使用。 2. 检查是否定义了`--build-engines`参数(或者可能用不同的名称,例如`--build_engines`,注意下划线和短横线的区别)。 3. 如果没有定义,且需要这个参数,则添加: ```python parser.add_argument('--build-engines', action='store_true', default=False, help='Whether to build engines') ``` 4. 如果不需要这个参数,则从运行命令中移除`--build-engines`。 5. 如果参数是在子解析器中定义的,确保在命令行中正确放置了子命令。 6. 保存脚本后再次运行。 示例修正后的代码片段: ```python import argparse def main(): parser = argparse.ArgumentParser(description='My script') # 添加其他参数... parser.add_argument('--data_path', type=str, default='./data') # 添加build-engines参数 parser.add_argument('--build-engines', action='store_true', help='Build engines if set') args = parser.parse_args() # 使用args.build_engines(注意:这里属性名会自动转换,短横线变下划线) if args.build_engines: print("Building engines...") # ... 其他代码 if __name__ == '__main__': main() ``` 注意:`argparse`会将命令行参数中的短横线(-)替换为下划线(_)来作为属性名。因此,在代码中访问时,使用`args.build_engines`(而不是`args.build-engines`)。 如果问题仍未解决,请检查脚本中是否有多个`ArgumentParser`实例,或者是否调用了`parse_args`多次。 另外,根据引用[5]中的错误信息,还可能是由于Jupyter内核传递了额外的参数导致的(如`-f`参数)。如果是在Jupyter中运行,可能需要通过修改调用方式避免传递这些参数。但是在命令行中直接运行脚本通常不会遇到这个问题。 所以,请根据上述步骤检查并修改。 </think>### 解决 `unrecognized arguments: --build-engines` 错误 这个错误表明您的脚本无法识别命令行参数 `--build-engines`,通常由以下原因导致: #### 1. **参数定义缺失**(最常见原因) 脚本中未定义 `--build-engines` 参数。在 `argparse` 模块中添加参数定义: ```python import argparse parser = argparse.ArgumentParser() # 添加缺失的参数定义 parser.add_argument('--build-engines', action='store_true', help='Build inference engines') # 布尔型参数[^3] # 其他参数定义... args = parser.parse_args() ``` `action='store_true'` 表示该参数不需要额外值,出现即视为 `True`[^3] #### 2. **参数位置错误** 确保参数定义在 `parse_args()` 调用之前: ```python # 错误顺序(导致unrecognized arguments) args = parser.parse_args() # 解析在定义之前 parser.add_argument('--build-engines') # 定义太晚 # 正确顺序 parser.add_argument('--build-engines') # 先定义 args = parser.parse_args() # 后解析[^3] ``` #### 3. **名称不一致** 检查参数名称是否完全匹配(注意大小写和中划线): ```python # 定义时使用下划线 parser.add_argument('--build_engines') # 使用下划线 # 调用时使用中划线(导致错误) python script.py --build-engines # 应改为 --build_engines ``` #### 4. **子命令未定义参数** 如果使用子命令解析器,需在对应子命令中添加参数: ```python parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() # 在build子命令中定义参数 build_parser = subparsers.add_parser('build') build_parser.add_argument('--build-engines') # 正确的定义位置[^3] ``` #### 5. **环境干扰问题** 当在Jupyter中运行时,内核可能注入额外参数: ```python # 错误信息示例(Jupyter注入额外参数) ipykernel_launcher.py: error: unrecognized arguments: -f /path/to/kernel.json [^5] # 解决方案:显式指定参数解析范围 args = parser.parse_known_args()[0] # 忽略未知参数[^1] ``` #### 调试步骤: 1. **打印已定义参数**: ```python print(parser._actions) # 显示所有已注册参数 ``` 2. **最小化测试**: ```bash python deepseek_python_20251031_116acc.py --help # 检查--build-engines是否在帮助中 ``` 3. **检查参数类型**: ```python # 需要值的参数需指定type parser.add_argument('--build-engines', type=int) # 要求整数值 ``` > **关键提示**:90%的此类错误源于参数定义缺失或名称不匹配。优先检查脚本中是否存在 `parser.add_argument('--build-engines')` 的定义[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值