使用来自 FLD 的最高特征值为 2D 数据投影多个集群

Projecting multiple clusters for 2D data using the heighest eigen values from FLD

我有 4 个大小为 5x5 的矩阵,其中五行 (5xn) 是数据点,列 (nx5) 是特征。如下:

datapoint_1_class_A = np.asarray([(216, 236, 235, 230, 229), (237, 192, 191, 193, 199), (218, 189, 191, 192, 193), (201, 239, 230, 229, 220), (237, 210, 200, 236, 235)])
datapoint_2_class_A = np.asarray([(202, 202, 201, 203, 204), (210, 211, 213, 209, 208), (203, 206, 202, 201, 199), (201, 207, 206, 199, 205), (190, 191, 192, 193, 194)])

datapoint_1_class_B = np.asarray([(236, 237, 238, 239, 240), (215, 216, 217, 218, 219), (201, 202, 203, 209, 210), (240, 241, 243, 244, 245), (220, 221, 222, 231, 242)])
datapoint_2_class_B = np.asarray([(242, 243, 245, 246, 247), (248, 249, 250, 251, 252), (210, 203, 209, 210, 211), (247, 248, 249, 250, 251), (230, 231, 235, 236, 240)])

前两个矩阵属于classA,后两个矩阵属于classB。

我通过计算矩阵 (Sw) 内的散布和矩阵 (Sb) 之间的散布来最大化它们的分离,然后提取特征值和特征向量。

然后,经过计算得到以下特征向量和特征值:

[(6551.009980205623, array([-0.4   ,  0.2531,  0.2835, -0.6809,  0.4816])), 
 (796.0735165617085, array([-0.4166, -0.4205,  0.6121, -0.2403,  0.4661])), 
 (4.423499174324943, array([ 0.1821, -0.1644,  0.7652, -0.2183, -0.5538])), 
 (1.4238024863819319, array([ 0.0702, -0.5216,  0.3792,  0.5736, -0.5002])), 
 (0.07624674030991384, array([ 0.2903, -0.2902,  0.2339, -0.73  ,  0.4938]))]

之后我将 W 矩阵乘以初始 20x5 矩阵:

我的 W 矩阵给出了以下矩阵:

矩阵W:

 [[-0.4,   -0.4166]
 [ 0.2531, -0.4205]
 [ 0.2835,  0.6121]
 [-0.6809, -0.2403]
 [ 0.4816,  0.4661]]

X_lda = X.dot(W)

并绘制我的数据

from matplotlib.pyplot import figure
plt.xlabel('LD1')
plt.ylabel('LD2')
plt.scatter(
    X_lda.iloc[:,0],
    X_lda.iloc[:,1],
    c=['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'red'],
    cmap='rainbow',
    alpha=1,
    edgecolors='w'
)

这个图的问题是数据没有很好地聚类和分离,我期望数据点为每个矩阵聚类,这就是我从上面的代码中得到的:

根据绘图轴,这些数据看起来没有很好地聚类,其中它们的 X 轴和 y 轴分别为 5 和 -5。我的目标是使用两个最高的特征值:6551.009980205623, 796.0735165617085 将我的数据绘制在特征 space(图)中,该特征恰好是簇大小 (5x5),因此轴为 5、X 中的 5和 y,其中簇内的每个点彼此非常相邻并且它们的距离非常大。

对我来说,这看起来类似于奇异值分解,它试图通过保留最能捕捉数据传播的特征向量,将高维 space 压缩成较小的维 space。

这一段时间以来一直是一种流行的策略,但是,它有其局限性:仅考虑将高维 space 投影到较低维度,您必然无法考虑微妙的存在于高维表示中的空间关系。

一种流行的替代方法是 t-sne,它使用损失函数迭代优化以保持低维表示的高维数据中的“接近度”。 this is a great video explaining t-sne and it's benefits.

最终,虽然在使用任何聚类算法时,您只会得到数据中实际存在的分离,而不是您想要的分离。完全有可能,无论您的表示如何,您最终都会得到您不满意的分组,这仅仅是因为这些组不存在于您的高维表示中。

首先,你的矩阵计算有误。您有 4 个 类(datapoint_1_class_A、datapoint_2_class_A、datapoint_1_class_B、datapoint_2_class_B),因此 W 的排名可能最多为 3。您已经满级了,这是不可能的。最后两个特征值应该在 1e-15 左右。

接下来,您可能混合了特征和点维度。请确保 X 的每一行对应 。 运行 一个简单的检查:为每个集群找到它的平均值(每个 column/feature)。将此点添加到群集中。这将使您的矩阵成为 6 个点乘以 5 个特征。现在,再次找到平均值。你应该得到完全相同的结果。

见以下代码:

import numpy as np
from matplotlib import pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
a1 = np.asarray([(216, 236, 235, 230, 229), (237, 192, 191, 193, 199), (218, 189, 191, 192, 193), (201, 239, 230, 229, 220), (237, 210, 200, 236, 235)])
a2 = np.asarray([(202, 202, 201, 203, 204), (210, 211, 213, 209, 208), (203, 206, 202, 201, 199), (201, 207, 206, 199, 205), (190, 191, 192, 193, 194)])

b1 = np.asarray([(236, 237, 238, 239, 240), (215, 216, 217, 218, 219), (201, 202, 203, 209, 210), (240, 241, 243, 244, 245), (220, 221, 222, 231, 242)])
b2 = np.asarray([(242, 243, 245, 246, 247), (248, 249, 250, 251, 252), (210, 203, 209, 210, 211), (247, 248, 249, 250, 251), (230, 231, 235, 236, 240)])

X = np.vstack([a1.T, a2.T, b1.T, b2.T])
y = [1]*5 + [2]*5 + [3]*5 + [4]*5
clf = LinearDiscriminantAnalysis(n_components=2)
clf.fit(X, y)

Xem = clf.transform(X)
plt.scatter(Xem[0:5,0], Xem[0:5,1], c='b', marker='o')
plt.scatter(Xem[5:10,0], Xem[5:10,1], c='b', marker='s')
plt.scatter(Xem[10:15,0], Xem[10:15,1], c='r', marker='o')
plt.scatter(Xem[15:20,0], Xem[15:20,1], c='r', marker='s')

结果如下: