使用Python进行Fisher线性判别分析

我需要使用Fisher线性判别分析将高维矩阵的示例A和B降维到二维,这与LDA非常相似。每个示例都有A和B类别,因此如果我有第三个示例,它们也有A和B类别,第四个、第五个和第n个示例也总是有A和B类别。因此,我想通过简单地使用Fisher线性判别分析来分离它们。我对机器学习还比较新手,所以不知道如何分离我的类别,我一直在根据公式直观地进行编程。在我读到的内容中,我需要对我的数据应用线性变换,以便找到一个好的阈值,但首先我需要找到最大化函数。为此任务,我设法找到了Sw和Sb,但不知道接下来该怎么做…

enter image description here

我还需要找到最大化函数。

enter image description here

该最大化函数为我提供了一个特征值解:

enter image description here

每个类别我有的都是2个示例的5×2矩阵。例如:

示例1 Class_A = [201, 103,40, 43,23, 50,12, 123,99, 78]Class_B = [   201, 129,   114, 195,   180, 90,   69, 62,   76, 90]示例2   Class_A = [68, 98,201, 203,78, 212,49, 5,204, 78]   Class_B = [   52, 19,   220, 219,   159, 195,   99, 23,   46, 50]

我尝试像这样找到上面的示例的Sw:

Example_1_Class_A = np.dot(Example_1_Class_A,  np.transpose(Example_1_Class_A))Example_1_Class_B = np.dot(Example_1_Class_B,  np.transpose(Example_1_Class_B))Example_2_Class_A = np.dot(Example_2_Class_A,  np.transpose(Example_2_Class_A))Example_2_Class_B = np.dot(Example_2_Class_B,  np.transpose(Example_2_Class_B))Sw = sum([Example_1_Class_A, Example_1_Class_B, Example_2_Class_A, Example_2_Class_B], axis=0)

至于Sb,我尝试像这样:

Example_1_Class_A_mean = Example_1_Class_A.mean(axis=0)Example_1_Class_B_mean = Example_1_Class_B.mean(axis=0)         Example_2_Class_A_mean = Example_2_Class_A.mean(axis=0)Example_2_Class_B_mean = Example_2_Class_B.mean(axis=0)         Example_1_Class_A_Sb = np.dot(Example_1_Class_A_mean, np.transpose(Example_1_Class_A_mean))Example_1_Class_B_Sb = np.dot(Example_1_Class_B_mean, np.transpose(Example_1_Class_B_mean))         Example_2_Class_A_Sb = np.dot(Example_2_Class_A_mean, np.transpose(Example_2_Class_A_mean))Example_2_Class_B_Sb = np.dot(Example_2_Class_B_mean, np.transpose(Example_2_Class_B_mean))Sb = sum([Example_1_Class_A_Sb, Example_1_Class_B_Sb, Example_2_Class_A_Sb, Example_2_Class_B_Sb], axis=0) 

问题是,我不知道如何处理我的Sw和Sb,我完全迷失了。基本上,我需要从这里做到这个:

enter image description here

对于给定的示例A和示例B,如何仅为类别A和仅为类别B分离一个聚类?


回答:

在回答你的问题之前,我先简单介绍一下PCA和(F)LDA的基本区别。在PCA中,你对底层类别一无所知,但你假设类别可分性信息存在于数据的方差中。因此,你旋转原始轴(有时称为将所有数据投影到新的轴上),使你的第一个新轴指向最大方差方向,第二个轴与第一个轴垂直并指向最大残差方差方向,依此类推。这样,PCA变换的结果是一个与原始数据维度相同的(子)空间。然后你可以只取前两个维度,拒绝其余的,从而实现从k维到仅2维的降维。

LDA的工作方式略有不同。在这种情况下,你提前知道数据中有多少个类别,并且你可以找到它们的均值和协方差矩阵。Fisher判据所做的是找到一个方向,使类别之间的均值最大化,同时同时总体变异性最小化(总体变异性是类内协方差矩阵的均值)。对于每个两个类别,只有一条这样的线。这就是为什么当你的数据有C个类别时,LDA最多可以为你提供C-1维,无论原始数据维度如何。在你的情况下,这意味着由于你只有A和B两个类别,你将得到一个一维投影,即一条线。这正是你图片中所展示的:原始的二维数据被投影到一条线上。线的方向是特征问题解的解。让我们生成类似于你图片的数据:

a = np.random.multivariate_normal((1.5, 3), [[0.5, 0], [0, .05]], 30)b = np.random.multivariate_normal((4, 1.5), [[0.5, 0], [0, .05]], 30)plt.plot(a[:,0], a[:,1], 'b.', b[:,0], b[:,1], 'r.')mu_a, mu_b = a.mean(axis=0).reshape(-1,1), b.mean(axis=0).reshape(-1,1)Sw = np.cov(a.T) + np.cov(b.T)inv_S = np.linalg.inv(Sw)res = inv_S.dot(mu_a-mu_b)  # the trick##### more general solution## Sb = (mu_a-mu_b)*((mu_a-mu_b).T)# eig_vals, eig_vecs = np.linalg.eig(inv_S.dot(Sb))# res = sorted(zip(eig_vals, eig_vecs), reverse=True)[0][1] # take only eigenvec corresponding to largest (and the only one) eigenvalue# res = res / np.linalg.norm(res)plt.plot([-res[0], res[0]], [-res[1], res[1]]) # this is the solutionplt.plot(mu_a[0], mu_a[1], 'cx')plt.plot(mu_b[0], mu_b[1], 'yx')plt.gca().axis('square')# let's project data point on itr = res.reshape(2,)n2 = np.linalg.norm(r)**2for pt in a:    prj = r * r.dot(pt) / n2    plt.plot([prj[0], pt[0]], [prj[1], pt[1]], 'b.:', alpha=0.2)for pt in b:    prj = r * r.dot(pt) / n2    plt.plot([prj[0], pt[0]], [prj[1], pt[1]], 'r.:', alpha=0.2)

生成的投影是使用一个巧妙的技巧计算的,适用于两个类别的问题。你可以在这里的第1.6节阅读更多细节。

enter image description here

关于你在问题中提到的“示例”。我认为你需要为每个示例重复这个过程,因为这是一组不同的数据点,可能具有不同的分布。还要注意,估计的均值(mu_a, mu_b)和类协方差矩阵与生成数据时使用的可能略有不同,特别是在样本量较小的情况下。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注