• 机器学习:特征选择


    1.特征选择

             特征选择是降维的一种方法,即选择对预测结果相关度高的特征或者消除相似度高的特征,以提高估计函数的准确率或者提高多维度数据集上的性能。

    2.删除低方差特征

            1)思路:设置一个阀值,对每个特征求方差,如果所求方差低于这个阀值,则删除此特征。默认情况下会删除0方差。

            2)核心函数

                  sklearn.feature_selection.VarianceThreshold

           3)主要参数:

                  threshold :设置的阀值

                 补充说明:

                 官网给出的是一个布尔值的数据集,阀值的表示方式为下面的公式:

                 

                 示例写法:sel = VarianceThreshold(threshold=(0.8 * (1 - 0.8)))

                 经过测试,非布尔值的数据集也适用,并且直接写成:threshold=0.16 也是可以的。

                 对于二维矩阵,求的是每列的方差,然后和阀值比较。

            4)示例

                 为了更好的说明用删除低方差的方式进行特征选择后,新的数据集不会影响预测结果或者不会造成太大的影响,这里选择一个官方提供的数据集进行对比。这个数据集是关于花朵类型判断的:包含150个样本数据,每个样本数据包含4个特征,这些样本数据属于3类,每类50个样本。

           使用决策树进行分类预测。

            详细代码如下:

    from sklearn.datasets import load_iris
    from sklearn import tree
    from sklearn.feature_selection import VarianceThreshold
    import numpy as np
    
    ##加载数据
    iris = load_iris()
    ##设置筛选阀值
    sel = VarianceThreshold(threshold=(.7 * (1 - .7)))
    
    ##设置训练集和标签集
    X, y = iris.data, iris.target
    print("原始数据:")
    print(X.shape) #(150, 4)
    
    #筛选数据
    X_new = sel.fit_transform(X)
    print("新数据集:")
    print(X_new.shape) #(150, 3)
    
    ##设置分类函数:决策树
    clf = tree.DecisionTreeClassifier()
    ##训练数据
    clf.fit(X, y)
    ##预测数据
    y_pred = clf.predict(X)
    
    ##使用选择特征后的数据进行训练
    clf.fit(X_new, y)
    ##在新数据集上进行预测
    y_pred1 = clf.predict(X_new)
    
    
    ##原始数据的预测结果和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y[i]:
            cnt += 1
    print("原始数据的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##新数据集和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred1[i]== y[i]:
            cnt += 1
    print("新数据集的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##原始数据的预测结果和新数据的预测结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y_pred1[i]:
            cnt += 1
    print("原始据集的预测结果和新数据集预测结果相同的个数:")
    print(cnt)
    View Code

            输出结果:

    原始数据:
    (150, 4)
    新数据集:
    (150, 3)
    原始数据的预测结果和真实结果相同的个数:
    150
    新数据集的预测结果和真实结果相同的个数:
    150
    原始据集的预测结果和新数据集预测结果相同的个数:
    150

       从结果可以看出,数据从150×4的矩阵变成了150×3的矩阵,但是完全没有对预测结果造成任何影响。

    3.单变量特征选择

            (下面的翻译可能不是很准确)

            1)思路:对每个特征做基于统计的检验,从而选择出最佳特征。

            2)可用的函数

                       SelectPercentile:根据最高分数的百分位数选择特征。
                       SelectKBest:根据k最高分选择特征。
                       SelectFpr:基于假阳性率测试选择特征。
                       SelectFdr:根据估计的虚假发现率选择特征。
                       SelectFwe:根据家庭错误率选择功能(这个翻译感觉很怪:based on family-wise error rate)
                       GenericUnivariateSelect:具有可配置模式的单变量特征选择器。

             3)可用的统计方法(上面函数的参数):                 

                       f_classif:用于分类任务的标签/特征之间方差分析的F值。
                       mutual_info_classif:离散目标的相互信息。
                      chi2:用于分类任务的非负性特征的卡方统计。
                      f_regression:用于回归任务的标签/特征之间的F值。
                      mutual_info_regression:连续目标的相互信息。

             4)示例

                   依然使用上面的关于花朵的数据集和决策树分类方法。

                   详细代码如下:

    from sklearn.datasets import load_iris
    from sklearn.feature_selection import SelectKBest
    from sklearn.feature_selection import chi2
    from sklearn import tree
    import numpy as np
    
    ##加载数据
    iris = load_iris()
    ##设置训练集和标签集
    X, y = iris.data, iris.target
    print("原始数据:")
    print(X.shape) #(150, 4)
    
    ##选择关键特征
    X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
    print("新数据集:")
    print(X_new.shape) #(150, 2)
    
    ##设置分类函数:决策树
    clf = tree.DecisionTreeClassifier()
    ##训练数据
    clf.fit(X, y)
    ##预测数据
    y_pred = clf.predict(X)
    
    ##使用选择特征后的数据进行训练
    clf.fit(X_new, y)
    ##在新数据集上进行预测
    y_pred1 = clf.predict(X_new)
    
    
    ##原始数据的预测结果和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y[i]:
            cnt += 1
    print("原始数据的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##新数据集和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred1[i]== y[i]:
            cnt += 1
    print("新数据集的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##原始数据的预测结果和新数据的预测结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y_pred1[i]:
            cnt += 1
    print("原始据集的预测结果和新数据集预测结果相同的个数:")
    print(cnt)
    View Code

                   输出结果:

    原始数据:
    (150, 4)
    新数据集:
    (150, 2)
    原始数据的预测结果和真实结果相同的个数:
    150
    新数据集的预测结果和真实结果相同的个数:
    149
    原始据集的预测结果和新数据集预测结果相同的个数:
    149

                   从结果可以看出,原始的数据集从150×4变成了150×2,但是预测的结果只有一个误差。

    4.使用SelectFromModel进行特征选择

             1)思路:SelectFromModel是一种元变压器,可用于任何在拟合后有coef_或feature_importances_属性的拟合函数。如果相应的coef_或feature_importances_值低于提供的threshold参数(阀值),则认为这些特征是是不重要的并且删除。除了数值上指定阈值外,还有内置的启发式算法,用于使用字符串参数来查找阈值。可用的启发式算法是“平均值”,“中位数”和浮点倍数,如“0.1 *mean”。

            2)由上面SelectFromModel的思路可知,首先需要进行一次拟合,然后才通过SelectFromModel选择特征。根据第一次拟合函数的不同,分为两类:

                a)基于L1的特征选择

                     详细代码:

    from sklearn.datasets import load_iris
    from sklearn.svm import LinearSVC
    from sklearn.feature_selection import SelectFromModel
    from sklearn import tree
    import numpy as np
    
    ##加载数据
    iris = load_iris()
    ##设置训练集和标签集
    X, y = iris.data, iris.target
    print("原始数据:")
    print(X.shape) #(150, 4)
    
    ##选择关键特征
    lsvc = LinearSVC(C=0.01, penalty="l1", dual=False)
    lsvc = lsvc.fit(X, y)
    model = SelectFromModel(lsvc, prefit=True)
    X_new = model.transform(X)
    print("新数据集:")
    print(X_new.shape) #(150, 3)
    
    ##设置分类函数:决策树
    clf = tree.DecisionTreeClassifier()
    ##训练数据
    clf.fit(X, y)
    ##预测数据
    y_pred = clf.predict(X)
    
    ##使用选择特征后的数据进行训练
    clf.fit(X_new, y)
    ##在新数据集上进行预测
    y_pred1 = clf.predict(X_new)
    
    
    ##原始数据的预测结果和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y[i]:
            cnt += 1
    print("原始数据的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##新数据集和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred1[i]== y[i]:
            cnt += 1
    print("新数据集的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##原始数据的预测结果和新数据的预测结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y_pred1[i]:
            cnt += 1
    print("原始据集的预测结果和新数据集预测结果相同的个数:")
    print(cnt)
    View Code

                    输出结果:

    原始数据:
    (150, 4)
    新数据集:
    (150, 3)
    原始数据的预测结果和真实结果相同的个数:
    150
    新数据集的预测结果和真实结果相同的个数:
    150
    原始据集的预测结果和新数据集预测结果相同的个数:
    150

                    从结果可以看出,数据从150×4变成了150×3,但是预测结果没有受影响。

                b)基于树的特征选择

                   详细代码:

    from sklearn.datasets import load_iris
    from sklearn.ensemble import ExtraTreesClassifier
    from sklearn.feature_selection import SelectFromModel
    from sklearn import tree
    import numpy as np
    
    ##加载数据
    iris = load_iris()
    ##设置训练集和标签集
    X, y = iris.data, iris.target
    print("原始数据:")
    print(X.shape) #(150, 4)
    
    ##选择关键特征
    etc = ExtraTreesClassifier()
    etc = etc.fit(X,y)
    model = SelectFromModel(etc, prefit=True)
    X_new = model.transform(X)
    print("新数据集:")
    print(X_new.shape) #(150, 2)
    
    ##设置分类函数:决策树
    clf = tree.DecisionTreeClassifier()
    ##训练数据
    clf.fit(X, y)
    ##预测数据
    y_pred = clf.predict(X)
    
    ##使用选择特征后的数据进行训练
    clf.fit(X_new, y)
    ##在新数据集上进行预测
    y_pred1 = clf.predict(X_new)
    
    
    ##原始数据的预测结果和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y[i]:
            cnt += 1
    print("原始数据的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##新数据集和真实结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred1[i]== y[i]:
            cnt += 1
    print("新数据集的预测结果和真实结果相同的个数:")
    print(cnt)
    
    ##原始数据的预测结果和新数据的预测结果的对比
    cnt = 0
    for i in range(len(y)):
        if y_pred[i] == y_pred1[i]:
            cnt += 1
    print("原始据集的预测结果和新数据集预测结果相同的个数:")
    print(cnt)
    View Code

                 输出结果:

    原始数据:
    (150, 4)
    新数据集:
    (150, 2)
    原始数据的预测结果和真实结果相同的个数:
    150
    新数据集的预测结果和真实结果相同的个数:
    149
    原始据集的预测结果和新数据集预测结果相同的个数:
    149

                 从结果看出,数据集从150×4变成了150×2,出现了一个误差。

           3)上述代码的选择特征,然后预测,也可简写成如下形式:

    clf = Pipeline([
      ('feature_selection', SelectFromModel(LinearSVC(C=0.01, penalty="l1", dual=False))),
      ('classification', tree.DecisionTreeClassifier())
    ])
    clf.fit(X, y)

                      

  • 相关阅读:
    rabbitmq 公平分发和消息接收确认(转载)
    rabbitmq 配置多个消费者(转载)
    Spring整合rabbitmq(转载)
    rabbitmq 一些属性
    rabbitmq 持久化 事务 发送确认模式
    TCP中的长连接和短连接(转载)
    rabbitmq 概念
    ZooKeeper介绍(转载)
    npm install 安装依赖报错解决
    ubuntu下安装node.js教程
  • 原文地址:https://www.cnblogs.com/lc1217/p/7126150.html
Copyright © 2020-2023  润新知