Python 我怎样才能找到什么数据是K形聚类?

Python 我怎样才能找到什么数据是K形聚类?,python,matplotlib,Python,Matplotlib,我写代码 import numpy import matplotlib.pyplot as plt from tslearn.clustering import KShape from tslearn.datasets import CachedDatasets from tslearn.preprocessing import TimeSeriesScalerMeanVariance ks = KShape(n_clusters=3, n_init=10, verbose=True, r

我写代码

import numpy
import matplotlib.pyplot as plt

from tslearn.clustering import KShape
from tslearn.datasets import CachedDatasets
from tslearn.preprocessing import TimeSeriesScalerMeanVariance


ks = KShape(n_clusters=3, n_init=10, verbose=True, random_state=seed)
y_pred = ks.fit_predict(data)

plt.figure(figsize=(16,9))
for yi in range(3):
    plt.subplot(3, 1, 1 + yi)
    for xx in stack_data[y_pred == yi]:
        plt.plot(xx.ravel(), "k-", alpha=.2)
    plt.title("Cluster %d" % (yi + 1))

plt.tight_layout()
plt.show()
我想通过使用KShape的聚类来划分
数据
。现在显示了图,但我无法找到每3个聚类中的数据

数据是A、B、C、D的顺序。所以我想显示要绘图的标签或聚类结果。我搜索了KShape的文档(),但找不到实现我理想的信息。我应该如何做呢?

为什么没有完美的解决方案 K-Shape是随机工作的,如果不为每次迭代设置种子,您可能会得到不同的簇和质心。如果给定的类完全由给定的质心描述,则没有确定的方法可以先验地知道,但您可以通过检查给定类主要分类到哪个质心,以模糊的方式以脱机方式继续

另外,任何给定的类,
A
,例如,都可能包含作为您正在考虑的特征空间中两个簇的一部分的元素

假设您有3个类,但您的数据集最好由4个簇来描述(例如,通过最大平均密度):您肯定至少有一个类的一些点位于第4个簇中

或者,假设您的类没有与您正在考虑的距离度量生成的质心重叠:考虑一个明显的例子:您有3个类,数字从0到100,从100到1000,从1000到1100,但是您的数据集包含从0到150以及从950到1100的数字:聚类算法将在两个聚类中找到其最佳值,并将a类的点放在两个聚类中的任意一个

例如,一旦您确定类
A
主要进入集群
1
,类
B
进入集群
2
等。。。您可以继续将该集群分配给给定的类

一种可能的模糊方法 我们将通过将最佳拟合类分配给包含其大部分点的簇来确定簇类:

简单示例:实际适合集群的类 在本例中,我们使用其中一个。此代码部分取自

我们设定种子,用于代码再现性:

seed = 0
np.random.seed(seed)
首先,我们准备数据集,选择第一个
类\u number=3
类:

classes_number = 3
X_train, y_train, X_test, y_test = CachedDatasets().load_dataset("Trace")
mask = y_train <= classes_number
X_train, y_train = X_train[mask], y_train[mask]  # Keep first 3 classes
X_train = TimeSeriesScalerMeanVariance().fit_transform(X_train)  # Keep only 50 time series
sz = X_train.shape[1]
现在,我们继续计算分配给每个集群的每个类的元素,并在没有将给定类的元素分配给给定集群的情况下添加0填充(当然会有一种更具python风格的方法,但我还没有找到):

添加填充:

padded_data = np.array([[
    data[j][1][data[j][0] == i][0] if np.any(data[j][0] == i) else 0
    for i in range(clusters_number)
] for j in range(classes_number)])

>>> array([[ 0,  0, 26],
           [21,  0,  0],
           [ 0, 22,  0]])
将获得的矩阵归一化:

normalized_data = padded_data / np.sum(padded_data, axis=-1)[:, np.newaxis]

>>> array([[0., 0., 1.],
          [1., 0., 0.],
          [0., 1., 0.]])
我们可以使用以下方法可视化获得的矩阵:

获得:

在这种最佳情况下,每个集群仅包含一个类,因此我们以绝对精度获得:

classes_clusters = np.argmax(normalized_data, axis=1)

>>> array([2, 0, 1])
第二个示例:不与集群重叠的类 为了简单起见,为了模拟不与集群完全重叠的类,我将洗牌一部分标签,但有大量的例子:大多数集群问题最终都是与集群不完全重合的类

tmp = y_train[:20]
np.random.shuffle(tmp)
y_train[:20] = tmp
现在,当我们再次执行脚本时,会得到一个完全不同的矩阵:

但我们仍然能够确定类别群集:

classes_clusters = np.argmax(normalized_data, axis=1)

>>> array([2, 0, 1])
第三个示例:数据集中不存在的类 假设我们被引导相信数据集中存在4个类:在使用不同的
k
值运行后,我们会发现当前数据集中的最佳集群数量是
k=3
:我们将如何继续将类分配给集群?哪门课可以扔掉

我们通过任意为标签指定第四类来模拟这种情况:

y_train[:20] = 4
再次运行我们的脚本,我们将获得:

很明显,第四节课得走了。我们可以对均值-方差进行阈值化:

threshold = np.mean(np.var(normalized_data, axis=1))

result = np.argmax(normalized_data[np.var(normalized_data, axis=1)>threshold], axis=1)
我们再次获得:

array([2, 0, 1])

我希望这个解释消除了你的大部分疑虑

谢谢你的回答。我无法从“一个给定的类a也可以包含~~~”中理解你的句子的意思。你能给我看看示例代码吗?谢谢你的写作。读完你的文章后,我有点困惑。在显示了绘图之后,显示了一个时间序列的图形。图形的线条与a、B、C、D的类相连,不是吗?当然,但在给定的情况下,生成的类适合集群。只需将集群的数量(在给定的示例中,您知道)设置为另一个,我描述的现象就会很清楚。不管怎样,代码正在进行中。更新了答案!我能很好地理解它!!非常感谢你!!
classes_clusters = np.argmax(normalized_data, axis=1)

>>> array([2, 0, 1])
y_train[:20] = 4
threshold = np.mean(np.var(normalized_data, axis=1))

result = np.argmax(normalized_data[np.var(normalized_data, axis=1)>threshold], axis=1)
array([2, 0, 1])