我正在开发一个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。有谁知道如何解决这个问题?
答案 0 :(得分:0)
答案 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;
}