liblinear实践初步

在相关推荐项目的改版中,对liblinear/fm/xgboost等主流成熟算法模型的训练效果进行了尝试和对比,并在一期改造中选择了liblinear实际上线使用。本文主要从工程应用的角度对liblinear涉及的各模式进行初步介绍,并给出liblinear/fm/xgboost的实际评测结果供参考。

 

1.      Liblinear说明

考虑到训练效率,本次选用的为多线程并行版liblinear,实际为liblinear-multicore-2.1-4,首先直接给出其train命令所支持的各模式说明,各模式选择不仅与我们使用liblinear工具直接相关,也对我们理解liblinear很有帮助,下面即主要围绕这些模式展开。

Parallel LIBLINEAR is only available for -s0, 1, 2, 3, 11 now

Usage: train [options] training_set_file[model_file]

options:

-s type : set type of solver (default 1)

  formulti-class classification

        0 -- L2-regularized logistic regression (primal)

        1 -- L2-regularized L2-loss support vector classification (dual)

        2 -- L2-regularized L2-loss support vector classification (primal)

        3 -- L2-regularized L1-loss support vector classification (dual)

        4 -- support vector classification by Crammer and Singer

        5 -- L1-regularized L2-loss support vector classification

        6 -- L1-regularized logisticregression

        7 -- L2-regularized logistic regression (dual)

  forregression

       11 -- L2-regularized L2-loss support vector regression (primal)

       12 -- L2-regularized L2-loss support vector regression (dual)

       13 -- L2-regularized L1-loss support vector regression (dual)

 

1.1  liblinear还是libsvm

既然是liblinear相关,不可免俗地会涉及到这个问题,当然其实这是个很大的命题,在此我们截取重点简单介绍。

首先,liblinear和libsvm都是国立台湾大学林智仁(Chih-Jen Lin)老师团队开发的,libsvm早在2000年就已经发布,liblinear则在2007年才发布首个版本。

在原理和实现上存在差别,libsvm是一套完整的svm实现,既包含基础的线性svm,也包含核函数方式的非线性svm;liblinear则是针对线性场景而专门实现和优化的工具包,同时支持线性svm和线性Logistic Regression模型。由于libsvm支持核函数方式实现非线性分类器,理论上,libsvm具有更强的分类能力,应该能够处理更复杂的问题。

但是,libsvm的训练速度是个很大的瓶颈,按一般经验,在样本量过万后,libsvm就比较慢了,样本量再大一个数量级,通常的机器就无法处理了;而liblinear设计初衷就是为了解决大数据量的问题,正因为只需要支持线性分类,liblinear可以采用与libsvm完全不一样的优化算法,在保持线性svm分类时类似效果的同时,大大降低了训练计算复杂度和时间消耗。

同时,在大数据背景下,线性分类和非线性分类效果差别不大,尤其是在特征维度很高而样本有限的情况下,核函数方式有可能会错误地划分类别空间,导致效果反而变差。林智仁老师也给出过很多实际例子证明,人工构造特征+线性模型的方式可以达到甚至超过kernel SVM的表现,同时大大降低训练的时间和消耗的资源。

关于实际时间对比,liblinear作者官方给出了以下数据:对于LIBSVM数据集中某实例"20242个样本/47236个特征",在保持交叉验证的精度接近的情况下,liblinear仅耗时约3秒,远远小于libsvm的346秒。

% time libsvm-2.85/svm-train -c 4 -t 0 -e 0.1 -m 800 -v 5rcv1_train.binary

Cross Validation Accuracy = 96.8136%

345.569s

% time liblinear-1.21/train -c 4 -e 0.1 -v 5rcv1_train.binary

Cross Validation Accuracy = 97.0161%

2.944s

 

1.2  具体solver的选择?线性svm还是logistic regression/L1正则化项还是L2正则化项

liblinear支持多种solver模式,以下直接列举liblinear支持的几种典型solver模式对应的结构风险函数(结构风险函数由损失函数和正则化项/罚项组合而成,实际即为求解结构风险函数最小值的最优化问题),以方便说明和理解。

L2-regularized L1-loss Support VectorClassification

L2-regularized L2-loss Support Vector Classification

L1-regularized L2-loss Support Vector Classification

L2-regularized Logistic Regression

L1-regularized Logistic Regression

Liblinear中同时支持线性svm和logisticregression,两者最大区别即在于损失函数(loss function)不同,损失函数是用来描述预测值f(X)与实际值Y之间差别的非负实值函数,记作L(Y, f(X)),即上述公式中的项。

另一个重要选择是正则化项。正则化项是为了降低模型复杂度,提高泛化能力,避免过拟合而引入的项。当数据维度很高/样本不多的情况下,模型参数很多,模型容易变得很复杂,表面上看虽然极好地通过了所有样本点,但实际却出现了很多过拟合,此时则通过引入L1/L2正则化项来解决。

一般情况下,L1即为1范数,为绝对值之和;L2即为2范数,就是通常意义上的模。L1会趋向于产生少量的特征,而其他的特征都是0,即实现所谓的稀疏,而L2会选择更多的特征,这些特征都会接近于0。

对于solver的选择,作者的建议是:一般情况下推荐使用线性svm,其训练速度快且效果与lr接近;一般情况下推荐使用L2正则化项,L1精度相对低且训练速度也会慢一些,除非想得到一个稀疏的模型(个人注:当特征数量非常大,稀疏模型对于减少在线预测计算量比较有帮助)。

 

1.3  primal还是dual

primal和dual分别对应于原问题和对偶问题的求解,对结果是没有影响的,但是对偶问题可能比较慢。作者有如下建议:对于L2正则-SVM,可以先尝试用dual求解,如果非常慢,则换用primal求解。

网上另一个可参考的建议是:对于样本量不大,但是维度特别高的场景,如文本分类,更适合对偶问题求解;相反,当样本数非常多,而特征维度不高时,如果采用求解对偶问题,则由于Kernel Matrix过大,求解并不方便。反倒是求解原问题更加容易。

 

1.4  训练数据是否要归一化

对于这点,作者是这样建议的:在他们文档分类的应用中,归一化不但能大大减少训练时间,也能使得训练效果更好,因此我们选择对训练数据进行归一化。同时在实践中,归一化使得我们能直接对比各特征的公式权重,直观地看出哪些特征比较重要。

 

2.      liblinear及fm/xgboost实际效果对比记录

本轮改造中,主要实际尝试了liblinear各模式的效果,也同时对业界常用的fm/xgboost进行了对比测试,以下一并列出供参考。

注:由于liblinear尚为单机训练,受内存限制,不能加载全量数据训练,因此后续针对训练数据量多少(1/120->1/4->1/2)也有专门实验;


   

2.1  liblinear效果总结

liblinear中'L14' 解决回归问题(for regression) 的s11效果相对最好0.8361,其次是解决分类问题(formulti-class classification)的s1/s2/s5(support vector classification) 的0.8356;
尝试过的各种模式的AUC完整排序如下:s11>s1/s2/s5/>s0/s7>s6

2.1.1       -e epsilon

set tolerance of termination criterion,此参数用于设置迭代终止条件的容忍度tolerance;

从L6->L10(提升0.16%)可以看出,s2模式下调小e会使AUC小幅上升;但对于不同 模式,调小e对AUC的影响幅度似乎不同,如s0模式下基本没有变化,L1->L3(仅提升0.04%);

因为e的影响不大,因此后续模式的尝试中直接采用各模式的默认e值;

2.1.2         -c cost

set the parameter C (default 1),此参数即为惩罚系数C,仅有solver-0/2支持-C参数自动判断最佳C;

从L6/L7/L8/L9可以看出,L8是系统自动计算出的c,确实AUC最高;

因为c对AUC影响很小(非单调、仅波动0.06%),因此后续模式的尝试也直接采用各模式的默认c值;

2.1.3         训练数据量的影响

从L5->L6(提升0.3%)可以看出,数据从1/120(约200万样本)提高到1/4(约6000万样本),AUC有小幅提升;而当数据量已足够大时,再增大数据量如L1->L2,AUC反而有下降,可以认为此时对AUC已无影响;

 

2.2  fm效果总结

fm模型主要尝试了libfm和libffm两种,其中libfm是fm算法作者的实现,libffm则是liblinear同作者国立台湾大学林智仁(Chih-JenLin)老师团队的实现;

测试中,fm算法作者的实现libfm效果确实最好,AUC达 0.8243;

而台湾大学的实现libffm对训练数据有附加field需求(此处实验了3种field,分别为无field/4种特征大类别/50种特征小类别),合理增加field类别的数量确实能明显提高AUC,但最高AUC仍只达到0.8109,不如libfm;

将训练数据从1/120(约200万样本)增加到1/4(约6000万样本),对libfm(FM1->FM2提升0.8%)和libffm(FFM9->FFM10提升0.3%)的AUC确实均有提升,说明在数据量还不足够时,提高训练数据量还是有帮助的;

 

2.3  xgboost效果总结

xgboost的全称是eXtreme Gradient Boosting,它是GradientBoosting Machine的一个c++实现,作者为华盛顿大学研究机器学习的大牛陈天奇。传统GBDT以CART作为基分类器,xgboost还支持线性分类器,它能够自动利用CPU的多线程进行并行,同时在算法上加以改进提高了精度,在Kaggle等数据竞赛平台社区知名度很高。

在测试中,xgboost确实表现出了实力,仅用默认参数配置和1/120小数据量(约200万样本),就达到了0.8406的超出所有liblinear效果的AUC;受时间限制,当前并未直接采用xgboost,后续有同事进一步跟进。

 

3.      参考文献

1 liblinear官方主页http://www.csie.ntu.edu.tw/~cjlin/liblinear/

2 统计学习方法(中文版)李航

3 [转载]LIBSVM与LIBLINEAR(一)https://segmentfault.com/a/1190000004867622

4 关于liblinearhttp://zhangliliang.com/2014/09/06/about-liblinear/

5 机器学习中的范数规则化之(一)L0、L1与L2范数http://blog.csdn.net/zouxy09/article/details/24971995

6 LR与SVM的异同http://www.cnblogs.com/zhizhan/p/5038747.html

7 Libsvm和Liblinear的使用经验谈http://m.blog.csdn.net/article/details?id=7607112

8 SVM和logistic回归分别在什么情况下使用?https://www.zhihu.com/question/21704547

9 Linear SVM 和 LR 有什么异同? https://www.zhihu.com/question/26768865

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页