c# - 如何使用朴素贝叶斯和主成分分析对文档进行分类(C#、Accord.NET)

标签 c# matrix classification pca naivebayes

我正在开发一个电子邮件分类项目,该项目会将电子邮件分类为特定类别。到目前为止,我们将有趣的数据(例如:主题和正文)以及其他信息保存到我们的数据库中。我们已成功地将术语频率 - 逆文档频率应用于项目,以检索在我们的电子邮件主题和正文中找到的所有术语/功能的矩阵。该矩阵的一个非常小的样本输出将是:

      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

实际上,这个矩阵要大得多,因为我们有 165 封电子邮件的大约 23000 个术语。因为我们需要使用此矩阵中的术语对电子邮件进行分类,所以 23000 个特征实在太多了。这就是我们实现降维算法 (PCA) 的原因。这是通过使用以下代码(Accord 框架)完成的:

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

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

// Creates a projection of the information
double[,] components = pca.Transform(matrix, 20);

// Creates form to show components
frmRPCA frmPCA = new frmRPCA(components);
frmPCA.ShowDialog();

现在我们已经对维度进行了硬编码,但这暂时不应该成为问题。

我一直在研究 Accord 框架的示例,了解如何使用朴素贝叶斯进行分类,但我真的不知道如何将其付诸实践。主要是因为该示例在我们处理数字时使用文本,并且我不太了解分类的工作原理。 See the example on how to implement Naive Bayes .

基本上,我的原始矩阵包含我的特征及其 TF-IDF 值(请参见上面的示例),并且我想使用包含 PCA 的矩阵(pca.Transform 方法的输出)对它们进行分类。目前,我只有 2 个类需要对我的电子邮件进行分类(注册和提交)。我将如何实现这一目标?另外,如果我将来想添加多个类,我将如何扩展它?

示例输出应类似于:

doc1 Registration
doc2 Registration
doc3 Registration
doc4 Submission
doc5 Submission

最佳答案

如果您对分类感兴趣,那么 LDA(及其变体)可能更适合您的情况。事实上,PCA 试图通过仅查看数据来最小化方差。但是,如果您有关于数据的额外信息(例如类标签),则有更好的方法来实现您的需求。

  • 如果您有类标签形式的额外信息(即, 数据集中的每个样本都有一个关联的整数值,表示它属于哪个类),那么您可以使用LDA(线性判别分析)来减少 以有助于分类的方式确定维数。

  • 如果您有实际输出形式的额外信息(即,每个 数据集中的样本实际上有一个与关联的 double 值 它),然后你可以使用 PLS(偏最小二乘法)以一种有用的方式降低维度 回归。

假设您遇到分类问题,以下是如何使用 LDA 减少特征数据​​数量的示例:

// Create some sample input data instances. This is the same
// data used in the Gutierrez-Osuna's example available at:
// http://research.cs.tamu.edu/prism/lectures/pr/pr_l10.pdf

double[][] inputs = 
{
    // Class 0
    new double[] {  4,  1 }, 
    new double[] {  2,  4 },
    new double[] {  2,  3 },
    new double[] {  3,  6 },
    new double[] {  4,  4 },

    // Class 1
    new double[] {  9, 10 },
    new double[] {  6,  8 },
    new double[] {  9,  5 },
    new double[] {  8,  7 },
    new double[] { 10,  8 }
};

int[] output = 
{
    0, 0, 0, 0, 0, // The first five are from class 0
    1, 1, 1, 1, 1  // The last five are from class 1
};

// Then, we will create a LDA for the given instances.
var lda = new LinearDiscriminantAnalysis(inputs, output);

lda.Compute(); // Compute the analysis


// Now we can project the data into LDA space:
double[][] projection = lda.Transform(inputs);

如果您想将问题从 2 维减少到 1 维,您可以使用:

double[][] reduced_data = lda.Transform(inputs, 1);

结果将是一个 10x1 矩阵。它将包含对执行分类仍然有用的数据的较低维度表示。因此,您可以使用 reduced_data 来代替使用原始数据来学习分类器。

此外,LDA 对象还附带一个简单的最小距离分类器,您可以使用它来对实例进行分类。例如,您可以使用

对数据集进行分类
int[] results = lda.Classify(inputs);

但是,没有什么可以阻止您使用您可能喜欢的任何其他分类器(例如朴素贝叶斯)。例如,为了使用朴素贝叶斯,您可以使用

// Create a new normal distribution Naive Bayes classifier for 
// a classification problem with 1 feature and the two classes
var nb = new NaiveBayes.Normal(classes: 2, inputs: 1);

// Compute the Naive Bayes model
nb.Estimate(reduced_data, output);

// Now, if we would like to classify the first instance 
// in our dataset, we would use
int result = nb.Compute(lda.Transform(input[0]));

还有框架附带的示例应用程序,应该 demonstrate how LDA works以及如何naive bayes works .

关于c# - 如何使用朴素贝叶斯和主成分分析对文档进行分类(C#、Accord.NET),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29696565/

相关文章:

javascript - 改善 javascript 矩阵效果中的多个 setInterval() 滞后

c++ - 将 cv::Mat A 的每个成员与 cv::Mat B 合并,以创建一个带有 [a(x,y),b(x,y)] 的 cv::Mat C

c - OpenGL 投影、 View 和世界矩阵

machine-learning - Vowpal Wabbit 多类线性分类

c# - 如何引用 System.Web.Optimization 程序集的 1.1.0.0 版本

c# - Xamarin.forms 共享项目在创建时出错

c# - 在 WHERE 子句中具有多个条件的 LINQ 查询

c# - 如何在 C# 中执行 fsync()?

python - Stanford NLP Parser 对 Kaggle Movie 评论中使用的相同语句给出不同的结果(情感)

python - 如何使用 NLTK BigramAssocMeasures.ch_sq