python 小白实现搜索引擎匹配模式

需求

部门需要实现一个匹配规则,例如 输入 格力空调维修 可以检索到格力空调维修电话、格力空调上面维修服务等等 和输入的关键词相关的数据库中的文章 类似于一个搜索引擎的检索模式

试过的方法

1、jieba+re

当时提出找个需求的时候 我的大概思路是 先对输入的关键词进行分词处理 然后对拿到的词写正则规则 进行查询 但是后来发现效果不太理想,总会匹配出其他不相关的标题 当然也有很大一部分原因是因为我的正则写得不够完善,但是 如果是将所有情况都写入的话 那是一个比较浩大的工程了 找个方案直接被我抛弃

2、synonyms判断句子相关度

import synonyms
def judge_similarity(k1, k2):
    r = synonyms.compare(k1, k2, seg=True)
    return r

传入K1,K2这两个句子 会返回他们俩的相关度 这个方法可以粗略的实现需求,根据需求对返回的相关系数进行判断可以自己设置一个阈值,但是依旧会发生匹配得不够准确的情况,例如 空调维修 和车载空调维修,这并不是希望看到的结果,这种方案可以当做一个备选方案

最终实现

思路

某一天早上 需求方来问这个功能的进度,我当时心中苦不堪言,PHP都有专门的框架可以实现这个功能,但是python没有(可能有 但是我没找到0.0),人家度娘这么大个团队弄的东西让我一个才毕业没多久的小白来弄,有过两个方案效果还不太好,在和需求方解(狡)释(辩)的过程当中我突然灵机一动,想到了第三种方案。
jieba的分词结果对相同的词是一样的,就比如 格力空调 使用搜索引擎的分割方式会得到
[格力,空调,格力空调]
这三个词语,只要这四个字出现在关键词或者标题当中 而不用担心 这四个字出现在什么地方
,比如格力空调维修 和 维修格力空调 分词的结果必定相同,直接对关键词和标题的分词结果进行比对 可以排除一些因为语序上的不同,而导致的完全匹配不能匹配出来的情况,为了方便对结果集进行比较 我将分词之后的结果转换为了集合而不是list

在实现了上诉功能后,会得到两个结果集,这两个结果集合 分别为A,B 我大致分为了一下几种情况:
1、子集于父集合关系 (一个是另一个的子集)
2、不是子集与父集关系,但是有交集
3、不是子集与父集关系,也没用交集
分别探讨一下这几种情况:
情况1:
关键词和标题是包含关系,关键词包含标题或者标题包含关键词 这种情况是我希望看到的
例如: 格力空调 和 格力空调维修
情况2:
关键词和标题有交集 证明有重复的字出现,但是又有分别的特征,两个句子是否讲诉的同一件事不得而知 例如 格力空调漏水 和 格力空调外机坏了
情况3:
完全不相关 例如: 格力空调 TCL电视这种情况

问题1:有近义描述

在我的文章库当中 有很多 XXX怎么解决、XXX如何解决 ,XXX怎么办这样的东西 我们关心的只是XXX的内容 后面的副词和语气助词我们并不关心,所以我根据自己的文章库 将常见的一些没用的词进行了剔除,删除掉 怎么,如何,为什么,怎么办…这些词语把他们定为了一个屁话集(没错 在我看来这些词就是屁话)

问题2:小瑕疵

在上面的讨论当中 第一种情况 假设A是keyword的结果集 B是title的结果集有两种情况
1、A包含B 2、B包含A 如果A包含B是我能接受的 这种情况表示查询的关键词比这个文章的标题更加的详细 就比如 格力空调外机清洗 和 格力空调清洗 这是我可以接受的结果
第二种情况 :B包含A 这种情况表示文章的标题比我给定的更加详细 有一定的误差 因此我构建了一个not_like 记录这种情况 差集当中如果出现not_like里的词语 就默认他们不相关

demo

import jieba
from parsedata.tools import SQLDB


class mySql(SQLDB):
    def read(self):
        sql = 'SELECT * FROM keywords'
        cur = self.db.cursor()
        cur.execute(sql)
        # infos = cur.fetchall()
        for i in cur.fetchall():
            title, *_ = i
            yield title

def parseword(word):
    pihua = ['被', '了', '怎么', '怎么办', '?', '什么', '如何', '的', '原因', '为何', '回事', '解决', '是', '和', '问题', '维修', '修', '修理', '正确',
             '哪些', '咋', '怎么回事', '?', '为什么', '}', '{', '多少', '不', '怎样', '好', '办法', '专业', '附近', '方法']
    remove_list = []
    word = word.strip().replace(' ', '')
    cword = jieba.lcut_for_search(word)
    for word in cword:
        if word in pihua:
            remove_list.append(word)
    if remove_list:
        for word in remove_list:
            cword.remove(word)
    return set(cword)


def run(keyword):
    cword = parseword(keyword)
    for title in db.read():
        a = parseword(title)
        if cword >= a:
            # print('原标题: {}----->{}     {} >= {}'.format(keyword, title, cword, a))
            return title
        elif cword <= a:
            not_like = ['制冷', '打孔', '清洗', '修理', '堵塞', '安装', '疏通', '加氟', '拆卸', '拆盖', '改', '拆洗']
            Difference_set = list(a - cword)
            flag = False
            # print('!!! 丝毫不相干:{}   |   {}'.format(keyword, title))
            for i in Difference_set:
                if i in not_like:
                    flag = True
                    break
            if flag:
                pass
            else:
                # print('差集:{}      title1:{}    title2:{}'.format(a - cword, keyword, title))
                return title
        # else:
        #     print('丝毫不相干:{}   |   {}'.format(keyword, title))


if __name__ == '__main__':
    db = mySql()
    keyword = 'TCL冰箱如何正确清洗'
    word = run(keyword)
    print(word)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值