在opencv的ml模块中有个统计模型类,而其他的比如朴素贝叶斯分类器、knn、svm等等其他模型都是基于该模型上派生出来的。所以先介绍下该模型。

该类的定义在文件“opencv\sources\modules\ml\include\opencv2\ml\ml.hpp”中:

class CV_EXPORTS_W CvStatModel
{
public:
CvStatModel();
virtual ~CvStatModel(); virtual void clear(); //save函数用来将整个模型状态保持到指定的XML 或者YAML文件中,并按照具体的类看是使用默认的名字还是指定的名字.
//使用了CxCore中的数据持久性功能。
CV_WRAP virtual void save(const char* filename, const char* name = 0) const; // load函数从指定的XML或者YAML中装载模型中指定的或者默认名字部分 //而之前的被装载的模型已经通过CvStatModel::clear()初始化了.
CV_WRAP virtual void load(const char* filename, const char* name = 0); // write函数会以将完整的模型以指定或者默认名字存储到文件中。该函数会被 CvStatModel::save()调用.
virtual void write(CvFileStorage* storage, const char* name) const; // read函数会从文件中指定的节点上读取整个模型。使用函数GetFileNodeByName()来定位节点。
//之前的模型也是需要被函数 CvStatModel::clear()初始化的.
virtual void read(CvFileStorage* storage, CvFileNode* node); //下面这几个函数被注释掉是因为它们不存在该模型中,只是对于其他的ml模型
//来说是有的,所以这里就完全不设定该函数,只是虽然各自派生的ml模型有各
//自的这几个函数,可是行为还是很类似的,所以就统一在该基类中介绍了。
// virtual bool train( const Mat& train_data, [int tflag,] ...,
// const Mat& responses, ..., [const Mat& var_idx,] ...,
// [const Mat& sample_idx,] ... [const Mat& var_type,] ...,
// [const Mat& missing_mask,] <misc_training_alg_params> ...
// )=0; // virtual float predict( const Mat& sample ... ) const=0; protected:
const char* default_model_name;
};

实现部分:

在文件“\opencv\sources\modules\ml\src\inner_functions.cpp”中

#include "precomp.hpp"
//构造函数,对该类唯一的类成员进行赋值
CvStatModel::CvStatModel()
{
default_model_name = "my_stat_model";
}
//虚析构函数,调用虚函数clear()来执行不同的类的清理工作
CvStatModel::~CvStatModel()
{
clear();
}
void CvStatModel::clear(){}
//写函数,将数据写入到指定的文件中
void CvStatModel::save( const char* filename, const char* name ) const
{
//存储文件的指针初始化
CvFileStorage* fs = 0;
//
CV_FUNCNAME( "CvStatModel::save" ); __BEGIN__;
//打开传入该函数的文件
CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_WRITE )); if( !fs )
CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" );
//如果未传入模型的名字,则写入默认的模型名字
write( fs, name ? name : default_model_name ); __END__;
//释放指向文件的指针
cvReleaseFileStorage( &fs );
} //装载指定文件中的数据
void CvStatModel::load( const char* filename, const char* name )
{
CvFileStorage* fs = 0; CV_FUNCNAME( "CvStatModel::load" ); __BEGIN__; CvFileNode* model_node = 0; CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ ));
if( !fs )
EXIT; if( name )
model_node = cvGetFileNodeByName( fs, 0, name );
else
{
CvFileNode* root = cvGetRootFileNode( fs );
if( root->data.seq->total > 0 )
model_node = (CvFileNode*)cvGetSeqElem( root->data.seq, 0 );
} read( fs, model_node ); __END__;
//释放指向文件的指针
cvReleaseFileStorage( &fs );
}
//写函数
void CvStatModel::write( CvFileStorage*, const char* ) const
{
OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" );
} void CvStatModel::read( CvFileStorage*, CvFileNode* )
{
OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" );
}

该文件中还有大量的数学计算函数,比如矩阵分解,从GMM上采样等等。

备注:好了这里就主要介绍下几个不存在于该类的函数。

1、模型训练函数

 bool CvStatModel::train(const Mat& train_data, [int tflag,] ..., const Mat& responses, ..., [const
Mat& var_idx,] ..., [const Mat& sample_idx,] ... [const Mat& var_type,] ...,
[const Mat& missing_mask,] <misc_training_alg_params> ... ) = 0

该函数是通过输入特征向量和对应的输出目标值(responses)来训练模型的。输入和输出的向量/值都是以矩阵的形式传递的。默认情况下输入特征向量是以train_data rows,也就是一个训练样本中所有的成分(特征)是连续存储的。不过一些算法是需要处理它们的转置形式的,只要当基于所有的输入集合中的特征都是连续存储的(个人:其实也就是存储成一个矩阵而不是链表).如果两种布局都支持的话,那么该方法将会有个tflag参数用来指定具体的情况。

• tflag=CV_ROW_SAMPLE 特征向量以行形式存储;

• tflag=CV_COL_SAMPLE 特征向量以列形式存储。

train_data 必须是 CV_32FC1 (32位浮点类型,单通道) 格式的. 而Responses通常存储成1D向量(一行或者一列)形式 ,格式有: CV_32SC1(只在分类的时候用); CV_32FC1, 其中一个输入向量对应着一个目标值.

对于分类问题来说, responses 是离散的标签;

对于回归问题来说,responses 是模型函数需要逼近的值。

一些算法只能用来分类;一些算法只能用来回归;还有一些能用在两方面。对于回归来说,输出变量的类型既可以是通过独立的参数传递也可以是var_type向量的最后一个元素:

• CV_VAR_CATEGORICAL 输出变量是离散的类别标签;

• CV_VAR_ORDERED(=CV_VAR_NUMERICAL) 输出的值是有序的,也就是说两个不同的值可以进行数值对比,当然这是一个回归问题。

输入变量的类型可以通过var_type指定。大多数算法只能处理有序的输入变量。

许多ML模型会在一个特征子集或者是训练集中样本子集上进行训练,为了能够容易的在不同状态间选择,该函数还包含了var_idx 和 sample_idx 这两个参数。前者是用来指定感兴趣的变量(特征);后者是用来指定感兴趣的样本。这两个向量都是整型向量 (CV_32SC1) ,(当然是基于0开始索引的)或者是基于激活的变量/样本的8位 (CV_8UC1)标记。当传递一个NULL指针给这两个参数时,也就意味着所有的变量/样本都会用来训练。

另外,许多算法可以处理缺失的值的情况,也就是说当某个具体的训练样本的特征的值是未知的(比如,忘记测量一个病人在礼拜一时候的体温)参数 missing_mask,是一个与train_data 具有相同size的8位的矩阵,它用来标记缺失的值(即该标记矩阵中非0值)

通常来说,在进入到训练阶段之前的模型的状态是需要调用CvStatModel::clear()来重置的 ;不过某些算法会让你选择是否使用新的训练数据来更新模型的状态而不是重置他们。

float CvStatModel::predict(const Mat& sample, ...) const

该函数用来对一个新的样本进行预测其response。在分类问题中,该方法返回一个类别标签;在回归问题上,盖方法返回一个函数值 。输入的样本必须与传递给train函数中train_data一样大的特征维度。如果var_idx 参数传递给了train,那么记得,也同时只提取必须的特征给该函数。后缀的const表示该预测函数不会影响到模型的内部状态,所以该方法可以安全的在不同的线程中被调用。

opencv7-ml之统计模型的更多相关文章

  1. 关于ML.NET v0.6的发布说明

    ML.NET 0.6版本提供了几项令人兴奋的新增功能: 用于构建和使用机器学习模型的新API 我们主要关注的是发布用于构建和使用模型的新ML.NET API的第一次迭代.这些新的,更灵活的API支持新 ...

  2. ML(1): 入门理论

    机器学习相关的文章太多,选取一篇本人认为最赞的,copy文章中部分经典供自己学习,摘抄至 http://www.cnblogs.com/subconscious/p/4107357.html#firs ...

  3. [ML] I'm back for Machine Learning

    Hi, Long time no see. Briefly, I plan to step into this new area, data analysis. In the past few yea ...

  4. ANN:ML方法与概率图模型

    一.ML方法分类:          产生式模型和判别式模型 假定输入x,类别标签y         -  产生式模型(生成模型)估计联合概率P(x,y),因可以根据联合概率来生成样本:HMMs   ...

  5. Spark2 ML 学习札记

    摘要: 1.pipeline 模式 1.1相关概念 1.2代码示例 2.特征提取,转换以及特征选择 2.1特征提取 2.2特征转换 2.3特征选择 3.模型选择与参数选择 3.1 交叉验证 3.2 训 ...

  6. [Machine Learning & Algorithm]CAML机器学习系列2:深入浅出ML之Entropy-Based家族

    声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 写在前面 记得在<Pattern Recognition And Machine ...

  7. [Machine Learning & Algorithm]CAML机器学习系列1:深入浅出ML之Regression家族

    声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 符号定义 这里定义<深入浅出ML>系列中涉及到的公式符号,如无特殊说明,符号 ...

  8. 机器学习 - ML

    CNCC - 2016 | 机器学习(原文链接) Machine Learning - ML,机器学习起源于人工智能,是AI的一个分支. 机器学习的理论基础:计算学习理论 - Computationa ...

  9. ML 基础知识

    A computer program is said to learn from experience E with respect to some task T and some performan ...

随机推荐

  1. 截取URL的某个参数值

          原文作者链接 https://www.jianshu.com/p/c9324d237a8e  

  2. 【读书笔记】iOS-网络-使用推送通知

    一,本地通知 本地通知有64位的最大限制.虽然,你依然可以调度通知,不过到到达的通知数被限定为接近64个,并且按照fireDate的顺序排序,系统会忽略掉其余的通知.这意味着如果现在有64个调用的本地 ...

  3. offsetTop 实现滚动条内内容定位

    js代码: var _parent_top = document.getElementsByClassName('parent')[0].offsetTop;var _phase_top = docu ...

  4. CSS隐藏多余的文字

    效果: <p><strong>商品名称:</strong>新鲜现摘云南绥江半边红李子甜脆脱骨李6斤当季绿色有机水果包邮</p></div> ...

  5. JavaSE——TCP协议网络编程(一)

    实现客户端与服务端的连接: 创建TCP服务端的 ServerSocket ServerSocket :此类实现服务器套接字.服务器套接字请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结 ...

  6. JS--我发现,原来你是这样的JS(三)(基础概念--灵魂篇)

    一.介绍 这是红宝书(JavaScript高级程序设计 3版)的读书笔记第三篇(灵魂篇介绍),有着剩下的第三章的知识内容. 红宝书这本书可以说是难啃的,要看完不容易,挺厚的,要看懂更不容易,要熟练js ...

  7. Git冲突与解决方法

    1.git冲突的场景 情景一:多个分支代码合并到一个分支时: 情景二:多个分支向同一个远端分支推送代码时: 实际上,push操作即是将本地代码merge到远端库分支上. 关于push和pull其实就分 ...

  8. ionic之angular1.X缓存问题解决

    众所周知ionic的angular1.X解决缓存的问题有: 1.在app.js里面修改:默认是true,设置了缓存 .state('tab.msg-main', { url: '/msg-main', ...

  9. 使用Tomcat部署应用

    概述 一个简单的web项目下载地址:https://files.cnblogs.com/files/Mike_Chang/hello.rar Tomcat部署应用三种方法. 方法一 将一个WAR文件或 ...

  10. [Android] 修图工具Draw9patch使用小结(附ubuntu快捷截图方法)

    做项目的时候,素材图遇到点问题,然后老大大概给我讲了讲android下面图片格式.9.png和draw 9-patch的用法,感觉很清楚也很有用,所以记录一下. 原文地址请保留http://www.c ...