使用Accord.Net的编码对象来编码第二个数据集

时间:2012-10-24 15:15:24

标签: c# machine-learning bayesian accord.net

我试图弄清楚如何使用机器学习NaiveBayes类来使用Accord.Net Framework进行贝叶斯预测。我已经按照文档中列出的example code进行操作,并且能够从示例中创建模型。

我无法弄清楚如何根据该模型进行预测。

Accord.Net框架的工作方式是使用名为Codification的类将字符串表转换为这些字符串的数字符号表示。以下是我如何创建输入和输出DataTable来训练模型(此代码的90%直接来自示例):

        var dt = new DataTable("Categorizer");
        dt.Columns.Add("Word");
        dt.Columns.Add("Category");

        foreach (string category in categories)
        {
            rep.LoadTrainingDataForCategory(category,dt);
        }

        var codebook = new Codification(dt);
        DataTable symbols = codebook.Apply(dt);
        double[][] inputs = symbols.ToArray("Word");
        int[] outputs = symbols.ToIntArray("Category").GetColumn(0);

        IUnivariateDistribution[] priors = {new GeneralDiscreteDistribution(codebook["Word"].Symbols)};
        int inputCount = 1;
        int classCount = codebook["Category"].Symbols;
        var target = new NaiveBayes<IUnivariateDistribution>(classCount, inputCount, priors);

        target.Estimate(inputs, outputs);

这一切都成功了。现在,我有新的输入,我想测试我刚刚构建的训练数据模型。所以我试着这样做:

        var testDt = new DataTable("Test Data");
        testDt.Columns.Add("Word");
        foreach (string token in tokens)
        {
            testDt.Rows.Add(token);
        }

        DataTable testDataSymbols = codebook.Apply(testDt);
        double[] testData = testDataSymbols.ToArray("Word").GetColumn(0);

        double logLikelihood = 0;
        double[] responses;
        int cat = target.Compute(testData, out logLikelihood, out responses);

请注意,我使用的是与之前构建模型时使用的相同的codebook对象。我希望使用与原始模型相同的代码簿来编码数据,否则相同的单词可能会被编码为两个完全不同的值(原始模型中的“bob”一词可能对应于数字23,而在新模型中,数字43 ......没办法工作。)

但是,我在这一行收到NullReferenceException错误:

        DataTable testDataSymbols = codebook.Apply(testDt);

这是错误:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Accord.Statistics.Filters.Codification.ProcessFilter(DataTable data)
   at Accord.Statistics.Filters.BaseFilter`1.Apply(DataTable data)
   at Agent.Business.BayesianClassifier.Categorize(String[] categories, String testText) 

我传入的对象都不是null,所以这必须是代码中更深层次的事情。但我不确定是什么。

感谢您的帮助。如果有人知道一个例子,其实际上是根据Accord.Net的贝叶斯实例做出的预测,如果你分享它,我将非常感激。

1 个答案:

答案 0 :(得分:4)

对于最后部分缺少文档感到抱歉。为了获得新单词的相同整数编码,您可以使用代码簿的Translate方法:

// Compute the result for a sunny, cool, humid and windy day:
double[] input = codebook.Translate("Sunny", "Cool", "High", "Strong").ToDouble(); 

int answer = target.Compute(input);

string result = codebook.Translate("PlayTennis", answer); // result should be "no"

但也应该可以调用codebook.Apply将相同的转换应用于新数据集。如果您认为这是一个错误,您是否要填写问题跟踪器中的错误报告?