BM25(Best Matching 25)是一种用于信息检索(Information Retrieval)和文本挖掘的算法,它被广泛应用于搜索引擎和相关领域。BM25 基于 TF-IDF(Term Frequency-Inverse Document Frequency)的思想,但对其进行了改进以考虑文档的长度等因素。
一.基本思想
以下是 BM25 算法的基本思想:
-
TF-IDF 的改进: BM25 通过对文档中的每个词项引入饱和函数(saturation function)和文档长度因子,改进了 TF-IDF 的计算。 -
饱和函数: 在 BM25 中,对于词项的出现次数(TF),引入了一个饱和函数来调整其权重。这是为了防止某个词项在文档中出现次数过多导致权重过大。 -
文档长度因子: BM25 考虑了文档的长度,引入了文档长度因子,使得文档长度对权重的影响不是线性的。这样可以更好地适应不同长度的文档。
二.计算方程
BM25 的具体计算公式如下:
其中:
-
是查询中的词项数。 -
是查询中的第个词项。 -
是逆文档频率,计算方式通常是,其中是文档总数, 是包含词项的文档数。 -
是词项在文档 中的出现次数(TF)。 -
是文档 的长度。 -
是所有文档的平均长度。 -
和 是调整参数,通常设置为 和 。
BM25 算法的实现通常用于排序文档,使得与查询更相关的文档排名更靠前。在信息检索领域,BM25 已经成为一个经典的算法。
三.Python 实现
以下是一个简单的 Python 实现 BM25 算法的例子。请注意,实际应用中可能需要进行更复杂的文本预处理,例如去除停用词、词干化等。
importmath
fromcollectionsimportCounter
classBM25:
def__init__(self,corpus,k1=1.5,b=0.75):
self.k1=k1
self.b=b
self.corpus=corpus
self.doc_lengths=[len(doc)fordocincorpus]
self.avg_doc_length=sum(self.doc_lengths)/len(self.doc_lengths)
self.doc_count=len(corpus)
self.doc_term_freqs=[Counter(doc)fordocincorpus]
self.inverted_index=self.build_inverted_index()
defbuild_inverted_index(self):
inverted_index={}
fordoc_id,doc_term_freqinenumerate(self.doc_term_freqs):
forterm,freqindoc_term_freq.items():
iftermnotininverted_index:
inverted_index[term]=[]
inverted_index[term].append((doc_id,freq))
returninverted_index
defidf(self,term):
doc_freq=len(self.inverted_index.get(term,[]))
ifdoc_freq==0:
return0
returnmath.log((self.doc_count-doc_freq+0.5)/(doc_freq+0.5)+1.0)
defbm25_score(self,query_terms,doc_id):
score=0
doc_length=self.doc_lengths[doc_id]
forterminquery_terms:
tf=self.doc_term_freqs[doc_id].get(term,0)
idf=self.idf(term)
numerator=tf*(self.k1+1)
denominator=tf+self.k1*(1-self.b+self.b*(doc_length/self.avg_doc_length))
score+=idf*(numerator/denominator)
returnscore
defrank_documents(self,query):
query_terms=query.split()
scores=[(doc_id,self.bm25_score(query_terms,doc_id))fordoc_idinrange(self.doc_count)]
sorted_scores=sorted(scores,key=lambdax:x[1],reverse=True)
returnsorted_scores
#Exampleusage
corpus=[
"Thequickbrown服务器托管网foxjumpsoverthelazydog",
"Aquickbrowndogoutpacesaswiftfox",
"Thedogislazybutthefoxisswift",
"Lazydogsandswiftfoxes"
]
bm25=BM25(corpus)
query="quickbrowndog"
result=bm25.rank_documents(query)
print("BM25Scoresforthequery'{}':".format(query))
fordoc_id,scoreinresult:
print("Document{}:{}".format(doc_id,score))
此代码创建了一个简单的 BM25 类,通过给定的语料库计算查询与文档的相关性得分。
NLP工程化
1.本公众号以对话系统为中心,专注于Python/C++/CUDA、ML/DL/RL和NLP/KG/DS/LLM领域的技术分享。
2.本公众号Roadmap可查看飞书文档:https://z0yrmerhgi8.feishu.cn/wiki/Zpewwe2T2iCQfwkSyMOcgwdInhf
NLP工程化
飞书文档
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用服务器托管网,IDC机房托管, http://www.fwqtg.net
OSPF高级特性 一、OSPF_提升故障收敛及网络恢复速度 1.FRR与BFD快速恢复故障 1.1 FRR 在传统转发模式下,当到达同一个目的网络存在多条路由时,路由器总是选择最优路由使用,并且下发到FIB表指导数据转发。 当最优路由故障时,需要等待路由收敛完…