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

上文中找的数据集和有点儿小,再找个大点儿的尝试下。这次找的是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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值