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