【朴素贝叶斯】实战朴素贝叶斯_代码实现_数据和接口

接下来,进行代码实现。


【样本格式】

首先,定义一下输入样本的格式,这些样本用于对朴素贝叶斯模型进行训练。定义格式如下:

1:9242 13626 28005 41622 41623 34625 36848 5342 51265 
0:16712 49100 2933 65827 6200 
1:53396 3675 43979 25739 
0:17347 61515 53679 59426 
1:32712 39134 63265 65430 

每一行是一个样本。行首是这个样本所属的类别的索引,类别索引从0开始。当类别是以标签的形式存在的时候,可以建立类别标签与类别索引之间的联系。这个由其他程序来做,很简单。类别索引与后面的输入特征用冒号(“:”)相分隔。后面是特征词的索引。同样,特征词词串与索引之间的映射关系也可以建立。用索引的好处是:1. 使得分类器算法更加通用化;2. 整数处理相对字符串更加高效。


【数据结构】

接下来,定义数据结构。在“实战朴素贝叶斯——基本原理”一文中,我们已经分析了模型的参数空间。接下来,我直接给出数据结构代码:

//节点类,用来存储特征以及特征对应的后验概率。注意,此时默认特征取值为1
struct FeaProbNode
	{
		int iFeadId;
		double dProb;
	};
//节点类,用来存储类别、类别的先验概率、以及特征向量在该类别下的后验概率
struct ClassFeaNode
	{
		int iClassId;
		double dClassProb;	// the prior probability of a class
		vector<FeaProbNode> FeaVec;
	};

//对各个类别存储上述信息
vector<ClassFeaNode> ClassFeaVec;

对于FeaProbNode的内容,我们直接将特征与他的后验概率相联系起来了。那么在前文中我们说到,特征可以取不同的值,而对于每一个特征的取值,在相应的类别中,都有一个后验概率。在我们文本分类任务中,特征通常是词,词的取值,我们前文中已经提到过,有两种 ,分别是1和0,对应着这个词是否出现了。上面FeaProbNode中存储的概率,是词取值为1的概率;对于取值为0的概率,可以通过概率归一化条件计算得出。


【函数接口】

函数接口很简单,分别对应着模型训练、模型预测、模型序列化(存取),如下:

// The format of input samples:
//		ClassLabelIndex segmenter(not whitespace) ItemOneIndex whitespace ItemTwoIndex......
//	iClassNum: the number of class label index, [0, iClassNum-1]
//	iFeaTypeNum: the number of feature type index, [0, iFeaTypeNum-1]
//	sSegmenter: the segmenter between Class label index and Item index
//	iFeaExtractNum: the number of features which is going to extract
//	sFileModel: the output model into txt file
//	bCompactModel: whether to show some infor for debug, true for not include those infor
// 
// The format of compact model parameters 
//	1. the number of class
//	2. the prior probability of class
//	3. the conditional probability of p(item|class)
bool Train (const char * sFileSample, int iClassNum, int iFeaTypeNum, 
	string & sSegmenter, int iFeaExtractNum, const char * sFileModel, bool bCompactModel = true);

// Load the naive bayes model
bool LoadNaiveBayesModel (const char * sFileModel);

// predict according to the input features
bool PredictByInputFeas (vector<int> & FeaIdVec, int & iClassId);

// predict by input test corpus whose format is the same with the training corpus
bool PredictFrmTstCorpus (const char * sFileTestCorpus, string & sSegmenter, const char * sFileOutput);

Train函数的参数比较多。首先,要有输入样本的文本文件,格式在上文中已经描述;然后,是样本类别数目(决定了ClassFeaVec的大小)和特征类别数目(通常是词表的大小);然后,是样本和特征之间的分隔符,在我们的例子中是“:”;接下来,是指定我们最终在模型中要选择多少特征——在这个程序中,我把特征选择和参数训练放在一起了,好处是只扫描一遍样本,效率高,坏处是代码偶合性太强,不容易扩展;最后,是输出的模型文件,bCompactModel是个标志,是否输出额外的信息,以便调试模型,默认是关闭的。

其实上面这些内容都是放到一个类NaiveBayes里面的,为了叙述方便,拆开来说了。下一篇,讲训练过程。



  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值