使用来自 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')
结果如下:
我有 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')
结果如下: