从成对列表 python 创建对称矩阵用于聚类 scikit,DBSCAN
create a symmetric matrix from a pairwise list python for clustering scikit, DBSCAN
我的目标是使用来自 scikit 的 DBSCAN 和预先计算的相似性矩阵来执行聚类。
我有一个包含功能的列表。我成对地为列表生成唯一的对,并有一个计算对之间相似性的函数。现在我想将其转换为对称矩阵,可用作聚类算法的输入。
我认为 groupby 可能会有所帮助,但我不确定如何去做。这是一个示例代码,它给出了一个距离为 measure.The 的对列表,原始列表中的 id 字段是唯一的行标识符。
def add_similarity(listdict):
random.seed(10)
newlistdist=[]
for tup_dict in listdict:
newdict={}
tup0=tup_dict[0]
tup1=tup_dict[1]
for key,value in tup0.items():
newdict[key +"_1"]=value
for key,value in tup1.items():
newdict[key+"_2"]=value
newdict["similarity"]=random.random()
newlistdist.append(newdict)
return newlistdist
def generatesymm():
listdict =[{'feature1': 4, 'feature2':2,"id": 100},{'feature1': 3, 'feature2': 2,"id":200},{'feature1': 4, 'feature2':2,"id": 300}]
pairs=list(itertools.combinations(listdict, 2) )
newlistdict=add_similarity(pairs)
如果我 运行 此代码给出
[{'id_2': 200, 'feature1_2': 3, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.571, 'id_1': 100},
{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.42, 'id_1': 100},
{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 3, 'similarity': 0.578, 'id_1': 200}]
我需要的输出
100 200 300
100 1 0.571 0.42
200 0.571 1 0.578
300 0.428 0.578 1
我不清楚 id_3
的来源,但下面是制作数据框的一种方法。诀窍是使用 numpy 索引矩阵的上三角和下三角部分。
In [679]:
import numpy as np
import pandas as pd
similarities = [x["similarity"] for x in newlistdict]
names = ['id_'+str(x) for x in range(1,4)]
n = len(similarities)
iuu = np.mask_indices(3, np.triu, 1)
iul = np.mask_indices(3, np.tril, -1)
mat = np.eye(n)
mat[iuu] = similarities
mat[iul] = similarities
df = pd.DataFrame(mat,columns=names)
df.index = names
df
Out[679]:
id_1 id_2 id_3
id_1 1.000000 0.896082 0.897818
id_2 0.896082 1.000000 0.186298
id_3 0.897818 0.186298 1.000000
(值与您的问题不同,因为我不知道您使用的随机种子。)
我的目标是使用来自 scikit 的 DBSCAN 和预先计算的相似性矩阵来执行聚类。 我有一个包含功能的列表。我成对地为列表生成唯一的对,并有一个计算对之间相似性的函数。现在我想将其转换为对称矩阵,可用作聚类算法的输入。 我认为 groupby 可能会有所帮助,但我不确定如何去做。这是一个示例代码,它给出了一个距离为 measure.The 的对列表,原始列表中的 id 字段是唯一的行标识符。
def add_similarity(listdict):
random.seed(10)
newlistdist=[]
for tup_dict in listdict:
newdict={}
tup0=tup_dict[0]
tup1=tup_dict[1]
for key,value in tup0.items():
newdict[key +"_1"]=value
for key,value in tup1.items():
newdict[key+"_2"]=value
newdict["similarity"]=random.random()
newlistdist.append(newdict)
return newlistdist
def generatesymm():
listdict =[{'feature1': 4, 'feature2':2,"id": 100},{'feature1': 3, 'feature2': 2,"id":200},{'feature1': 4, 'feature2':2,"id": 300}]
pairs=list(itertools.combinations(listdict, 2) )
newlistdict=add_similarity(pairs)
如果我 运行 此代码给出
[{'id_2': 200, 'feature1_2': 3, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.571, 'id_1': 100},
{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.42, 'id_1': 100},
{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 3, 'similarity': 0.578, 'id_1': 200}]
我需要的输出
100 200 300
100 1 0.571 0.42
200 0.571 1 0.578
300 0.428 0.578 1
我不清楚 id_3
的来源,但下面是制作数据框的一种方法。诀窍是使用 numpy 索引矩阵的上三角和下三角部分。
In [679]:
import numpy as np
import pandas as pd
similarities = [x["similarity"] for x in newlistdict]
names = ['id_'+str(x) for x in range(1,4)]
n = len(similarities)
iuu = np.mask_indices(3, np.triu, 1)
iul = np.mask_indices(3, np.tril, -1)
mat = np.eye(n)
mat[iuu] = similarities
mat[iul] = similarities
df = pd.DataFrame(mat,columns=names)
df.index = names
df
Out[679]:
id_1 id_2 id_3
id_1 1.000000 0.896082 0.897818
id_2 0.896082 1.000000 0.186298
id_3 0.897818 0.186298 1.000000
(值与您的问题不同,因为我不知道您使用的随机种子。)