Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么OpenCV3.1 NormalBayesClassifier';在这个例子中,错误率这么高?_C++_Opencv_Machine Learning_Naivebayes_Opencv3.1 - Fatal编程技术网

C++ 为什么OpenCV3.1 NormalBayesClassifier';在这个例子中,错误率这么高?

C++ 为什么OpenCV3.1 NormalBayesClassifier';在这个例子中,错误率这么高?,c++,opencv,machine-learning,naivebayes,opencv3.1,C++,Opencv,Machine Learning,Naivebayes,Opencv3.1,我正在尝试使用OpenCV3.1的NormalBayesClassifier解决一个简单的问题,我可以轻松地生成训练数据。我决定把输入的数字分为偶数或奇数。显然,这可以100%准确地直接计算,但关键是为了熟悉OpenCV的ML功能 所以,我的第一个问题是-NormalBayesClassifier不是这个问题的合适模型,有没有理论上的原因 如果不是,第二个问题是,为什么我的错误率这么高cv::ml::StatModel::calcError()为我提供了30%-70%的输出 第三,降低错误率的最

我正在尝试使用OpenCV3.1的
NormalBayesClassifier
解决一个简单的问题,我可以轻松地生成训练数据。我决定把输入的数字分为偶数或奇数。显然,这可以100%准确地直接计算,但关键是为了熟悉OpenCV的ML功能

所以,我的第一个问题是-
NormalBayesClassifier
不是这个问题的合适模型,有没有理论上的原因

如果不是,第二个问题是,为什么我的错误率这么高
cv::ml::StatModel::calcError()
为我提供了30%-70%的输出

第三,降低错误率的最佳方法是什么

下面是一个最小的、自包含的片段,它演示了这个问题:

(为了清楚起见,对于偶数,分类/输出应为
0
,对于奇数,分类/输出应为
1


在代码中,您为算法提供了一个单一的特征,即要分类的数字。这是不够的,除非您多次提供相同数字的多个示例。如果您想让学习算法了解奇数vs偶数,那么需要考虑分类器可以使用什么样的特征来学习。大多数机器学习技术都需要您首先仔细设计特征

既然您想用ML进行实验,我建议如下:

  • 对于每个数字,创建5个特征,一个对每个数字进行编码。因此,5将是00005或f1=0,f2=0,f3=0,f4=0,f5=0,11098将是f1=1,f2=2,f3=0,f4=9,f5=8
  • 如果您的数字大于该数字,则只能保留最后5位数字
  • 训练你的分类器
  • 使用相同的编码进行测试。您希望从分类器中了解到,只有最后一个数字对确定奇数与偶数很重要

  • 如果你想更多地使用它,你可以用二进制格式编码数字。这将使分类器更容易了解数字的奇数或偶数

    来自doc:“普通贝叶斯分类器——这个简单的分类模型假设每个类别的特征向量都是正态分布的(尽管不一定是独立分布的)因此,假设整个数据分布函数为高斯混合,每类一个分量。算法使用训练数据估计每类的平均向量和协方差矩阵,然后使用它们进行预测。”显然,这种假设不适用于奇数和偶数。我认为大多数ml分类器都无法将奇数和偶数进行分类。嗨@Mika-谢谢你的澄清,但我不确定我是否理解。你能详细描述一下这是如何应用于奇偶问题的吗?你的特征空间只有一个维度,即值。NBC假设两个类都是正态分布的,因此理想情况下,每个类在要素空间中都有一个固定点,并且该类的样本分布在该点周围。但是在奇数和偶数情况下,你的点是规则分布的(并且在这个一维中是不可分离的,这对于许多其他ml分类器来说是个问题),好的,这是有意义的。OpenCV中是否有更合适的分类器能够解决这个问题?或者,或者除此之外,是否有一个更好的示例问题,我可以尝试使用贝叶斯分类器?请看一下的第一个答案。以贝叶斯分类器为例,我将从正态分布生成随机值,并向其添加一些噪声。谢谢
    #include <ml.h>
    #include <iomanip>
    
    int main() {
    
       const int numSamples = 1000;
       cv::RNG rng = cv::RNG::RNG((uint64) time(NULL));
    
       // construct training sample data
    
       cv::Mat samples;
       samples.create(numSamples, 1, CV_32FC1);
    
       for (int i = 0; i < numSamples; i++) {
          samples.at<float>(i) = (int)rng(10000);
       }
    
       // construct training response data
    
       cv::Mat responses;
       responses.create(numSamples, 1, CV_32SC1);
    
       for (int i = 0; i < numSamples; i++) {
          int sample = (int) samples.at<float>(i);
          int response = (sample % 2);
          responses.at<int>(i) = response;
       }
    
       cv::Ptr<cv::ml::TrainData> data = cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, responses);
    
       data->setTrainTestSplitRatio(.9);
    
       cv::Ptr<cv::ml::NormalBayesClassifier> classifier = cv::ml::NormalBayesClassifier::create();
    
       classifier->train(data);
    
       float errorRate = classifier->calcError(data, true, cv::noArray());
    
       std::cout << "Bayes error rate: [" << errorRate << "]" << std::endl;
    
       // construct prediction inputs
       const int numPredictions = 10;
    
       cv::Mat predictInputs;
       predictInputs.create(numPredictions, 1, CV_32FC1);
    
       for (int i = 0; i < numPredictions; i++) {
          predictInputs.at<float>(i) = (int)rng(10000);
       }
    
       cv::Mat predictOutputs;
       predictOutputs.create(numPredictions, 1, CV_32SC1);
    
       // run prediction
    
       classifier->predict(predictInputs, predictOutputs);
    
       int numCorrect = 0;
    
       for (int i = 0; i < numPredictions; i++) {
          int input = (int)predictInputs.at<float>(i);
          int output = predictOutputs.at<int>(i);
          bool correct = (input % 2 == output);
    
          if (correct)
             numCorrect++;
    
          std::cout << "Input = [" << (int)predictInputs.at<float>(i) << "], " << "predicted output = [" << predictOutputs.at<int>(i) << "], " << "correct = [" << (correct ? "yes" : "no") << "]"  << std::endl;
       }
    
       float percentCorrect = (float)numCorrect / numPredictions * 100.0f;
    
       std::cout << "Percent correct = [" << std::fixed << std::setprecision(0) << percentCorrect << "]" << std::endl;
    }
    
    Bayes error rate: [36]
    Input = [9150], predicted output = [1], correct = [no]
    Input = [3829], predicted output = [0], correct = [no]
    Input = [4985], predicted output = [0], correct = [no]
    Input = [8113], predicted output = [1], correct = [yes]
    Input = [7175], predicted output = [0], correct = [no]
    Input = [811], predicted output = [1], correct = [yes]
    Input = [699], predicted output = [1], correct = [yes]
    Input = [7955], predicted output = [1], correct = [yes]
    Input = [8282], predicted output = [1], correct = [no]
    Input = [1818], predicted output = [0], correct = [yes]
    Percent correct = [50]