返回python中具有多个功能的输入查询的最佳匹配
我有以下项目:返回python中具有多个功能的输入查询的最佳匹配,python,matching,fuzzy-search,Python,Matching,Fuzzy Search,我有以下项目: [ { "id":"item1", "age": 1, "color": 'fff', "rate": 3 }, { "id":"item2", "age": 2, "color": '000', "rate": 4 }, { "id":"item3", "age": 3, "color": 'eee', "rate": 5 }, { "id":"item4", "color": 'bbb', "rate": 5 } ] 现在,我希望用户搜索一个
[
{ "id":"item1", "age": 1, "color": 'fff', "rate": 3 },
{ "id":"item2", "age": 2, "color": '000', "rate": 4 },
{ "id":"item3", "age": 3, "color": 'eee', "rate": 5 },
{ "id":"item4", "color": 'bbb', "rate": 5 }
]
现在,我希望用户搜索一个需要的项目:{“年龄”:1,“颜色”:“000”,“比率”:5}
甚至{“年龄”:3,“颜色”:“abc”}
我想找到此查询的最佳匹配项。我该怎么做?
我不是在寻找确切的答案。尽管如此,我还是有兴趣将其作为后端服务实现,所以Python应该可以。我只是不知道如何解决这个问题。是否有某种匹配算法或模糊搜索我需要看看
更新:数据很大(数百万项),每个项有50-100个键,但有些项可能没有全部键。此外,用户查询可能不包含所有键 您的数据集有多大 对于一个小数据集,您可以在O(n*m)时间内完成这项工作(列表中有n个项目,dict中有m个关键点),只需在比较相同关键点的值后获取匹配最多的项目,并跟踪匹配的数量
search_item = {"age": 1, "color": '000', "rate": 5}
mx = -float('inf')
for item in lst:
curr = sum(search_item[k]==item[k] for k in item)
if curr > mx:
match = item
mx = curr
print(match)
搜索条件可能不是简单的键值匹配。你得给它下定义
对于非常大的数据集,您可以从列表中构造一个,并将搜索时间缩短到O(log(n)),以防重用列表/树来搜索多个项目
您应该将十六进制颜色转换为数字类型,这样就可以跨维度使用同质的int类型,并且比较更容易,因为比较int要比模糊字符串匹配简单得多
例如,颜色ffb
比eee
更接近fff
:
>>> int('fff', 16)
4095
>>> int('ffb', 16)
4091
>>> int('eee', 16)
3822
我假设您希望
数据的元素
最匹配,而不是所有dict中每个键的最佳匹配
这可以让你开始:
>>> data = [
... { "id":"item1", "age": 1, "color": 'fff', "rate": 3 },
... { "id":"item2", "age": 2, "color": '000', "rate": 4 },
... { "id":"item3", "age": 3, "color": 'eee', "rate": 5 }
... ]
>>> user_input = {"age": 1, "color": 'fff', "rate":5}
>>>
>>> criterion = lambda d: len(user_input.items() & d.items())
>>> max(data, key=criterion)
{'id': 'item1', 'age': 1, 'color': 'fff', 'rate': 3}
调用max
返回data
的唯一元素,其中有两个匹配项
如果您想要更复杂的模糊匹配而不仅仅是计算直接命中,例如'ffe'
比'abc'
更接近'fff'
,那么您需要
- 为与某些键关联的每种类型的值定义距离度量
- 使用这些度量来实现更复杂的
标准
字符串,考虑数值类型的“和”> ABS(X-Y)。
你的匹配规则是什么?通常,它只是简单地比较搜索到的值和列表中的值。对于年龄和比率,简单的数字比较会很好,对于颜色,您可能需要定制比较或搜索现有的颜色比较算法。一旦你有了距离,你就可以得出一个最终的单值距离,然后选择最接近的一个。谢谢,这很有意义,但是请看一下更新。简单的数字比较是什么意思?它是欧几里得距离,余弦相似性,内积吗?或者你是说别的?这取决于你,在这种情况下,一个简单的欧几里德距离就可以了。谢谢,请查看更新。我应该使用一个简单的abs(x-y)
还是在整个向量上使用欧几里德距离(可能是标准化的)?@towi_并行性,这取决于您。你可以尝试什么可以提供更好的点击率。谢谢,请检查更新。对于大型数据集,您建议这样做吗@托维尤:是的,可以。但是单独使用数字类型会更容易。答案已更新。