• NLP gensim 相似度计算


    from collections import defaultdict
    from gensim import corpora
    import jieba
    from gensim import similarities
    import re
    
    
    class Similarity:
    
        def docs(self, datas):
            # 构建主搜索索引
            docs = []
            for doc in datas:
                data = [i for i in jieba.cut(doc['title']) if i not in self.stop_words]
                docs.append(data)
                # print(data)
            dictionary = corpora.Dictionary(docs)
            corpus = [dictionary.doc2bow(doc) for doc in docs]
            lsi = similarities.MatrixSimilarity(corpus)
            return corpus, lsi
    
        def __init__(self, words=None, stop_words=None, degree=95, title_len=0.9):
            """
            :param words: 分词 中标 候选人 公示 结果 失败 成交供应商 询价 单一来源 采购 成交人 更正 比选 公告 招标
            :param stop_words: 停用词 中标 候选人 公示 结果 失败 成交供应商 询价 单一来源 采购 成交人 更正 比选 公告 招标 的 是 _
            :param degree: 文本相似度
            :param title_len: 匹配相似度之后,文本删除停用词之后的最短相同长度
            """
            words = set() if words is None else words
            for w in words:
                jieba.add_word(w)
            #  停用词
            self.stop_words = set() if stop_words is None else stop_words
            self.stop_params = re.compile("|".join(self.stop_words))
            # 相似度
            self.degree = degree
            self.title_len = title_len
    
        def handle(self, bid_datas, win_datas):
            """
            :param bid_datas: [{"id": id, "title": title}]
            :param win_datas: [{"id": id, "title": title}]
            :return: {"win_id": ["bid_id", "bid_id"]}
            """
            if len({i['id'] for i in bid_datas} & set({i["id"] for i in win_datas})) != 0:
                raise Exception("bid 和 win 的id重复了")
            merge_data = defaultdict(list)
            all_datas = []
            all_datas.extend(win_datas)
            all_datas.extend(bid_datas)
            corpus, lsi = self.docs(all_datas)
            
            win_len = len(win_datas)
            # 以中标数据为基准和招标数据进行匹配
            for i, corpus in enumerate(corpus[:win_len]):
                for j, v in [i for i in enumerate(lsi[corpus]) if i[0] >= win_len]:
                    # print(i, j - win_len, v)
                    if v * 100 - self.degree >= 0:
                        merge_data[i].append((j-win_len, v))
                        
            similary_data = defaultdict(list)
            for i, values in merge_data.items():
                source = win_datas[i]
                source_title = source['title']
                source_title = self.stop_params.sub("", source_title)
                if len(values) == 1:
                    similary_data[source['id']].append(bid_datas[values[0][0]]['id'])
                    continue
                for index, weight in values:
                    target_title = bid_datas[index]['title']
                    target_title = self.stop_params.sub("", target_title)
                    min_title = source_title if len(source_title) < len(target_title) else target_title
                    j = 0
                    for j in range(len(min_title)):
                        if source_title[j] != min_title[j]:
                            continue
                    if j >= len(min_title) * self.title_len:
                        similary_data[source['id']].append(bid_datas[index]['id'])
            return similary_data
    bid_datas = [
       
        {"id": 1, "title": "中国电信股份有限公司曲靖分公司“三供一业”供水管网改造工程招标代理的结果-采购项目中标公示"},
        {"id": 2, "title": "项目视图四象限图坐标轴调至中间"},
        {"id": 3, "title": "12345654564564"}
    ]
    win_datas = [
        
        {"id": 4, "title": "中国电信集团有限公司曲靖分公司“三供一业”供水管网改造工程招标代理的结果-采购项目招标公告"},
        {"id": 5, "title": "项目视图四象限图坐标轴调至中间"},
    ]
    words = set("中国电信股份有限公司 中国电信集团有限公司 中标 候选人 股份 公示 结果 失败 成交供应商 询价 单一来源 采购 成交人 更正 比选 公告 招标".split(" "))
    stop_words = set("中标 候选人 公示 结果 失败 成交供应商 询价 单一来源 采购 成交人 更正 比选 公告 招标 的 是 _ -".split(" "))
    datas = Similarity(words=words, stop_words=stop_words, degree=90).handle(bid_datas, win_datas)
    print("datas = ", datas)
    
  • 相关阅读:
    js属性对象的hasOwnProperty方法
    利用递归的方式在JSON 数据中找到某个节点的多有父节点
    数组中的方法 --- 不改变原数组的方法
    数组中的方法-- 会改变原数组的
    break continue return 的区别
    解决vue中对象属性改变视图不更新的问题
    怎么实现无痛刷新token
    正则的使用记录
    一级域名的登录信息在二级域名中获取
    没有什么问题是不能通过增加一个抽象层解决的
  • 原文地址:https://www.cnblogs.com/iFanLiwei/p/12885872.html
Copyright © 2020-2023  润新知