美文网首页人工智能/模式识别/机器学习精华专题
从零构建机器学习模型(二)sklearn特征提取源码分析

从零构建机器学习模型(二)sklearn特征提取源码分析

作者: 雨洛晨曦 | 来源:发表于2018-05-20 19:24 被阅读0次

    <开场白>(*´゚∀゚`)ノ 不存在的


    1.1.6 实践操作特征选择

    上一篇可能抽象的东西比较多,我们现在从代码的角度分析一下整个特征选择的部分。

    Python的Sklearn库中有一个包feature_selection主要就是做特征提取的,我们从这个包具体地看一下这个问题。

    Sklearn中主要提供五种特征选取的方法,分别代表了不同的特征选择方式:

    a.移除低方差的特征(Removing features with low variance)(filter方式):

    v2-340b2ecdd7e8f8ecc3e0e06121b83ab5_hd.jpg v2-05b136b76a96edb298e7b277ddfbc915_hd.jpg

    这里VarianceThreshold类直接继承base包下的BaseEstimator,间接继承本包下的SelectorMixin

    BaseEstimator主要是一些参数方法(get,set)以及打印版本等功能块:

    v2-43b17d8392878453fb4163fc289c2d7b_hd.jpg

    例如上图这个静态私有的_get_param_names方法为公有函数提供参数检查。

    1. init先通过反射加载cls实例的deprecated信息,也就是检查函数是否版本过期并在不存在时为init赋值构造函数;
    2. signature为init构造体提供函数信息及函数绑定检查;
    3. parameters遍历init实例Init_signature的parameters字段值并取出除self(也就是实例自身,类函数第一参数)及变量key字段(因为signature返回tuple);
    4. 最后返回param的排序名称;

    而该方法内的signature结构如下:

    v2-653a1893d6d880283b47e61d8d8964c8_hd.jpg

    这部分和python inspect里的signature不太一样,先检查obj是否有callable方法,也就是是否有函数名直接调用的call方法,而后检查传入的obj是否是绑定好的实例方法,sig=signature(obj.func)则为obj内部每个方法提供递归的检查。后续的步骤应该是为实例添加参数绑定,将未绑定的参数的第一项作为self绑定实例,若存在则将都需的转化为tuple也就是*param的类型。总的来说这部分提供了参数的标准化。

    后面的部分也都类似,依次检查obj是否属于FunctionType函数,functools.partial偏函数,type类或元类等等。

    而SelectorMixin则有比较详细的说明文档doc

    v2-c2db05d2c1dc44fa0cf70e086be827a0_hd.jpg

    用来返回一个提取特征的mask。内部的基本原理是一个调用自身抽象函数_get_support_mask的get_support函数作为正变换transform和反变换inverse_transform的基础,而这个抽象函数会在继承类中依据不同的类方法重写。正变换transform和反变换inverse_transform的功能主要有检查sparse的性质并做参数检查,而后返回safe_mask。

    而后的VarianceThreshold类则是一个标准的fit流程:

    v2-3018a070032c320696bfb8ecf7f5bf87_hd.jpg

    分别是:

    1. 构建初始化的threshold;
    2. 检查数据类型并依据类型求出方差variance,这里主要是因为稀疏矩阵有自己的variance库,而dense则可以直接求(这里的check_array在init里导入validation下的check_array,可能是出于这个函数用的比较多吧);
    3. 错误检查;
    4. 重写抽象方法_get_support_mask;
    v2-428c5acd1eb15c8981f8f3f4cf4412bd_hd.jpg

    其中check_is_fitted主要就是检查一下实例和属性的正常:

    v2-e6278838c4b5dab8039284a8254baec0_hd.jpg

    最后用self.variance>self.threshold做返回。整体涉及算法的部分很少,主要还是在框架下作了很多的数据转换以及检验的部分。其实就是在体现以用户为中心的思路,保证对不同数据源的Robust性质。

    b.单变量特征选择(Univariate feature selection)(filter方法)

    Univariate feature selection的类和函数都写在了init下面,不过原始的定义还是在univariate_selection里面,我们可以简单看一下比较常用的卡方检验,documentation的实例如下:

    v2-f251de52531f8ec74d45d75f7bbeeb28_hd.jpg

    chi2就是卡方检验函数

    v2-9f69189376826883217817e16255e15f_hd.jpg
    v2-441f82fca7cc47f70ce4e0b786a1cb74_hd.jpg

    里面包括数据格式化,二值变换以及卡方值计算,对照卡方公式看就好。

    SelectKbest用传入的score函数初始化,并重写了继承_BaseFilter类下的_check_params和以及_BaseFilter继承SelectorMixin的_get_support_mask接口,而后添加工厂模式的topk特征选择,当然这里做了个小优化:

    v2-9430647950261a45a8597ab4a0e4157c_hd.jpg

    也就是说当k取0或all的时候不进行处理,算个小trick吧。

    继承自_BaseFilter类下的fit函数将score规范化成输出,而继承自SelectorMixin的transform则进行正变换成标准mask输出。最后的结果就如同示例所示。

    最后注意selectKbest实可以自定义score函数的,只要将输入的score函数替换为想要的函数表达式或者函数就可以。

    例如下面用lambda表达式计算pearson相关系数作为score的函数

    SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)

    再比如下面利用互信息计算score分数

    SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)

    因为SelectKBest的写法中score函数与SelectKBest框架是分离的,所以可以作为自由发挥的拓展。

    c.递归特征消除(Recursive feature elimination)(wrapper)

    递归消除特征法的原理其实就是使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。类似于boosting的思路,例如用线性回归作为基分类器,对特征进行回归并抹除小系数特征做类似降维的行为,再用新的特征集重复回归。这也就是为什么官方说“递归特征消除 ([RFE](https://link.zhihu.com/?target=http%3A//sklearn.lzjqsdd.com/modules/generated/sklearn.feature_selection.RFE.html%23sklearn.feature_selection.RFE))通过递归减少考察的特征集规模来选择特征”。不过可能计算复杂度比较大,基分类器选取也有问题,没有见到很多用的。等以后用到的时候再补充了。

    d.使用SelectFromModel选择特征(Feature selection using SelectFromModel)(Embedding)

    这个就是带regularize的特征选择了,不同于其他的是这里的threshold相当于全局threshold而不是单个特征的。具体代码等下一部分说完regularize再讨论好了,这一章内容到知乎上限了…………(╯‵□′)╯︵┻━┻

    两种基础模型

    d1.基于L1的特征选择(L1-based feature selection)

    d2.基于树的特征选择(Tree-based feature selection)

    以及其拓展结合L2惩罚项来优化可以参考这位老哥的知乎:

    特征工程到底是什么?

    e.特征选择融入pipeline(Feature selection as part of a pipeline)

    pipeline,没什么好说的,Linux和Python最常用的东西。


    今天就不讲具体的结构了,内容好像有点多知乎上传不了,等下次吧。

    相关文章

      网友评论

        本文标题:从零构建机器学习模型(二)sklearn特征提取源码分析

        本文链接:https://www.haomeiwen.com/subject/npmtjftx.html