现在的位置: 首页 > 综合 > 正文

再次实现Logistic Regression(c++)_实现和测试

2014年11月21日 ⁄ 综合 ⁄ 共 2201字 ⁄ 字号 评论关闭

1. 实现

相比上面的实现,主要是随机梯度下降的算法代码稍有变动。变动后,模型训练实现如下:

// the update formula is : theta_new = theta_old - dLearningRate * (dY - iClass) * dXi
void LogisticRegression::UpdateThetaVec(Sample & theSample, double dY, double dLearningRate)
{
	vector<FeaValNode>::iterator p = theSample.FeaValNodeVec.begin();
	while (p != theSample.FeaValNodeVec.end())
	{
		if (p->iFeatureId < (int)ThetaVec.size())
		{
			double dGradient = (dY - theSample.iClass) * p->dValue;
			double dDelta = dGradient * dLearningRate;
			ThetaVec[p->iFeatureId] -= dDelta;
		}
		p++;
	}
}

代码注释中写了权重更新公式。TrainSGDOnSampleFile函数实现没变。

2. 测试

2.1 数据

数据还是从libsvm的网站上找的二分类数据,链接为 http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary.html 。用的其中australian数据,共14维实值特征,2分类问题,689个样本。选择500个样本作为训练集,其余样本作为测试集。对原始数据格式做了处理,输入数据格式如下:

0 1:1 2:-0.869774 3:-0.517857 4:-1 5:-0.0769231 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-0.86 14:-1 
1 1:1 2:0.0201503 3:-0.821429 5:-0.0769231 7:-0.824561 8:1 9:1 10:-0.641791 11:1 13:-0.59 14:-0.9498 
1 1:1 2:0.313383 3:-0.392857 5:0.384615 6:0.75 7:-0.508772 8:1 9:1 10:-0.910448 11:-1 13:-1 14:-1 
1 1:1 2:-1 3:-0.714286 4:-1 5:0.230769 6:-0.25 7:-0.877193 8:1 9:1 10:-0.940299 11:1 13:-0.88 14:-0.98 
1 1:1 2:-0.83218 3:-0.321429 5:0.538462 6:-0.25 7:-0.929825 8:1 9:-1 10:-1 11:1 13:-0.94 14:-0.992 
0 1:-1 2:-0.754286 3:-0.166786 5:-0.538462 6:0.75 7:-0.994035 8:-1 9:-1 10:-1 11:-1 13:-0.68 14:-0.9999 
0 1:1 2:-0.884812 3:-0.285714 5:0.230769 6:0.75 7:-0.988421 8:-1 9:1 10:-0.970149 11:-1 13:-0.88 14:-0.99998 
0 1:1 2:-0.366015 3:-0.821429 4:-1 5:0.230769 6:-0.25 7:-0.789474 8:-1 9:-1 10:-1 11:-1 12:-1 13:-0.8 14:-1 
0 1:1 2:-0.536241 3:-0.75 5:0.230769 6:-0.25 7:-0.754386 8:1 9:1 10:-0.910448 11:1 13:-0.671 14:-1 
0 1:1 2:-0.769323 3:-0.946429 4:-1 5:0.692308 6:0.5 7:-0.947368 8:-1 9:-1 10:-1 11:1 13:-0.868 14:-0.99996 

各个字段含义:classindex featureindex1:featurevalue1 featureindex2:featurevalue2......

需要注意的是,各维实值特征都已经归一化到[-1, 1]区间之内了。

2.2 训练

沿用从前的参数,代码如下:

TrainSGDOnSampleFile ("..\\Data\\australian_scale_train.txt", 15, 0.01, 100, 0.05);
SaveLRModelTxt ("Model\\Mod_001_100_005_scale.txt");

迭代两次后,模型收敛。

2.3 测试

结果是 88.35%

The total number of sample is : 189
The correct prediction number is : 167
Precision : 0.883598

要注意的是,对于实值输入,将各个维度的输入值归一化到同一个区间范围内非常重要,我用原始数据尝试跑一下训练程序,结果是没有训练出来。原因很简单:输入的值特别大或者特别小,sigmoid函数的输出值为0.0或者1.0,cost function的值则计算为正负无穷,训练无法停止。归根结底一句话——由于sigmoid函数在计算机中的精度限制,我们必须对实值输入进行归一化处理。

完。

转载请注明出处:http://blog.csdn.net/xceman1997/article/details/18136269

抱歉!评论已关闭.