我有一个文件,我正在从中读取数据。 我需要有关如何设计数据结构的建议,该结构执行以下操作: 所以,数据的形式是
id_1::id_2::similiarity_score
现在,虽然数据采用这种形式,但也意味着
id_2::id_1::same_similiarity_Score
所以,我想要的是一个数据结构,当我在程序中使用时。 所以我想说我想使用这些数据来找到哪两个相似的项目
object.maxSimiliarity(object_id_1)
returns object_id_2 # has max score
但是这个object_id_1也可以在数据库的product_id_2列中...
所以在数据库中可以是以下形式之一:
object_id_1:: object_id_2::score
or object_id2::object_id_1::score
所以我想要以
的方式设计这个数据结构k_1, k_2:: value <--> k_2,k_1::value
答案 0 :(得分:3)
这类事情的一般技巧是找到规范化 - 一种将特定类的所有成员映射到同一对象的函数。在这种情况下,您可以通过对前两个组件进行排序来实现它,这两个组件将B :: A :: Score转换为A :: B :: Score,同时保持A :: B :: Score不变。
答案 1 :(得分:2)
在我看来,你可以使用这些分数来建立最佳或最差匹配的列表:
d = {
'id1': [id_best_match_to_id1, id_next_best_match_to_id1, ..., id_worst_match_to_id1],
'id2': [id_best_match_to_id2, id_next_best_match_to_id2, ..., id_worst_match_to_id2],
...
}
如果需要保留相似性分数,请使用(id_best_match_to_id1, similarity_score_to_id1)
形式的元组列表。
我没有看到利用这种相似性的方法是sim(x,y)==sim(y,x)
的对称关系。
答案 2 :(得分:0)
数据看起来非常像加权图的节点和边。如果a
与b
类似,得分为5.0
,类似于c
且得分为1.0
,那么您可能会将其显示为:
a
/ \
/ \
5.0 1.0
/ \
b c
Networkx是一个python库,提供现成的图形对象和算法。将数据加载到加权多图中(即,它支持节点A--B
和B--A
之间的多个连接是微不足道的。之后,在给定对象id的情况下获取最相似的对象是查找节点,找到它的最大加权边缘并在其末尾返回节点。
import networkx as nx
## Test data
data = """\
a::b::2
b::a::3
a::c::5
b::e::1
"""
rows = (row.split('::') for row in data.split())
class Similarity(object):
def __init__(self, data):
self.g = nx.MultiGraph()
self.load(data)
def load(self, data):
## Turn the row into data suitable for networkx graph
rows = ((row[0], row[1], float(row[2])) for row in data)
self.g.add_weighted_edges_from(rows)
def most_similar(self, obj_id):
## Get edges from obj_id node
edges = self.g.edges_iter(obj_id, data=True)
## Sort by weight, get first, get joined node
return sorted([(i[0], i[1], i[2].get('weight', 0)) for i in edges])[-1][1]
sc = Similarity(rows)
sc.most_similar('a') ## 'c'
## Add some more data linking a --> f with a high score
sc.load([('a', 'f', 10)])
sc.most_similar('a') ## 'f'