跟踪不同时间段的集群
Tracking clusters across different time periods
我是 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')
然后我想在'pivot table'中找到最大值:
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。我想这样做直到我得到一个完整的列表,例如(下面的示例不基于枢轴 table 值):
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)。
此外,您可以通过使用上一期的中心作为起始条件来增加稳定的机会。
在上面的例子中,两个聚类之间的相似性很小,我会拒绝你可以 map/track 聚类中心的假设。 k-means 不稳定的情况并不少见,这通常只是暗示它无论如何都不能很好地工作。
您可能还想使用例如 ARI 和 AMI 来衡量两个聚类分配的相似性。如果这些给你的价值很低,那么找到一对一的映射就没有意义了。
我是 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')
然后我想在'pivot table'中找到最大值:
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。我想这样做直到我得到一个完整的列表,例如(下面的示例不基于枢轴 table 值):
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)。
此外,您可以通过使用上一期的中心作为起始条件来增加稳定的机会。
在上面的例子中,两个聚类之间的相似性很小,我会拒绝你可以 map/track 聚类中心的假设。 k-means 不稳定的情况并不少见,这通常只是暗示它无论如何都不能很好地工作。
您可能还想使用例如 ARI 和 AMI 来衡量两个聚类分配的相似性。如果这些给你的价值很低,那么找到一对一的映射就没有意义了。