2015-05-08 3 views
1

Я работаю над проектом на C#, который использует компонентный компонентный анализ, чтобы применить уменьшение функции/уменьшение размера в матрице [,]. Матричные столбцы - это функции (слова и биграммы), которые были извлечены из набора писем. В начале у нас было около 156 писем, в результате которых около 23000 терминов и все работало, как это предполагалось, используя следующий код:Как решить OutOfMemoryException, которое выбрасывается с использованием анализа основных компонентов

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. Все работало так, как должно.

Теперь, когда мы увеличили размер набора данных (1519 писем и 68375 терминов), мы сначала получали некоторые исключения OutOfMemory. Мы смогли решить эту проблему, отрегулировав некоторые части нашего кода, пока мы не смогли достичь той части, где мы вычисляем компоненты 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. кто-нибудь знает, как решить эту проблему?

+0

Перейти на x64 и установить больше памяти? – xanatos

+0

Насколько велика матрица источника входного массива? Является ли исключение также поднятым, если вы предоставляете только одну запись? –

+0

У меня квад CPU Q9300 2.50GHz - оперативная память 8 ГБ и 64-разрядная операционная система, поэтому я не уверен, проблема в этом или нет. При использовании первого примера выборки кода не выдает ошибку, но занимает + - 45 минут. Использование ковариационной матрицы должно быть лучше, но порождает ошибку. – Redesign1991

ответ

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; 
} 
+0

Я пытаюсь реализовать класс, который вы предоставили. В настоящее время принимается 1 ошибка на: собственные векторы = матрица.Сортировка (собственные значения, собственные векторы, новый GeneralComparer (ComparerDirection.Descending, true)); говорит, что аргументы типа не могут быть выведены из использования. Попробуйте указать неявно. Имейте пространство имен Accord.Math, на которое ссылается – Redesign1991

+0

К сожалению, я забыл включить этот метод. Вот он: https://gist.github.com/cesarsouza/aeb3c080c502ea5702b5 – Cesar