我对Python比较陌生,我遇到了以下问题:我试图在两个时间段内集中客户(两个不同的数据集)。 k均值聚类结果存储在pandas数据框中,列有'name','clustering_period_1'和'clustering_period_2'。由于聚类标签在聚类期间没有任何意义,我想在'clustering_period_2'中重新分配标签。
方法:我想弄清楚期间1和期间2的每个聚类输出,组合发生的频率,例如:在第1期中为群集1分配观察的频率,在第2期分配给群集5.我使用pivot_table函数执行此操作:
df.pivot_table(index='cluster', columns='cluster_2', values='name', aggfunc='count')
然后我想在'数据透视表'中找到最大值:
cluster_period_2 0 1 2 3 4 5 6
cluster_period_1
0 51 43 50 49 32 36 33
1 26 28 17 34 25 28 30
2 34 47 35 33 37 36 34
3 7 6 2 5 7 5 6
4 30 19 24 26 20 18 20
5 3 11 5 6 4 6 3
6 4 2 1 13 2 4 3
在此示例中,这将是51,这意味着cluster_0_period_1现在是cluster_0_in_period_2。然后,我想找到不在已使用的列和行中的下一个最大值,即不在第0行或第0列中。这是47,这意味着cluster_2_period_1现在是cluster_1_period_2。我想这样做,直到我得到一个完整的列表,例如(以下示例不基于数据透视表值):
cluster_0_period_1 -> cluster_0_period_2
cluster_1_period_1 -> cluster_4_period_2
...
cluster_6_period_1 -> cluster_5_period_2
我该如何最好地实现这一点?或者如果有一种完全不同的方法更有意义(例如字典或基于列表),请随时提出建议。
提前谢谢了
我们做stack
df1=df.stack().to_frame('val').reset_index()
A=[]
B=[]
for x,y in df1.groupby('cluster_period_1'):
y=y.loc[~y['cluster_period_2'].isin(A),:]
A.append(y['cluster_period_2'].loc[y.val.idxmax()])
B.append(y.val.idxmax())
print(A)
print(y)
然后
df1.loc[B]
Out[472]:
cluster_period_1 cluster_period_2 val
0 0 0 51
10 1 3 34
15 2 1 47
25 3 4 7
30 4 2 24
40 5 5 6
48 6 6 3
这种贪婪的方法可能找不到最好的任务。
相反,使用Hungarian algorithm (Kuhn-Minutes)。
此外,您可以使用上一期间的中心作为起始条件来增加稳定的几率。
在上面的例子中,两个聚类之间的相似性很小,我会拒绝你可以映射/跟踪聚类中心的假设。 k-means不稳定并不罕见,这通常只是暗示它无论如何都不能正常工作。
您可能还希望使用例如ARI和AMI来测量两个群集分配的相似性。如果这些值为低值,则找到1对1映射没有意义。