模糊搜索:在不确定性中寻找精确结果

目录

模糊搜索:在不确定性中寻找精确结果

一、引言

二、模糊搜索的背景

三、模糊搜索的原理

[1、编辑距离(Levenshtein Distance):](#1、编辑距离(Levenshtein Distance):)

[2、Jaccard 相似系数:](#2、Jaccard 相似系数:)

[3、Soundex 算法:](#3、Soundex 算法:)

4、TF-IDF(词频-逆文档频率)和余弦相似度:

四、模糊搜索的简单实现方式

1、数据库中的模糊搜索

2、使用编辑距离的模糊搜索

3、支持拼音和多音字的模糊匹配

4、动态词库和分词模糊搜索

5、时间、地理位置约束的模糊搜索

6、使用自然语言处理库等实现语义搜索

五、总结


作者:watermelo37

涉及领域:Vue、SpingBoot、Docker、LLM、python等


温柔地对待温柔的人,包容的三观就是最大的温柔。


模糊搜索:在不确定性中寻找精确结果

一、引言

在我们日常生活和工作中,搜索功能无处不在。无论是在网页搜索、文件检索,还是数据库查询中,我们时常会因为拼写错误或信息不完整而无法找到需要的结果。模糊搜索(Fuzzy Search)应运而生,它通过识别与查询相似的词语来帮助我们获得更加灵活的搜索结果。本文将详细探讨模糊搜索的背景、原理、实现方式以及应用领域,帮助读者更深入理解这一基础且实用的技术。

二、模糊搜索的背景

模糊搜索的出现解决了传统精确搜索的局限性。通常情况下,精确搜索会严格匹配用户输入和数据内容,而忽略拼写错误、相似词语或复杂查询条件。然而,在实际应用中,数据往往不是完全一致的,如姓名、地址、商品描述等字段可能存在拼写错误、缩写、拼音差异等。模糊搜索的出现弥补了这种匹配漏洞,使得搜索功能更加"容错"。

应用背景举例:

  • 搜索引擎:用户可能会输入错误的关键词,而模糊搜索可以理解用户的真实意图。
  • 电商平台:帮助用户找到与拼写错误或相似词相关的商品。
  • 数据库查询:在需要模糊匹配的数据字段(如姓名、地址等)中有效查找相关内容。

三、模糊搜索的原理

模糊搜索的核心在于通过相似度计算来衡量两段文本的"接近程度",并根据预设的容差来判断是否符合搜索条件。以下是常用的模糊搜索算法原理:

1、编辑距离(Levenshtein Distance):

编辑距离是一种常用的相似度计算方法,它通过计算两字符串之间的插入、删除或替换的最小操作次数来衡量其相似程度。距离越小,字符串越相似。例如,"apple"与"aple"的编辑距离为1(删除一个字母"p")。

2、Jaccard 相似系数:

通过计算两个文本的交集与并集比例来衡量其相似度,通常适用于分析词组或短语的相似性。例如,在"apple pie"和"apple tart"两个短语中,相同单词"apple"占比较高,因此相似性较强。

3、Soundex 算法:

Soundex 是一种基于发音的相似性算法,常用于处理人名或发音相近的词语匹配。例如,"Smith"和"Smyth"使用 Soundex 可以匹配出相同的编码。

4、TF-IDF(词频-逆文档频率)和余弦相似度:

该方法通过词频和逆文档频率计算关键词权重,适合较长文本的模糊匹配。余弦相似度计算文本的向量夹角,以此判断文本间的相似性。

四、模糊搜索的简单实现方式

模糊搜索的实现通常结合特定的数据库、编程语言及框架。以下是几种常见的实现方式:

1、数据库中的模糊搜索

SQL 中的模糊匹配 :许多关系型数据库如 MySQL、PostgreSQL 支持 LIKE 和正则表达式匹配来进行模糊查询。例如:

sql 复制代码
SELECT * FROM products WHERE name LIKE '%apple%';

在此基础上,还能增加多字段、权重分配的模糊搜索。

例如在用户搜索书籍数据库时,输入的关键词可以匹配书名、作者、出版社、出版年份等多个字段,书名字段权重最高,作者次之,出版社和出版年份次之。关键词在不同字段中匹配的权重累加,以确定最终的排序。

这里可以使用 ElasticSearch 中的 multi_match ,并为每个字段设置权重。例如,书名设置为2倍权重,作者1.5倍。

javascript 复制代码
{
  "query": {
    "multi_match": {
      "query": "哈利波特",
      "fields": ["title^2", "author^1.5", "publisher"]
    }
  }
}

全文检索引擎:Elasticsearch、Solr 等全文检索引擎提供了丰富的模糊搜索支持,包含多种分词和相似度算法,适合处理海量数据。

2、使用编辑距离的模糊搜索

编辑距离算法较为经典,通常可以在 Python 等编程语言中使用。以下是一个简单的编辑距离实现:

python 复制代码
def levenshtein_distance(str1, str2):
    len_str1 = len(str1) + 1
    len_str2 = len(str2) + 1
    dp = [[0 for _ in range(len_str2)] for _ in range(len_str1)]

    for i in range(1, len_str1):
        dp[i][0] = i
    for j in range(1, len_str2):
        dp[0][j] = j

    for i in range(1, len_str1):
        for j in range(1, len_str2):
            cost = 0 if str1[i - 1] == str2[j - 1] else 1
            dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost)
    
    return dp[-1][-1]

# 示例
distance = levenshtein_distance("apple", "aple")
print(f"编辑距离: {distance}")

3、支持拼音和多音字的模糊匹配

在包含中文数据的 MongoDB 中,可以通过拼音分词和模糊搜索来实现拼音模糊匹配。例如搜索姓名时,可以接受拼音或汉字。

python 复制代码
from pypinyin import lazy_pinyin
from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['user_db']
collection = db['users']

def search_user(query):
    pinyin_query = ''.join(lazy_pinyin(query))  # 将查询内容转成拼音
    regex = f".*{pinyin_query}.*"
    
    results = collection.find({
        "$or": [
            {"name": {"$regex": regex, "$options": "i"}},  # 汉字字段匹配
            {"pinyin_name": {"$regex": regex, "$options": "i"}}  # 拼音字段匹配
        ]
    })
    return list(results)

4、动态词库和分词模糊搜索

在搜索菜单时,动态更新分词词库,将菜名分词后进行模糊搜索。例如,将"清炒小白菜""炒青椒"等关键词进行分词后模糊匹配(Python + Elasticsearch + Jieba 分词)。

javascript 复制代码
import jieba
from elasticsearch import Elasticsearch

# 自定义词典更新
jieba.add_word("清炒小白菜")
jieba.add_word("炒青椒")

# Elasticsearch 初始化
es = Elasticsearch()

def search_menu(query):
    query_tokens = jieba.lcut(query)  # 使用 Jieba 分词
    query_string = ' '.join(query_tokens)

    # Elasticsearch 查询
    response = es.search(
        index="menu",
        body={
            "query": {
                "match": {
                    "dish_name": {
                        "query": query_string,
                        "fuzziness": "AUTO"
                    }
                }
            }
        }
    )
    return response['hits']['hits']

# 示例查询
results = search_menu("炒青菜")
for result in results:
    print(result["_source"])

5、时间、地理位置约束的模糊搜索

可以通过Elasticsearch 地理位置和评分查询来获取离用户较近且评分较高的景点,结合 geo_distance 和评分 function_score 查询。

javascript 复制代码
POST /places/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "description": {
            "query": "热门景点",
            "fuzziness": "AUTO"
          }
        }
      },
      "functions": [
        {
          "gauss": {
            "location": {
              "origin": "40.7128,-74.0060",  // 用户当前位置
              "scale": "10km"
            }
          }
        },
        {
          "field_value_factor": {
            "field": "rating",
            "factor": 1.2,  // 评分加权
            "modifier": "sqrt"
          }
        }
      ],
      "boost_mode": "sum"
    }
  },
  "sort": [
    "_score"  // 结果按评分和距离组合排序
  ]
}

6、使用自然语言处理库等实现语义搜索

在需要更复杂的语义匹配时,可以借助 NLP 库,如 spaCy 或 Transformers,将文本嵌入向量空间后计算相似性,以实现语义层面的模糊搜索。

这里给一个基础的例子,利用 BERT 将输入语句与每个文档计算语义相似度,以找到更语义匹配的结果。以下示例使用 transformers 库实现。

python 复制代码
from transformers import BertTokenizer, BertModel
import torch
from scipy.spatial.distance import cosine

# 加载预训练模型和分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')

def get_sentence_embedding(sentence):
    inputs = tokenizer(sentence, return_tensors="pt")
    outputs = model(**inputs)
    return outputs.last_hidden_state.mean(dim=1).detach().numpy()

def search_documents(query, documents):
    query_embedding = get_sentence_embedding(query)
    results = []
    for doc in documents:
        doc_embedding = get_sentence_embedding(doc['content'])
        similarity = 1 - cosine(query_embedding, doc_embedding)
        results.append((doc, similarity))
    
    # 按相似度降序排序
    results = sorted(results, key=lambda x: x[1], reverse=True)
    return [doc for doc, score in results if score > 0.75]  # 设定相似度阈值

# 示例使用
documents = [
    {"content": "4K电视拥有超清晰的分辨率"},
    {"content": "液晶电视有多种型号"},
    {"content": "智能电视可以连接互联网"},
]
query = "高清电视"
results = search_documents(query, documents)
for result in results:
    print(result)

关于机器学习的内容(自然语言处理NLP、语义分析、向量嵌入数据库、LLM微调等等),我近期会围绕这个主题更新一系列文章,欢迎关注噢,专栏地址人工智能与大模型https://blog.csdn.net/rengj010617/category_12746789.html

五、总结

模糊搜索作为搜索技术的基础部分,凭借其较强的容错性和高效性,广泛应用于各类场景。然而,在需求越来越复杂的今天,模糊搜索的局限性也逐渐显现,尤其在深层语义理解和复杂查询中。因此,模糊搜索在与语义搜索等新型搜索方式结合的过程中展现了更大的潜力。希望本文对你理解模糊搜索的背景、原理及应用有所帮助,助力你在实际项目中灵活运用这一工具。

只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

其他热门文章,请关注:

你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解

通过array.filter()实现数组的数据筛选、数据清洗和链式调用

极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图

el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能

TreeSize:免费的磁盘清理与管理神器,解决C盘爆满的燃眉之急

在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境

Dockerfile全面指南:从基础到进阶,掌握容器化构建的核心工具

MutationObserver详解+案例------深入理解 JavaScript 中的 MutationObserver

JavaScript中闭包详解+举例,闭包的各种实践场景:高级技巧与实用指南

干货含源码!如何用Java后端操作Docker(命令行篇)

Idea启动SpringBoot程序报错:Port 8082 was already in use;端口冲突的原理与解决方案

PDF预览:利用vue3-pdf-app实现前端PDF在线展示

相关推荐
跟德姆(dom)一起学AI20 分钟前
0基础跟德姆(dom)一起学AI 深度学习02-Pytorch基本使用
开发语言·人工智能·pytorch·python·深度学习·机器学习
木向21 分钟前
leetcode86:分隔链表
数据结构·c++·算法·leetcode·链表
有限无限资料库34 分钟前
制造企业数字化中台(技术中台、数据中台、业务中台)建设方案
大数据·人工智能·制造
好看资源平台39 分钟前
Python网络爬虫与数据采集实战——网络协议与HTTP
爬虫·python·网络协议
aqua353574235841 分钟前
第二天python笔记
c语言·开发语言·python·scrapy·算法·蓝桥杯
明朝百晓生1 小时前
无线感知会议系列【14】SignFi: Sign Language Recognition Using WiFi
人工智能
XXXJessie1 小时前
acwing算法基础03-递归,枚举
算法·深度优先·图论
_OLi_1 小时前
力扣 LeetCode 19. 删除链表的倒数第N个结点(Day2:链表)
算法·leetcode·链表
几何DDDMm1 小时前
Python自动化测试---Appium
开发语言·python·appium