我正在做一个聚类算法,其中我有一个包含(m)行和(n)特征的数据集。我为数据集创建了一个Jaccard相似度矩阵,将我的数据集转换为(m * m)相似度矩阵。
在创建相似度矩阵后,我在矩阵上运行某个逻辑以找到几个坐标。
我写的逻辑实际上遍历了矩阵中的一半元素,但需要花费大量时间。因为我是python的新手,我的代码不是太优化而是直接的。
请在下面找到我的代码:
similarity_dict={}
for (i,j), value in np.ndenumerate(matrix_for_cluster):
if value>threshold and j>=i:
if i in similarity_dict:
similarity_dict[i].append(j)
if i<>j:
if j in similarity_dict:
similarity_dict[j].append(i)
else:
similarity_dict[j]=[i]
else:
similarity_dict[i]=[j]
Matrix for cluster is the similarity matrix, If any of the element's value is greater than the threshold value then the element index is stored in a dictionary.
我非常感谢有关优化代码的任何帮助
答案 0 :(得分:3)
在我看来,您想要或正在尝试构建的内容看起来像一个图形。在这种情况下,您可以使用networkx
包:
>>> sim_matrix
array([[0, 1, 0, 2, 2],
[1, 0, 2, 0, 1],
[0, 2, 0, 1, 2],
[2, 0, 1, 0, 0],
[2, 1, 2, 0, 0]])
>>> sim_matrix[sim_matrix < 2] = 0 # apply your threshold
>>> sim_matrix
array([[0, 0, 0, 2, 2],
[0, 0, 2, 0, 0],
[0, 2, 0, 0, 2],
[2, 0, 0, 0, 0],
[2, 0, 2, 0, 0]])
sim_matrix
numpy数组:
>>> import networkx as nx
>>> graph = nx.Graph(sim_matrix)
>>> graph.nodes()
[0, 1, 2, 3, 4]
>>> graph.edges(2)
[(2, 1), (2, 4)]
>>> graph.edges(4)
[(4, 0), (4, 2)]
内部networkx
与python词典一起使用,所以它几乎就是你想要构建的,但已经为你构建了。
注意:这会创建一个不定向的图形。如果您希望它定向,请将nx.Graph
更改为nx.DiGraph
行。
编辑:更新了示例,使sim_matrix实际上成为对称矩阵(非定向图)。
查找有关networkx和numpy here的更多信息。
希望它有所帮助!
答案 1 :(得分:0)
这应该做同样的事情,但可能产生更少的VM操作:
for (i,j), value in np.ndenumerate(matrix_for_cluster):
if value>threshold and j>=i:
similarity_dict.setdefault(i,[]).append(j)
if i != j:
similarity_dict.setdefault(j,[]).append(i)
但总的来说,scipy和numpy(你已经使用过我已经看过)有更多优化的矩阵和类似东西的相似性,如果你可以把所有的工作保存在num / scipy的本地东西,你会获得更好的表现。