自己手書きBM 25アルゴリズム
2349 ワード
pythonはBM 25アルゴリズムを実現する
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/7/30 20:50
# @Author : fuGuoWen
# @Site :
# @File : test06.py
# @Software: PyCharm
import math
class BM25(object):
def __init__(self, docs):
"""
:param docs: list
"""
self.D = len(docs)
self.avgdl = sum([len(doc) + 0.0 for doc in docs]) / self.D
self.docs = docs
self.f = []
self.df = {}
self.idf = {}
self.k1 = 1.5
self.b = 0.75
self.init()
def init(self):
for doc in self.docs:
#
tmp = {}
for word in doc:
if not word in tmp:
tmp[word] = 0
tmp[word] += 1
self.f.append(tmp)
for k, v in tmp.items():
if k not in self.df:
self.df[k] = 0
self.df[k] += 1
for k, v in self.df.items():
# self.idf[k] = math.log(self.D - v + 0.5) - math.log(v + 0.5)
self.idf[k] = math.log(self.D +1) - math.log(v + 0.5)
def sim(self, doc, index):
"""
:param doc:
:param index:
:return:
"""
score = 0
for word in doc:
if word not in self.f[index]:
continue
d = len(self.docs[index])
score += (self.idf[word] * self.f[index][word] * (self.k1 + 1)
/ (self.f[index][word] + self.k1 * (1 - self.b + self.b * d
/ self.avgdl)))
return score
def simall(self, doc):
"""
:param doc: list
:return:
"""
scores = []
for index in range(self.D):
score = self.sim(doc, index)
scores.append(score)
return scores
if __name__ == '__main__':
corpus = [
['hello','world','hello'],['hello','go']
]
bm=BM25(corpus)
#
print(bm.f)
#
print(bm.df)
print(bm.idf)
scores=bm.simall(['hello'])
print(scores)