BM25算法——(他人写)

import math
import jieba


class BM25(object):

    def __init__(self, docs):
        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 = {}  # 存储每个词的idf值
        self.k1 = 1.5
        self.b = 0.75
        self.init()

    def init(self):
        for doc in self.docs:
            tmp = {}
            for word in doc:
                tmp[word] = tmp.get(word, 0) + 1  # 存储每个文档中每个词的出现次数
            self.f.append(tmp)
            for k in tmp.keys():
                self.df[k] = self.df.get(k, 0) + 1
        for k, v in self.df.items():
            self.idf[k] = math.log(self.D - v + 0.5) - math.log(v + 0.5)

        for key, value in self.__dict__.items():
            print(key, value)

    def sim(self, doc, index):
        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, query_list):
        sim_dict = {}

        # 遍历所有的候选文章,计算每个文章与querey的score
        for index in range(self.D):
            # 查询的每个语素,计算每个语素与该句子的score
            score = 0
            for query in query_list:
                # 每个语素的idf
                if query in self.idf:
                    quer_idf = self.idf[query]
                else:
                    quer_idf = 0
                # 计算R
                if query in self.f[index]:
                    f_i = self.f[index][query]
                else:
                    f_i = 0
                R = (f_i * (self.k1 + 1)) / (f_i + self.k1 * (1 - self.b + self.b * len(self.docs[index]) / self.avgdl))
                # 计算idf*R
                sim = quer_idf * R
                score += sim
            if score != 0:
                sim_dict[score] = index

        sim_dict = sorted(sim_dict.items(), key=lambda item: item[0], reverse=True)
        return sim_dict


if __name__ == '__main__':

    sents = []
    sents.append("自然语言自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。")
    sents.append("它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。")
    sents.append("自然语言处理是一门融语言学、计算机科学、数学于一体的科学。")
    sents.append("因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,")
    sents.append("所以它与语言学的研究有着密切的联系,但又有重要的区别。")
    sents.append("自然语言处理并不是一般地研究自然语言,")
    sents.append("而在于研制能有效地实现自然语言通信的计算机系统,")
    sents.append("特别是其中的软件系统。因而它是计算机科学的一部分。")

    # 分词并剔除停用词
    docs = []
    for sent in sents:
        words = list(jieba.cut(sent))
        new_words = []
        for word in words:
            if word not in [",", "。", "的", "而", "是", "与", "中", "它", "能"]:
                new_words.append(word)
        docs.append(new_words)
    s = BM25(docs)

    print()
    list1 = ['自然语言', '计算机科学', '人工智能', '领域']  # 分词之后的list
    sim_dict = s.simall(list1)
    for score, index in sim_dict:
        print(score, sents[index])
D 8
avgdl 10.125
docs [['自然语言', '自然语言', '处理', '计算机科学', '领域', '人工智能', '领域', '一个', '重要', '方向'], ['研究', '实现', '人', '计算机', '之间', '用', '自然语言', '进行', '有效', '通信', '各种', '理论', '和', '方法'], ['自然语言', '处理', '一门', '融', '语言学', '、', '计算机科学', '、', '数学', '于', '一体', '科学'], ['因此', '这一', '领域', '研究', '将', '涉及', '自然语言', '即', '人们', '日常', '使用', '语言'], ['所以', '语言学', '研究', '有着', '密切', '联系', '但', '又', '有', '重要', '区别'], ['自然语言', '处理', '并', '不是', '一般', '地', '研究', '自然语言'], ['在于', '研制', '有效', '地', '实现', '自然语言', '通信', '计算机系统'], ['特别', '其中', '软件系统', '因而', '计算机科学', '一部分']]
f [{'自然语言': 2, '处理': 1, '计算机科学': 1, '领域': 2, '人工智能': 1, '一个': 1, '重要': 1, '方向': 1}, {'研究': 1, '实现': 1, '人': 1, '计算机': 1, '之间': 1, '用': 1, '自然语言': 1, '进行': 1, '有效': 1, '通信': 1, '各种': 1, '理论': 1, '和': 1, '方法': 1}, {'自然语言': 1, '处理': 1, '一门': 1, '融': 1, '语言学': 1, '、': 2, '计算机科学': 1, '数学': 1, '于': 1, '一体': 1, '科学': 1}, {'因此': 1, '这一': 1, '领域': 1, '研究': 1, '将': 1, '涉及': 1, '自然语言': 1, '即': 1, '人们': 1, '日常': 1, '使用': 1, '语言': 1}, {'所以': 1, '语言学': 1, '研究': 1, '有着': 1, '密切': 1, '联系': 1, '但': 1, '又': 1, '有': 1, '重要': 1, '区别': 1}, {'自然语言': 2, '处理': 1, '并': 1, '不是': 1, '一般': 1, '地': 1, '研究': 1}, {'在于': 1, '研制': 1, '有效': 1, '地': 1, '实现': 1, '自然语言': 1, '通信': 1, '计算机系统': 1}, {'特别': 1, '其中': 1, '软件系统': 1, '因而': 1, '计算机科学': 1, '一部分': 1}]
df {'自然语言': 6, '处理': 3, '计算机科学': 3, '领域': 2, '人工智能': 1, '一个': 1, '重要': 2, '方向': 1, '研究': 4, '实现': 2, '人': 1, '计算机': 1, '之间': 1, '用': 1, '进行': 1, '有效': 2, '通信': 2, '各种': 1, '理论': 1, '和': 1, '方法': 1, '一门': 1, '融': 1, '语言学': 2, '、': 1, '数学': 1, '于': 1, '一体': 1, '科学': 1, '因此': 1, '这一': 1, '将': 1, '涉及': 1, '即': 1, '人们': 1, '日常': 1, '使用': 1, '语言': 1, '所以': 1, '有着': 1, '密切': 1, '联系': 1, '但': 1, '又': 1, '有': 1, '区别': 1, '并': 1, '不是': 1, '一般': 1, '地': 2, '在于': 1, '研制': 1, '计算机系统': 1, '特别': 1, '其中': 1, '软件系统': 1, '因而': 1, '一部分': 1}
idf {'自然语言': -0.9555114450274362, '处理': 0.4519851237430572, '计算机科学': 0.4519851237430572, '领域': 0.9555114450274362, '人工智能': 1.6094379124341003, '一个': 1.6094379124341003, '重要': 0.9555114450274362, '方向': 1.6094379124341003, '研究': 0.0, '实现': 0.9555114450274362, '人': 1.6094379124341003, '计算机': 1.6094379124341003, '之间': 1.6094379124341003, '用': 1.6094379124341003, '进行': 1.6094379124341003, '有效': 0.9555114450274362, '通信': 0.9555114450274362, '各种': 1.6094379124341003, '理论': 1.6094379124341003, '和': 1.6094379124341003, '方法': 1.6094379124341003, '一门': 1.6094379124341003, '融': 1.6094379124341003, '语言学': 0.9555114450274362, '、': 1.6094379124341003, '数学': 1.6094379124341003, '于': 1.6094379124341003, '一体': 1.6094379124341003, '科学': 1.6094379124341003, '因此': 1.6094379124341003, '这一': 1.6094379124341003, '将': 1.6094379124341003, '涉及': 1.6094379124341003, '即': 1.6094379124341003, '人们': 1.6094379124341003, '日常': 1.6094379124341003, '使用': 1.6094379124341003, '语言': 1.6094379124341003, '所以': 1.6094379124341003, '有着': 1.6094379124341003, '密切': 1.6094379124341003, '联系': 1.6094379124341003, '但': 1.6094379124341003, '又': 1.6094379124341003, '有': 1.6094379124341003, '区别': 1.6094379124341003, '并': 1.6094379124341003, '不是': 1.6094379124341003, '一般': 1.6094379124341003, '地': 0.9555114450274362, '在于': 1.6094379124341003, '研制': 1.6094379124341003, '计算机系统': 1.6094379124341003, '特别': 1.6094379124341003, '其中': 1.6094379124341003, '软件系统': 1.6094379124341003, '因而': 1.6094379124341003, '一部分': 1.6094379124341003}
k1 1.5
b 0.75

2.072939365988203 自然语言自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。
0.5534511719302742 特别是其中的软件系统。因而它是计算机科学的一部分。
-0.46479352733942675 自然语言处理是一门融语言学、计算机科学、数学于一体的科学。
-0.8151282469428366 它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。
-1.0551660129137332 而在于研制能有效地实现自然语言通信的计算机系统,
-1.4637622136590513 自然语言处理并不是一般地研究自然语言,

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YJII

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值