python - 为什么 whoosh Search 在 sklearn 中的性能比 tfidfvectorizer 差?
问题描述
我实现了一个基本的(几乎所有默认选项)基于 TF-IDF 矢量化器(sklearn)的搜索程序,以根据用户查询搜索一些文档。
我也尝试在 python 中使用 Whoosh 来实现相同的功能。虽然独立的 tfidfvectorizer 实现会为同一个查询返回许多直观的结果,但 whoosh 查询只返回一个。(当我尝试在更多字段中搜索并归结为 0 个结果时,这也消失了)。我想知道我在这里做错了什么?
我已经尝试根据 whoosh 文档适当地设置 whoosh searcher 中的评分。
with myindex.searcher(weighting=scoring.TF_IDF()) as s:
有了这个,我认为它应该给出与 TF-IDF 矢量化器的 sklearn 实现有些相似的结果,但只返回一次命中。我如何获得类似的结果,即在 whoosh 中使用类似于 sklearns TF-IDF 矢量化器实现的东西。
此外,当我使用多个字段
MultifieldParser(["title", "content", "tags", "categories"], ix.schema)
而不是仅使用单个字段“内容”进行搜索时,结果是没有命中。
架构:
schema = Schema(id = NUMERIC,
title = TEXT(field_boost=2.0, stored=True, analyzer = StandardAnalyzer(minsize = 1)),
content = TEXT(stored=False, analyzer = StemmingAnalyzer(minsize = 1)),
permalink = ID(stored=True),
tags = KEYWORD(field_boost=2.0,lowercase=True, commas=True, scorable=True, stored = True),
categories = KEYWORD(field_boost=2.0,lowercase=True, commas=True, scorable=True, stored = True),
pub_date = DATETIME(stored = True),
creator = TEXT(stored=False)
)
搜索:
writer = ix.writer()
for i in range(len(df)):
writer.add_document(id = df["ID"][i], title = df["Title"][i], content=df["Content"][i],
permalink = df["Permalink"][i], tags = df["Tag"][i], categories = df["Category"][i],
pub_date = df["PubDate"][i], creator = df["Creator"][i])
writer.commit()
with ix.searcher(weighting=scoring.TF_IDF()) as searcher:
parser = MultifieldParser(["title", "content", "tags", "categories"], ix.schema)
query_string = sys.argv[2]
myquery = parser.parse(query_string)
results = searcher.search(myquery, limit = 10, terms = True)
print(len(results))
for i in range(results.scored_length()):
print(results[i])
print()
print("\n")
该代码确实有效并且还获取结果。我面临的唯一问题是,与 TF-IDF 实现相比,它们似乎缺乏,并且在大多数情况下返回的结果也更少(问题不在于 whoosh 搜索中的限制属性)。我想知道如何在嗖嗖声中获得更好的结果或结果评分,以及为什么它返回的结果比正常实现少。
查询“如何编码?”的输出示例 TF-IDF(sklearn):
30 Tips to Become Super Effective Software Developers
(Cosine Similarity of 0.3783876779183675 ):
Automation and Continuous Delivery are the bedrock of DevOps
(Cosine Similarity of 0.1476918570123896 ):
Practical Implementation of DevOps Step by Step
(Cosine Similarity of 0.1469115686911894 ):
10 Software Development Frustrations & What You Can Do To Avoid Them!
(Cosine Similarity of 0.13241987064219532 ):
WHOOSH(仅在内容字段中搜索时。否则返回 0 次点击):
<Hit {'title': 'Ultimate List of 110 Must Read Software Development Books'}>
编辑:我刚刚再次运行代码,发现如果我删除“?” 从查询“如何编码?” 并且仅在“标题”和“内容”中搜索,它会返回很多结果,而且它们看起来也更好。虽然只要我在要搜索的字段中包含“标签”和“类别”,结果就会变为 0。这是为什么呢?
解决方案
? 被视为通配符。我现在正在玩嗖嗖声,并注意到:
query = QueryParser("content", ix.schema).parse("one")
我得到:
<Top 1 Results for Term('content', 'one') runtime=0.0006002392619848251>
如果我搜索一个?:
query = QueryParser("content", ix.schema).parse("one?")
我得到:
<Top 0 Results for Wildcard('content', 'one?') runtime=0.0002482738345861435>
正如您在第二个示例中看到的,返回的对象是通配符。在此处阅读更多信息:https ://whoosh.readthedocs.io/en/latest/querylang.html#inexact-terms
推荐阅读
- r - 在 R 中使用 split() 后将观察结果制成表格的惯用方法
- php - 试图从数组php内部访问数据
- reactjs - 如何将 component 属性与自定义组件一起使用?
- windows - 无法在 Windows Powershell 上使用 cd。找不到路径
- javascript - 如何使用 jQuery DataTables 过滤某些列
- python - Python tkinter 列表框绑定
仅适用于第二次点击 - amazon-web-services - 如何在 Cloudformation 中根据 vCPU 或内存指定 AWS Spot 队列的目标容量?
- algorithm - 是否有动态生成迷宫的算法,确保总是有更多的地方可以去?
- javascript - pattern() 函数和 onkeyup() 函数不能一起工作
- google-calendar-api - 谷歌日历请求出现 500 错误