Okapi BM25。Rank-BM25提供了多种BM25算法, 如Okapi BM25,BM25L,BM25+等。它的使用也非常简单ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.1em;font-weight: bold;margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;border-left: 3px solid rgb(15, 76, 129);color: rgb(63, 63, 63);">安装ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;overflow-x: auto;border-radius: 8px;margin: 10px 8px;">pipinstallrank_bm25ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.1em;font-weight: bold;margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;border-left: 3px solid rgb(15, 76, 129);color: rgb(63, 63, 63);">初始化ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">以Okapi BM25为例ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;overflow-x: auto;border-radius: 8px;margin: 10px 8px;">fromrank_bm25importBM25Okapi
corpus=[
"Hellotheregoodman!",
"ItisquitewindyinLondon",
"Howistheweathertoday?"
]
#分词使用空格
tokenized_corpus=[doc.split("")fordocincorpus]
bm25=BM25Okapi(tokenized_corpus)ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.1em;font-weight: bold;margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;border-left: 3px solid rgb(15, 76, 129);color: rgb(63, 63, 63);">查询(文档排名)ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;overflow-x: auto;border-radius: 8px;margin: 10px 8px;">query="windyLondon"
tokenized_query=query.split("")
doc_scores=bm25.get_scores(tokenized_query)
#array([0.,0.93729472,0.])ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">?:Rank-BM25不做任何文本预处理。如果想要做诸如转换为小写、停用词移除、词干提取等操作,需要自己实现。所以如果要进行处理中文,就需要用到专业的中文分词器了。分词器是自然语言处理(NLP)中非常重要的工具,它们将连续的文本字符串分割成有意义的单元,通常是单词或短语。中文分词器的实现很多,如jieba,SnowNLP,THULAC,HanLP等,可以根据需要选择,这里就以jieba为例。
pipinstallnltkjieba
importnltk
nltk.download('stopwords')importjieba
fromtypingimportList
defchinese_tokenizer(text:str)->List[str]:
tokens=jieba.lcut(text)
return[tokenfortokenintokensiftokennotinstopwords.words('chinese')]
corpus=[
"床前明月光",
"疑是地上霜",
"举头望明月",
"低头思故乡",
]
tokenized_corpus=[chinese_tokenizer(doc)fordocincorpus]
bm25=BM25Okapi(tokenized_corpus)
query="床前明月光"
tokenized_query=chinese_tokenizer(query)
doc_scores=bm25.get_scores(tokenized_query)
doc_scores
#array([1.8621931,0.,0.,0.])BM25Retriever基于Rank-BM25,可以指定分词方法,如果不指定,则使用默认的tokenize_remove_stopwords。
fromnltk.stemimportPorterStemmer
deftokenize_remove_stopwords(text:str)->List[str]:
#lowercaseandstemwords
text=text.lower()
stemmer=PorterStemmer()
words=list(simple_extract_keywords(text))
return[stemmer.stem(word)forwordinwords]如果想使用前面定义的chinese_tokenizer, 只需这样做
fromllama_index.retrievers.bm25importBM25Retriever
fromllama_index.coreimportDocument
fromllama_index.core.node_parserimportSentenceSplitter
fromllama_index.core.response.notebook_utilsimportdisplay_source_node
documents=[Document(text="床前明月光"),
Document(text="疑是地上霜"),
Document(text="举头望明月"),
Document(text="低头思故乡")]
splitter=SentenceSplitter(chunk_size=1024)
nodes=splitter.get_nodes_from_documents(documents)
retriever=BM25Retriever.from_defaults(
nodes=nodes,
similarity_top_k=2,
tokenizer=chinese_tokenizer
)
nodes=retriever.retrieve("故乡")
fornodeinnodes:
display_source_node(node)昨天介绍了DuckDBRetriever, 它基于DuckDB fts,于是不可避免地有以下几个缺点,
1.不支持中文
2.不能增量更新,只能重建索引BM25Retriever的缺点是不能持久化,只能全部加载内存中。
有没有既可以持久化,又支持中文分词,并且可以对索引进行增加和删除的呢?
Okapi BM25,一般简称 BM25 算法,在 20 世纪 70 年代到 80 年代,由英国一批信息检索领域的计算机科学家发明。这里的 BM 是 “最佳匹配”(Best Match)的缩写,Okapi 是第一个使用这种方法的信息获取系统的名称。在信息检索领域,BM25 算法是工程实践中举足轻重的重要的 Baseline 算法。迄今为止距 BM25 的提出已经过去三十多年,但是这个算法依然在很多信息检索的任务中表现优异,是很多工程师首选的算法之一。
BM25(Best Match 25)是一种用于信息检索的统计算法,主要用于评估搜索词(query)和文档之间的相关性。它基于概率检索模型,通过计算查询词与文档之间的相关性得分来对文档进行排序。BM25算法的核心思想可以概括为以下几点:
1.查询词权重(IDF):BM25使用逆文档频率(Inverse Document Frequency,IDF)来衡量查询词的重要性。IDF的计算公式为:
其中,(N)是文档集合中的文档总数,(n(qi))是包含查询词(qi)的文档数量。IDF值越高,表示查询词在文档集合中越稀有,其权重越大。
2.词频和文档长度的标准化:BM25考虑到词频(TF)与相关性之间的关系是非线性的。为了平衡词频对得分的影响,引入了饱和函数和文档长度因子。标准化后的词频公式为:
其中,(tf(qi, d))是查询词在文档中的词频,(Ld)是文档长度,(Lavg)是文档集合中所有文档的平均长度,(k1)和(b)是调节参数。
3.查询词频率的加权:如果查询较长,某些词在查询中出现频率较高,BM25还会考虑这些词在查询中的频率,通过引入另一个调节参数(k3)来调整查询词频率对得分的影响。
4.最终得分计算:BM25的最终得分是查询中每个词与文档相关性得分的加权和。公式为:
其中,(R(qi, d))是查询词(qi)与文档(d)的相关性得分。
BM25算法因其简单、高效且效果良好,在搜索引擎和信息检索系统中得到了广泛应用。它的参数(k1)、(b)和(k3)可以根据具体应用场景进行调整,以达到最佳的检索效果。
| 欢迎光临 链载Ai (https://www.lianzai.com/) | Powered by Discuz! X3.5 |