Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用主成分分析应用特征约简?(C#,协议)_C#_Matrix_Pca_Accord.net - Fatal编程技术网

如何使用主成分分析应用特征约简?(C#,协议)

如何使用主成分分析应用特征约简?(C#,协议),c#,matrix,pca,accord.net,C#,Matrix,Pca,Accord.net,我试图通过Accord框架实现PCA,以实现降维,即特征降维。基本上,我有一个包含23000多个特性的大矩阵。这些都是从一组文档中提取的特征。该矩阵的简单概述如下所示: 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 矩阵中的数字对应于

我试图通过Accord框架实现PCA,以实现降维,即特征降维。基本上,我有一个包含23000多个特性的大矩阵。这些都是从一组文档中提取的特征。该矩阵的简单概述如下所示:

      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个特性(稍后需要进行分类)。为了实现这一点,我们需要使用一些减少特征/维度数量的东西。所以我们做了一些搜索,发现了accord框架、内核PCA、ALGLIB等等。它们对我们来说都很模糊,因为我们没有PCA方面的任何背景,我们离数学家很远

因此,我们选择使用Accord框架,因为它看起来很容易实现,使用以下代码进行测试:

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();
这将返回比例、累计比例、奇异值和特征值。同样,没有线索

那么,我们如何应用这一原则,将+-23000项的矩阵减少到+-20项呢

免责声明:我将冒昧地给出一个答案,它不会解决您问题中的所有问题。TL;医生:在底部建议

主成分(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 ....
式中,N与特征的原始数量相同,这些值(0.1,0.001,-0.8,…)表示给定PC上每个特征的加载,表示原始项与PC的相关性。高正值或负值表示该项与PC的高正相关性或负相关性

发现的主成分的一个重要特性是它们是不相关的,这是很好的直观说明

您可以尝试自己将其可视化,方法是想象您正在查看2D x-y散点图(x和y是两个特征),其中包含大量数据点(x和y的单独观测值),并尝试旋转和平移轴,同时数据点保持静止

首先,尝试旋转x轴,使其与点云的中心相交,就像线性回归线一样。接下来,将Y轴移动(平移)到点云的中心。X轴和Y轴的旋转和平移位置是主要组件

正如您可能已经注意到的,主成分按其等级进行编号。其中,排名最低的成分解释了原始数据集中最大的方差。对于上面的示例图像,您可以清楚地看到,“PCA轴1”比“PCA轴2”解释的差异要大得多

一般来说,PC的数量,加在一起解释了数据集中的大部分差异,将远远小于N个输入特征。这就是允许您通过选择第一个
X
PC来减少特征尺寸数量的原因,这些PC可以解释足够多的差异

您可以做的另一件事是查看PC上所谓的分数。这会查看PC上每个文档的分数,即它对给定PC的贡献程度

可以找到更全面的介绍性文本,以及其中一些概念和概念的示例

回到你的问题,我给你的建议是:

将主成分分析应用于复杂问题(如从一组简化的术语对文档进行分类)绝非易事,需要对主成分分析和您试图解决的分类问题有透彻的了解

我建议你试着寻找/雇佣一位该领域的专家,他可以为你提供指导,并通过向你提出重要的问题来帮助你走上正确的道路

做更多的研究以更好地了解其他地方用于解决与您正在处理的问题类似的问题的特征约简和分类方法也是明智的


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

我之前遇到过一个非常类似的问题,这就是我发现的。 使用PCA(基于accord实现)的问题是获取原始数据中最重要的特征。PCA结果是基于旧组件的总和乘以其权重的新组件,如Alex所述

这里的问题是获取权重可能有点棘手,因此您可能会发现它很简单
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 ....
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;