我有一个这种格式的字典
items = {"0":'lorem ipsum', "1":'blah blah', "2":'blah", "3":'lorem',.....}
我们说len(items) = 70
我有一个70x70矩阵,每对字典都有值。例如,matrix[4][20]
表示字典中第4项和第20项之间的值。
我想对字典项进行聚类,并将值大于某个阈值的所有项放在同一组中。我不知道我的方式是否是最佳方式。也许有一个图书馆可以比我的快得多。因为我的矩阵可能是10000x10000。
size = range(0,len(items))
t = 1
mydict = {}
for i in size:
mylist = items[i]
size.remove(i)
for j in size:
if items[j] in lis:
pass
elif matrix[i][j] > 0.50:
mylist.append(items[j])
size.remove(j)
mydict[t] = mylist
t = t + 1
mylist = []
然后我打印超过5个项目的所有组。
for i in mydict:
if len(mydict[i]) > 5:
print mydict[i]
print ""
你看到有什么错误吗?知道任何库或更好的算法吗?
已更新 这是一个更好的例子:
items = {"0": 'item 0', "1":'item 1', "2":'item 2', "3":'item 3', "4":'item 4', "5":'item 5'}
matrix = [[1.0 0.2 0.7 0.8 0.3 0.1],
[0.2 1.0 0.2 0.3 0.6 0.2],
[0.7 0.2 1.0 0.7 0.2 0.3],
[0.8 0.3 0.7 1.0 0.2 0.4],
[0.3 0.6 0.2 0.2 1.0 0.1],
[0.1 0.2 0.3 0.4 0.1 1.0]]
**The results:**
[item 0, item 2, item 3]
[item 1, item 4]
[item 5]
矩阵是三角形,对角线上的所有点都是1.
答案 0 :(得分:2)
这听起来好像是在尝试使用单链接进行层次链接聚类,然后使用给定的阈值进行切割。
这基本上等同于最小生成树(MST)问题,并且速度也尽可能快:O(n^2)
其中n
是项目数。
所以我相信你的算法是合理的。请注意,层次聚类的SciPy实现仅支持Ward链接,而不支持单链接,并且可能具有O(n^3)
复杂度。
如果你想更快地做事,尽量不要首先构建矩阵。但是保留一组集群,并通过一次添加一个元素来适当地连接它们。基本上,对于每个新项目,找到超过阈值的所有项目。然后你可以得到三种情况:1。附近没有其他集群。然后使用当前项启动一个新集群。 2.只有一个集群,将当前项添加到此集群。 3.有多个集群。合并所有这些,然后添加当前项。
class cluster:
def __init__(self, first):
self.members = [first]
mydict = {}
for i in range(0,len(items)):
nearby = set()
for j in range(0, i):
if matrix[i][j] > 0.5: nearby.add(mydict[j])
if len(nearby) == 0:
mydict[i] = cluster(i)
else:
mydict[i] = nearby.pop()
mydict[i].members.append(i)
for other in nearby: # merge other clusters
mydict[i].members.extend(other.members)
for k in other.members: mydict[k] = mydict[i]
请注意,我故意只追踪整数。保存内存是处理大型数据集的关键,而整数只是您拥有的最有效的实体。