Python根据无法识别搜索词找出可能输入内容模型

下面是一个 Python 示例:根据"无法识别"的搜索词,从已知词库/历史搜索词中找出可能想输入的内容,并记录未知搜索词和候选结果。

```python

import difflib

import json

from collections import Counter, defaultdict

class SearchSuggester:

def init(self, known_words, history_queries=None, min_score=0.3):

已知可识别词库

self.known_words = set(known_words)

历史搜索词,可作为候选池

self.history_queries = list(history_queries or \[\])

self.min_score = min_score

记录无法识别的搜索词出现次数

self.unknown_counter = Counter()

记录每个未知搜索词对应的候选输入

self.candidate_log = defaultdict(list)

def is_recognized(self, query: str) -> bool:

"""判断搜索词是否可识别,这里简单判断是否在已知词库中"""

return query in self.known_words

@staticmethod

def _edit_distance(a: str, b: str) -> int:

"""计算编辑距离,用于衡量字符串相似程度"""

m, n = len(a), len(b)

dp = list(range(n + 1))

for i in range(1, m + 1):

prev = dp0

dp0 = i

for j in range(1, n + 1):

tmp = dpj

if ai - 1 == bj - 1:

dpj = prev

else:

dpj = min(prev, dpj, dpj - 1) + 1

prev = tmp

return dpn

def _score(self, query: str, candidate: str) -> float:

"""综合相似度评分"""

序列相似度

seq_score = difflib.SequenceMatcher(None, query, candidate).ratio()

编辑距离相似度

dist = self._edit_distance(query, candidate)

edit_score = 1 - dist / max(len(query), len(candidate), 1)

前缀、包含关系加分

prefix_bonus = 0.08 if candidate.startswith(query) else 0.0

contains_bonus = 0.04 if query in candidate else 0.0

return 0.55 * seq_score + 0.45 * edit_score + prefix_bonus + contains_bonus

def suggest(self, query: str, top_n: int = 5):

"""为未知搜索词推荐可能输入"""

pool = set(self.history_queries) | self.known_words

scored = \[\]

for word in pool:

if word == query:

continue

score = self._score(query, word)

if score >= self.min_score:

scored.append((word, round(score, 4)))

scored.sort(key=lambda x: x1, reverse=True)

return scored:top_n

def collect(self, query: str, top_n: int = 5):

"""

搜集无法识别的搜索词及其可能输入内容。

如果搜索词可识别,则不记录,直接返回空列表。

"""

if self.is_recognized(query):

return \[\]

self.unknown_counterquery += 1

suggestions = self.suggest(query, top_n=top_n)

self.candidate_logquery = suggestions

return suggestions

def dump(self, path: str):

"""将搜集结果保存到 JSON 文件"""

data = {

"unknown_counter": dict(self.unknown_counter),

"candidate_log": dict(self.candidate_log),

}

with open(path, "w", encoding="utf-8") as f:

json.dump(data, f, ensure_ascii=False, indent=2)

if name == "main":

known_words = {

"苹果手机", "华为手机", "小米手机", "蓝牙耳机", "机械键盘"

}

history_queries = [

"苹果手机", "苹果电脑", "华为手机", "小米手机",

"蓝牙耳机", "机械键盘", "显示器", "笔记本电脑"

]

suggester = SearchSuggester(known_words, history_queries)

test_queries = [

"苹果手几",

"篮牙耳机",

"机械健盘",

"苹果手机", # 可识别,不会被记录

]

for q in test_queries:

result = suggester.collect(q)

print(f"搜索词: {q!r} -> 可能输入: {result}")

print("\n未知词统计:", suggester.unknown_counter)

print("候选记录:", dict(suggester.candidate_log))

保存搜集结果

suggester.dump("unknown_query_candidates.json")

```

输出示例:

```text

搜索词: '苹果手几' -> 可能输入: ('苹果手机', 0.9), ('苹果电脑', 0.5), ...

搜索词: '篮牙耳机' -> 可能输入: ('蓝牙耳机', 0.9), ...

搜索词: '机械健盘' -> 可能输入: ('机械键盘', 0.9), ...

搜索词: '苹果手机' -> 可能输入: \[\]

```

这个实现的核心是:

  1. 判断搜索词是否在已知词库中;

  2. 如果无法识别,就从历史搜索词和已知词库中找相似词;

  3. 使用编辑距离和字符串相似度综合打分;

  4. 记录未知搜索词及其候选内容,方便后续分析或人工审核。

实际生产中可以进一步使用 rapidfuzz、拼音纠错、Elasticsearch Suggest、用户点击日志等提升效果。

文章仅供参考用。

相关推荐
昵称画3 小时前
交接班记录电子化:三班之间的信息不漏
开发语言·数据库·人工智能·低代码·php
“AI国潮设计-小江”3 小时前
【AIGC实战】Python+SDXL批量生成“潮汕英歌舞不倒翁”IP | 角色一致性与多场景融合方案,附完整代码
开发语言·人工智能·python·prompt·aigc
传奇开心果编程3 小时前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言
Linux_cy3 小时前
服务器管理工具哪个好用?我用了七八个
运维·服务器·javascript·python·ssh·面板·gmssh
MoRanzhi12033 小时前
第6篇(下)· 使用 PyQt5 实现 2048 高性能计算版:统一运行控制与跨模式安全交接
python·pyqt·进程管理·状态机·软件架构·并发控制·数据一致性
code tsunami3 小时前
【无标题】
开发语言·python
CodeGL4 小时前
10、Python基础之进程和线程
开发语言·python
TechWayfarer5 小时前
PHP漏洞被利用,怎么揪出攻击IP?
开发语言·python·tcp/ip·网络安全·php
2601_967980116 小时前
Python列表操作方法详解
python·数据类型·修改·列表操作·功能汇总
卡卡~~6 小时前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法