我有4个5×5的矩阵,其中五行(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)])
前两个矩阵属于类别A,后两个矩阵属于类别B。
我通过计算类内散布矩阵(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矩阵乘以初始的20×5矩阵:
我的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 figureplt.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
,在特征空间(图表)内绘制我的数据,使其正好是一个聚类的大小(5×5),因此X和Y轴分别为5和5,其中每个聚类内的点彼此非常接近,而它们的距离非常大。
回答:
首先,你的矩阵计算中有一些错误。你有4个类别(datapoint_1_class_A, datapoint_2_class_A, datapoint_1_class_B, datapoint_2_class_B),所以W
的秩最大为3。你得到了满秩,这是不可能的。最后两个特征值应该在1e-15左右。
其次,你可能混淆了特征和点的维度。请确保X
的每一行对应一个点。进行一个简单的检查:对于每个聚类,按每一列/特征找到其均值。将这个点添加到聚类中。这将使你的矩阵变为6个点乘以5个特征。现在,再次找到均值。你应该得到完全相同的结果。
请看以下代码:
import numpy as npfrom matplotlib import pyplot as pltfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysisa1 = 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]*5clf = 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')