上文中找的数据集和有点儿小,再找个大点儿的尝试下。这次找的是libsvm的一个数据集合,预测是否是成年人的,原始特征14个,包括6个连续特征和8个枚举特征。连续特征被区间化,转成枚举特征,枚举特征进一步按照枚举取值转成0-1离散特征,共得到123个特征0-1特征。训练集1605个样本,测试集30956个样本。原始数据可以从这个链接下载:http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary.html
数据样例:
0 5 7 14 19 39 40 51 63 67 73 74 76 78 83
0 3 6 17 22 36 41 53 64 67 73 74 76 80 83
0 5 6 17 21 35 40 53 63 71 73 74 76 80 83
0 2 6 18 19 39 40 52 61 71 72 74 76 80 95
0 3 6 18 29 39 40 51 61 67 72 74 76 80 83
0 4 6 16 26 35 45 49 64 71 72 74 76 78 101
1 5 7 17 22 36 40 51 63 67 73 74 76 81 83
1 2 6 14 29 39 42 52 64 67 72 75 76 82 83
1 4 6 16 19 39 40 51 63 67 73 75 76 80 83
1 3 6 18 20 37 40 51 63 71 73 74 76 82 83
按照参数组合0.01(学习率)、100(最大迭代次数)、0.05(cost最小降低幅度)进行训练,迭代三次,log:
Hello world for Logistic Regression
In loop 0: current cost (0.435969) previous cost (1) ratio (0.564031)
In loop 1: current cost (0.369433) previous cost (0.435969) ratio (0.152616)
In loop 2: current cost (0.354655) previous cost (0.369433) ratio (0.0400018)
测试结果,分类精度:
The total number of sample is : 30956
The correct prediction number is : 25950
Precision : 0.838287
记得从前用libsvm,精度和这个差不多。换一个参数组合,保持学习率和最大迭代次数,将cost最小降低幅度由0.05改成了0.01,条件更苛刻了。迭代log如下:
Hello world for Logistic Regression
In loop 0: current cost (0.435969) previous cost (1) ratio (0.564031)
In loop 1: current cost (0.369433) previous cost (0.435969) ratio (0.152616)
In loop 2: current cost (0.354655) previous cost (0.369433) ratio (0.0400018)
In loop 3: current cost (0.347017) previous cost (0.354655) ratio (0.0215371)
In loop 4: current cost (0.342248) previous cost (0.347017) ratio (0.0137425)
In loop 5: current cost (0.338963) previous cost (0.342248) ratio (0.00960019)
测试结果,分类精度:
The total number of sample is : 30956
The correct prediction number is : 26068
Precision : 0.842098
精度有所提升,意料之中。
接下来我做了一个蛮有意思的事情。众所周知,LR的一个优点就是能够高效的利用大规模特征,这意味着在实际应用中,候选特征非常多。那么,LR模型如何做特征选择呢?我头脑中最native的一个想法,就是把所有候选特征都用上,进行模型训练,如果特征的区分力弱,则这个特征的训练出来的权重就会比较低,那么我们对所有特征权重排序,去除不重要的特征就行了。这种去除,会对模型的性能又怎样的影响呢?接下来,我就是要在上述数据的基础上,进行尝试。
方法是在训练好的模型参数基础上,将值过于低的参数直接设置为0,使之不发挥作用。代码如下:
void ToDeleteLater (const char * sFileIn, const char * sFileOut, double dThreshold)
{
ifstream in (sFileIn);
ofstream out (sFileOut);
vector<double> ParaVec;
copy (istream_iterator<double>(in), istream_iterator<double>(), back_inserter(ParaVec));
double iNum = 0;
vector<double>::iterator p = ParaVec.begin();
while (p != ParaVec.end())
{
double dTmp = abs(*p);
if (dTmp < dThreshold)
{
out << 0 << endl;
iNum++;
}
else
out << *p << endl;
p++;
}
cout << iNum << endl;
}
呵呵,看函数名就看出是临时弄得。测试的代码:
ToDeleteLater ("Model\\Mod_ala_001_100_001.txt", "Model\\Mod_ala_001_100_001_ex.txt", 0.01);
LoadLRModelTxt ("Model\\Mod_ala_001_100_001_ex.txt");
PredictOnSampleFile ("..\\Data\\svm_ala_test.txt", "Model\\Rslt_ala_001_100_001_ex.txt", "Model\\Log_ala_001_100_001_ex.txt");
尝试了ToDeleteLater函数中dThreshold的不同取值,结果如下:
dThreshold=0.01 去除特征数目=23 分类精度=0.842098
dThreshold=0.05 去除特征数目=53 分类精度=0.842131
dThreshold=0.1 去除特征数目=64 分类精度=0.842389
dThreshold=0.2 去除特征数目=84 分类精度=0.836122
baseline精度是0.842098,基本特征数目是123。可以看到,最开始,精度没变;之后,甚至是去除了一半左右的特征,精度逐渐升高,说明我们训练过程中遇到了过拟合;最后,当阈值很高的时候,去除了大部分特征,精度才略有下降。
初步能说明两个事情:
1. 删除较小权重的特征,对模型性能影响不大,甚至有提升
2. 跟数据集、训练方法(没有加L1或L2 regulation)有关,存在过拟合
完。
另,转载请注明出处:http://blog.csdn.net/xceman1997/article/details/17927195