摘要:2020华为软件挑战赛如期举行,本次挑战赛分为热身赛、初赛、复赛、总决赛4个部分,其中热身赛结合当前机器学习中分类问题以及鲲鹏服务器性能相关来出题。为了解决该问题,达到算法准确率和程序时间的平衡。本文基于高斯贝叶斯的分类算法思想,用C++程序来编写该算法,并在完成之后进行算法以及程序等层面优化策略。充分利用特征选择以及内存映射等特点。在赛题数据集上取得1.12分的成绩,为热身赛第180名左右(总约800名报名选手)。
目录
基于高斯贝叶斯分类的C++优化器
1 问题介绍
2 算法以及程序优化流程
3 流程详解
3.1 特征选择
3.2 使用什么分类算法
3.3 为什么使用C++?
3.4 如何优化C++程序?
3.4.1 算法层面
3.4.2 代码层面
4 结束语
机器学习是金融风控中使用到的核心技术之一。金融风控中,会结合各类特征,进行风险预估(常见的特征如:学历、性别、收入、负债情况、商品购买记录、历史逾期行为、人际社交等)。数据分析工程师会针对上述特征进行特征工程处理,再选用合适的机器学习模型进行数据建模工作。
在“大数据”的时代背景下,保证机器学习算法效果的同时,充分挖掘IT基础设施算力,提升算法计算性能,一方面有利于保护企业现有IT投资,另一方面能让数据分析师以更短的时间完成建模,从而可以选择出来更优化的业务模型。
在本次比赛中,我们准备了已经做好了特征工程处理的数据和对应的样例代码,您需要优化模型提升准确率和性能。
由问题定义可知这是一个分类问题,华为官方要求在准确率和时间两个指标上来综合计分。为了能够达到两者的均衡。本文问题解决方案如下
问题解决流程
由于本篇为赛题博客,所涉及的知识点大多广而不深,所以在这里依据问题解决流程简单罗列下子问题以及本文解决的方法。
因为本次热身赛的训练集在8w左右,测试集在2w左右。在分类算法达到一定准确率上如何让程序运行更快是一个亟待解决的问题。而特征选择的必要性体现出来,它可以缩短程序I/O读取数据集训练以及预测时间从而获得更好成绩。特征选择主要有3个派别的方法包括基于过滤的方法,其中有方差检验、相关性检验,这一派别方法通过去掉不符合阙值的特征以及优先选择与目标变量相关性高的特征来筛选特征集合。而基于嵌入的方法派别利用正则化和树模型,通过构建目标函数不断去除那些不太重要的特征。最后基于包裹的方法派别使用现成的分类算法为学习器,每次递归消除那些使得学习器性能提升最小的特征。
在本文中,由于并不知晓训练集多特征对于分类标签的共同影响,而且为了节省时间考虑。本文选择了基于皮尔逊系数的相关性检验方法来过滤特征。两个变量之间的皮尔逊相关系数定义为两个变量之间的协方差和标准差的商,其中协方差反应的是X和Y之间的总体误差,而标准差反应是X和Y各自作为一组数据的离散程度。公式如下
即
在该公式中,P为皮尔森相关系数,X为特征,Y为标签,分子为X和Y的方差。分母是X,Y的标准差乘积。该公式刻画X和Y之间的相关性,该公式能够反应每个特征和对应标签之间的关系,r值绝对值越大,表示X和Y相关性越高。但是这种过滤特征的方法有缺陷,皮尔逊系数是假设两个变量之间是线性相关而进行分析的,r值越大,相关性越高。而在本赛题中,并不知X和Y之间是否有线性关系,仅仅依赖现有条件去筛选特征,该缺陷可以靠画出X和Y的数据变化图来验证。本文不再赘述,暂且使用这种方法。本文使用皮尔逊相关系数方法从训练集中1000个特征中,取200列特征。之所以选择200列,是因为在后续实验中发现200列是保证贝叶斯预测准确率大于70的条件之一。
在使用sklearn机器学习库来调研已有的分类算法中,本文基于各种分类算法在赛题发放的样例数据集表现,选择高斯贝叶斯分类器。该分类器在样例数据集中取全部特征可以达到约84%的准确率,用时仅为4.88s。关于高斯贝叶斯分类器的内容,本文不再赘述。只给出其分类思想以及前提假设。
假设:
特征分布符合正态分布,且各个特征之间独立。
分类思想公式:
本公式为基本的贝叶斯公式,其中x为特征集合,yi表示标签。而样例数据集只有1和0两个类别。所以在该公式计算过程中,不需要计算分母。只需要计算分子即可。分子由两部分组成,包括P(x|yi)和P(yi),前者可以直接转化为P(x1|yi),P(x2|yi)...P(xn|yi)来计算(因为贝叶斯强烈的假设条件),而P(xi|yi)使用正态分布的概率密度计算即可,后者为训练集中每一种标签对应的先验概率。
在挑选什么语言来实现贝叶斯算法问题上,目前大赛比较好的选手都是选择C++语言。其相对于其他编程语言的优点在于:
缺陷在于:
在算法层面,本文所做的是特征选择
1.数据截取
在实验过程中,发现仅需要200列特征,1/10训练集即可在测试集上达到70准确率。
2. I/O的优化
在I/O层面,本文使用mmap内存映射机制。该机制过程如下
mmap通过将硬盘中的文件一部分内容映射到用户空间上,那么用户获取该空间指针就可以直接向内核缓存区读写这部分内容,相对于Fread读取方法,mmap没有硬盘拷贝到用户空间的过程,自然更快。本文首先获取需要读取训练集和测试集文件大小,再依据文件大小映射出整个文件到用户空间上,取文件映射头指针一个一个读取200列数据。
3 .并行优化
在并行层面,分别读取两个文件的操作很明显是可以并行的。数据隔离满足线程安全,本文采用两个线程分别读取数据到vector中。
4.代码优化
代码优化层面主要是语言特性以及计算机底层方面知识,本文在网络资源的帮助下,就以下几点做出改进
本文基于高斯贝叶斯分类器,结合特征选择,以及优化程序等流程,在大赛取得一定成绩,但仍有较大进步空间。分为以下几个方面阐述:
本部分是笔者自己打比赛自己问自己的问题,可读可不读
问题的细致定义:
(C++性能优化代码+选择合适的算法(准确率和时间)+特征工程+服务器特性)4个方面的知识点 问题很简单,简单二分类问题,数据集为几w行1000列。但是要准确率以及够快。