如何解决使用主成分分析抛出的OutOfMemoryException

时间:2015-05-08 11:29:11

标签: c# machine-learning classification pca accord.net

我正在开发一个C#项目,该项目使用主成分分析在[,]矩阵上应用特征缩减/降维。矩阵列是从集合电子邮件中提取的特征(单词和双字母组)。一开始我们有大约156封电子邮件,结果大约有23000个条款,所有内容都有效,因为它应该使用以下代码:

public static double[,] GetPCAComponents(double[,] sourceMatrix, int dimensions = 20, AnalysisMethod method = AnalysisMethod.Center) 
{
    // Create Principal Component Analysis of a given source
    PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis(sourceMatrix, method);

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

    // Creates a projection of the information
    double[,] pcaComponents = pca.Transform(sourceMatrix, dimensions);

    // Return PCA Components
    return pcaComponents;
}

我们收到的组件后来使用Accord.NET框架中的线性判别分析'分类方法进行了分类。一切都在按原样运作。

现在我们已经增加了out数据集的大小(1519封电子邮件和68375个术语),我们起初得到了一些OutOfMemory Exceptions。我们能够通过调整代码的某些部分来解决这个问题,直到我们能够到达计算PCA组件的部分。现在这需要大约45分钟,这太长了。在检查the website of Accord.NET on PCA之后,我们决定尝试使用最后一个使用协方差矩阵的示例,因为它说:“有些用户想要分析大量数据。在这种情况下,可能会直接计算数据上的SVD在内存异常或过多的计算时间“。因此,我们将代码更改为以下内容:

public static double[,] GetPCAComponents(double[,] sourceMatrix, int dimensions = 20, AnalysisMethod method = AnalysisMethod.Center) 
    {
        // Compute mean vector
        double[] mean = Accord.Statistics.Tools.Mean(sourceMatrix);

        // Compute Covariance matrix
        double[,] covariance = Accord.Statistics.Tools.Covariance(sourceMatrix, mean);

        // Create analysis using the covariance matrix
        var pca = PrincipalComponentAnalysis.FromCovarianceMatrix(mean, covariance);

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

        // Creates a projection of the information
        double[,] pcaComponents = pca.Transform(sourceMatrix, dimensions);

        // Return PCA Components
        return pcaComponents;
    }

然而,这会引发System.OutOfMemoryException。有谁知道如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我认为并行化你的求解器是最好的选择。

也许像FEAST这样的东西会有所帮助。

http://www.ecs.umass.edu/~polizzi/feast/

Parallel linear algebra for multicore system

答案 1 :(得分:0)

问题是代码使用锯齿状矩阵而不是多维矩阵。关键是double [,]需要分配连续的内存量,这可能很难找到,具体取决于你需要的空间。如果使用锯齿状矩阵,则会分散内存分配,并且更容易找到空间。

您可以通过升级到最新版本的框架并使用新API进行统计分析来避免此问题。不是在构造函数中传递源矩阵并调用.Compute,而是简单地调用.Learn():

public static double[][] GetPCAComponents(double[][] sourceMatrix, int dimensions = 20, AnalysisMethod method = AnalysisMethod.Center) 
{
    // Create Principal Component Analysis of a given source
    PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis(method)
    {
        NumberOfOutputs = dimensions // limit the number of dimensions
    };

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

    // Creates a projection of the information
    double[][] pcaComponents = pca.Transform(sourceMatrix);

    // Return PCA Components
    return pcaComponents;
}