IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> django_实现朴素/基本模糊单词拼写候选/纠错api -> 正文阅读

[Python知识库]django_实现朴素/基本模糊单词拼写候选/纠错api

django_实现朴素/基本模糊拼写候选/纠错

这只是一个粗糙的玩具,不具备智能性

使用到的拼写数据库支持(一角)

在这里插入图片描述

数据库模型

from django.db.models.functions import Length
CharField.register_lookup(Length)

class WordMatcher(models.Model):
    """词典升级的时候,模糊匹配的词典也需要一并升级!!!!"""
    spelling = models.CharField(max_length=255)
    char_set = models.CharField(max_length=26)
    # word_length = models.IntegerField(default=0)
    #    django提供了类似的Length的数据库函数,长度子字段可以不需要存储(本身也不是一个好主意)
    def __str__(self):
        return str([self.spelling,self.char_set])

Words词典

在这里插入图片描述

char_set字段的计算(数据库的产生)

wob = Word.objects
class UpdateWordMatcher:
	
    # 填充单词模糊匹配数据库支持(模糊推荐算法)
    # 测试两个例子
    def update(self):
        # sub_dict_set = wob.all()
        sub_dict_set = wob.all()[:2]
        for item in sub_dict_set:
            # print(item)
            char_set = set(item.spelling)
            chars = list(char_set)
            chars.sort()
            chars_str = "".join(chars)
            # return chars_str
            print(chars_str)
            d = {"spelling": item.spelling, "char_set": chars_str}
            wmob.create(**d)
            # chars=list(char_set).sort()
            # print(chars)

序列化器

class WordMatcherModelSerializer(ModelSerializer):
    class Meta:
        model=WordMatcher
        fields = "__all__"

参考代码

Serialzier部分是使用了Django_DRF框架的序列化器

class WordMatcherViewSet(ModelViewSet):
    """ 模糊匹配数据库"""
    wmob = WordMatcher.objects
    queryset = wmob.all()
    serializer_class = WordMatcherModelSerializer
    #filter_fields = ['spelling', 'char_set']
    def fuzzy_match(self, req, spelling, start_with=0):
        """

        :param req:
        :type req:
        :param spelling:
        :type spelling:
        :param start_with:匹配开头的字符串长度 (default: {0},表示没有被强制规定)
        :type start_with:
        :return:
        :rtype: Response
        """

        spelling_len = len(spelling)
        # 根据模糊拼写的长度,选择一个较为合适的start_with
        if(start_with==0):
            #没有被强制设值
            # 启用内部判断取值
            if(spelling_len>4):
                start_with=2
            else:
                start_with=1
        # 获得模糊拼写的字母集合
        spelling_char_set = set(spelling)
        # 获取模糊拼写的字母集列表(字母集合去重后转换为列表)
        spelling_char_list = list(spelling_char_set)
        # 对字母集合转成的列表进行排序
        spelling_char_list.sort()
        spelling_char_set_str = "".join(spelling_char_set)
        spelling_char_set_len = len(spelling_char_set)
        # print("@spelling_chars:", spelling_char_set_str)
        # 定义匹配的单词的长度范围
        left_len = spelling_len * 0.70
        # right_len = spelling_len * 1.25
        right_len = spelling_len * 1.4
        if spelling_len >= 4:
            right_len = spelling_len * 2

        # 模糊匹配
        # queryset = self.get_queryset().filter(spelling__length__gte=left_len) & self.get_queryset().filter(
        #     spelling__length__lte=right_len) & self.queryset.filter(char_set__contains=spelling_chars)
       
        """限制单词长度"""
        queryset = self.queryset.filter(spelling__length__gte=left_len) & self.queryset.filter(
            spelling__length__lte=right_len)
        # 匹配开头(严格模式)(可以额外设置变量,追加if)
        # print(queryset)
        # 匹配发音:mysql中有一个soundx函数,
        queryset = queryset.filter(spelling__startswith=spelling[:start_with])
        """限制单词字符集规模的差异"""
        # 10:14(5:7);
        # 10:16(5:8);
        queryset = queryset.filter(char_set__length__lte=1.25 * spelling_char_set_len)
        # 3:5;
        # 4:5
        queryset = queryset.filter(char_set__length__gte=0.6 * spelling_char_set_len)

        """匹配字符组成(最后一步)"""
        # 方案0:使用icontains函数来匹配(无法匹配到替换了个别字母的形近词!
        ## 可以引入随机剔除字符操作
        # 方案1:双向包含(或运算)(比上衣种情况稍好,但还是无法满足需求)
        # 方案2:差集(限制差集中的元素个数)(容错个别字母(种类)的不同)
        # queryin = queryset.filter(char_set__in=spelling_chars)
        # print("@queryin:", queryin)
        # queryset = queryset.filter(Q(char_set__contains=spelling_chars) | Q(char_set__in=spelling_chars))
        items = []
        for item in queryset:
            item_char_set_len = len(item.char_set)
            item_spelling_len = len(item.spelling)
            intersection = set(item.char_set) & set(spelling_char_set)
            intersection_len = len(intersection)
            # if (item.spelling == "dad"):
            #     print("dad", diff, len(diff), item, spelling_chars_len * 0.5)
            #     # print()
            if (spelling_len >= 5):
                if (intersection_len >= spelling_char_set_len * 0.8 and intersection_len >= item_char_set_len * 0.8):
                    # if (item.spelling == "dad"):
                    # print(item, diff)
                    items.append(item)
            elif (intersection == spelling_char_set):
                #     长度小于5的输入,我们只需要检查是否包含全部字符即可
                # else:
                print("@intersection", intersection)
                print("@spelling_char_set", spelling_char_set)
                print(item, intersection, spelling_char_set_len)
                if (item_spelling_len == spelling_len):
                    items.append(item)

        # print(queryset)
        items.sort(key=lambda x:x.spelling)
        print(len(items))
        return Res(self.serializer_class(instance=items, many=True).data)
        # return Res(self.serializer_class(instance=queryset, many=True).data)

    def fuzzy_match_simple(self, req, spelling):
        return self.fuzzy_match(req, spelling)

路由

    path('fuzzy/<str:spelling>/', views.WordMatcherViewSet.as_view({
        "get": "fuzzy_match_simple"
    })),
    path('fuzzy/<str:spelling>/<int:start_with>/', views.WordMatcherViewSet.as_view({
        "get": "fuzzy_match"
    })),

api基本效果

eg0:

在这里插入图片描述

eg1:

在这里插入图片描述

eg2

GEThttp://127.0.0.1:8000/word/fuzzy/fhather/1
在这里插入图片描述

项目地址

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-19 11:55:12  更:2022-05-19 11:55:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 14:08:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码