2015-04-15 30 views
2

我正在尝试通过Accord框架实现PCA,以实现降维(即功能减少)。基本上,我有一个包含超过23000个功能的大矩阵。这些都是从一组文档中提取的所有功能。一个非常简单的是矩阵的概述如下所示:如何使用主成分分析来应用特征缩减? (C#,Accord)

 dog cat fish 
doc1 0,024 0,011 0,008 
doc2 0,011 0,014 0,007 
doc3 0,005 0,024 0,003 
doc4 0,008 0,028 0,008 
doc5 0,002 0,03 0,006 

在矩阵中的数字对应的词频 - 我们已经把我们的计划之内计算出逆文档频率。基本上这表明我们在某个文档中出现了多少次该术语。这对我们来说是非常有用的信息,因为我们需要它来确定我们矩阵中的哪一项可以用作稍后分类的功能。因为我们有大约23000个可能的特征(并且#只会在未来增加),所以我们需要减少这个数目,比如+ - 20个特征(以后需要进行分类)。为了让我们认识到这一点,我们需要使用减少特征/维度数量的东西。所以我们做了一些搜索,并且遇到了协议框架,内核PCA,ALGLIB等等。他们对我们都非常含糊,因为我们没有PCA背景,而且我们也远离数学家。

所以我们选择,因为它看起来很容易实现,通过使用用于测试目的下面的代码使用协议框架:

double[,] sourceMatrix = 
     { 
      { 2.5, 2.4 }, 
      { 0.5, 0.7 }, 
      { 2.2, 2.9 }, 
      { 1.9, 2.2 }, 
      { 3.1, 3.0 }, 
      { 2.3, 2.7 }, 
      { 2.0, 1.6 }, 
      { 1.0, 1.1 }, 
      { 1.5, 1.6 }, 
      { 1.1, 0.9 } 
     }; 

     // Creates the Principal Component Analysis of the given source 
     var pca = new PrincipalComponentAnalysis(sourceMatrix, AnalysisMethod.Center); 

     // Compute the Principal Component Analysis 
     pca.Compute(); 

     // Creates a projection 
     double[,] components = pca.Transform(sourceMatrix); 

     for (int i = 0; i < components.GetLength(0); i++) 
     { 
      for (int j = 0; j < components.GetLength(1); j++) 
      { 
       Console.WriteLine(components[i, j]); 
      } 
     } 

     Console.ReadLine(); 

此代码将打印起因于变换方法在控制台矩阵。由于我们并不真正了解所有数字的含义以及它们如何帮助减少这些特征,因此我们决定在datagridview中查看组件矩阵,通过在与前面的代码示例完全相同的矩阵上使用此代码:

// Creates the Principal Component Analysis of the given source 
    var pca = new PrincipalComponentAnalysis(sourceMatrix, AnalysisMethod.Center); 

    // Compute the Principal Component Analysis 
    pca.Compute(); 

    // Display 
    dgvPCA.DataSource = pca.Components; 
    dgvPCA.Columns["Analysis"].Visible = false; 

这将返回比例,扩展比例,奇异值和特征值。再一次,没有线索。

那么我们如何应用这个原理来将我们的+ - 23000的矩阵减少到+ - 20?

+0

如果您需要从23000到20功能减少数据进一步说明,经过20作为pca.Transform的第二个参数,即:var features = pca.Transform(sourceMatrix,20); – Cesar

+0

有一个非常简单的PCA PCA介绍,名为“主要组件分析教程”,Lindsay Smith,可在此处获得:http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_components.pdf 我还创建了一个配套材料,解释如何在Accord.NET中关注Lindsay的教程:http://arxiv.org/abs/1210.7463 – Cesar

+0

感谢您的分享,我在研究过程中已经遇到了您的一些工作,证明有帮助。 – Redesign1991

回答

1

免责声明:我将冒昧给出一个答案,将不会解决您的问题中的所有问题。 TL; DR:沿着劝在底部

主成分(PC)是一个简单的许多功能,其中一个功能是值(通常观察或测量)的向量的投影(线性组合)一些维度。

对于您的问题,功能似乎是术语“术语频率 - 反向文档频率”,每个文档都带有“测量”。所有文档的所有特征形成一个矩阵。

什么主成分分析(PCA)所做的是通过寻找这些主成分变换(或拉开)这个矩阵(你可以查看作为抽象的功能,它们有时也被称为“隐藏功能”) 。如所提到它们仅仅是原始术语矢量的线性组合,如:

PC1 = 0.1 * Cat + 0.001 * Dog - 0.8 * Fish ... ` 
PC2 = 0.0001 * Cat - 0.102 * Dog + 0.1 * Fish ...` 
... 
PCN = 0.00000001 * Cat - 0.0000000001 * Dog + 0.00000000000001 * Fish .... 

Ñ是一样的原来数目的特征,并且这些值(0.1,0.001,-0.8,.. 。)代表在给定PC上的每个特征的加载,表示原始术语如何与PC相关。高正值或负值表示该术语与PC高度正相关或负相关。

找到的主要组件的一个重要特性是它们是orthogonal,即不相关,这很好地在视觉上图示here

您可能试图通过想象您正在用一组数据点(x和y的单独观察值)来查看2D xy散点图(x和y是两个特征),并尝试旋转和平移轴,而数据点保持静止。

x-y plot

首先尝试旋转x轴得到它的相交点云的中心,作为一个线性回归会排队。接下来,您将Y轴移动(平移)到点云的中心。 X和Y轴的旋转和平移位置是您的主要组件。

rotated axes

正如你可能已经注意到,主成分的编号,由他们排名。如果排名最低的组件解释了原始数据集中最大的差异。对于上面的示例图像,您可以清楚地看到“PCA轴1”比“PCA轴2”解释了更多的方差。

一般来说,PC的数量可以共同解释您所有方差的大部分数据集将比输入特征小得多。通过选择解释足够变化量的第一台电脑,可以减少功能部件的数量。

你可以做的另一件事是看PC上所谓的得分。这将在PC上查看每个文档的得分,即它对给定PC有多大贡献。

可以找到更彻底的介绍性文本here以及这些概念中的一些的示例herehere

再回到你的问题,我建议你:

主成分分析的一个复杂问题的应用程序,如从术语缩减的一组分类文件是远离琐碎,需要一个彻底的了解PCA和您尝试解决的分类问题。

我会建议您尝试找到/雇用这方面的专家,他们可以为您提供指导,并通过询问重要问题来帮助您沿着正确的道路前进。

明智地做一些更多的研究,以获得更好的感觉特征减少和分类方法,正在其他地方用于解决类似的问题,你正在处理。

此外,建议使用专门针对此类数据分析(例如SAS,Matlab,R等)开发和验证您的特征选择和分类方法的工具。一旦这些方法得到验证,如果您需要在一个c#软件中实施它们,请查找最适合的工具(可能是Accord)。

+0

谢谢你的阐述。我肯定需要对这个概念做更多的研究,并且考虑到这个概念的深度,也许会和我的上司讨论一下。 – Redesign1991

+0

我一直在寻找更多的PCA,我现在对它的理解更好。我想我只需要找到一种方法来检索哪些变量是由某个(或多个)组件反映的,是正确的? – Redesign1991

0

我之前有一个非常类似的问题,这就是我发现的。 使用PCA(基于协议实现)的问题是获取原始数据中最重要的功能。如Alex所解释的,PCA结果是基于旧部件的总和乘以其权重的新部件。

这里的问题是获得权重可能有点棘手,因此您可能会发现尝试用svm解决您的问题更简单,更高效。

协议还提供了一个非常有用的实现,下面是一个示例代码:

double[][] inputs = new double[DataFiles.Count][]; 
int[] outputs = new int[DataFiles.Count]; 
//fill the inputs and outputs with your data 
double c = SequentialMinimalOptimization.EstimateComplexity(inputs); 


// Creates the SVM for input variables 
SupportVectorMachine svm = new SupportVectorMachine(inputs:Count); 

// Creates a new instance of the sparse logistic learning algorithm 
var smo = new ProbabilisticDualCoordinateDescent(svm, inputs, outputs) 
{ 
// Set learning parameters 
Complexity = c, 
Tolerance = 1e-5, 
}; 
try 
{ 
double error = smo.Run(); 
} 
catch (ConvergenceException) 
{ 
} 
// Show feature weight importance 
double[] weights = svm.Weights; 

,并请找到 https://github.com/accord-net/framework/wiki/Linear-Support-Vector-Machines

+0

缩进是一件好事。 –