删除低方差scikit-learn的特征

jax*_*jax 4 python-2.7 scikits scikit-learn

scikit-learn提供了各种方法来删除描述符,给定的教程提供了初始方法

http://scikit-learn.org/stable/modules/feature_selection.html#
Run Code Online (Sandbox Code Playgroud)

但是给定的教程没有提供任何方法或方法来告诉您保留已删除或保留的功能列表的方法.在下面给出的教程页面上提供了代码:

    from sklearn.feature_selection import VarianceThreshold
    X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
    sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
    sel.fit_transform(X)
array([[0, 1],
       [1, 0],
       [0, 0],
       [1, 1],
       [1, 0],
       [1, 1]])
Run Code Online (Sandbox Code Playgroud)

这个例子只包含两个描述符"shape(6,2)",但在我的例子中我有一个巨大的数据形状(51,9000).在获得合适的模型之后,我希望保留可用功能的跟踪,这样当我将针对未知数据集运行我的模型时,我将仅计算测试集的所选描述符.

例如,当我使用WEKA 6.0工具执行机器建模时,此工具在特征选择方面提供了非凡的灵活性,并且在化学数据集上执行任务后提供了最佳特征列表9000,并且我可以使用列名称保存减少的数据.

谢谢

Ima*_*ngo 9

然后,如果我没错,你可以做的是:

VarianceThreshold的情况下,您可以调用方法fit而不是fit_transform.这将适合数据,结果差异将存储在vt.variances_(假设vt是您的对象).

有了一个threhold,您可以像以下一样提取转换的功能fit_transform:

X[:, vt.variances_ > threshold]
Run Code Online (Sandbox Code Playgroud)

或者将索引作为:

idx = np.where(vt.variances_ > threshold)[0]
Run Code Online (Sandbox Code Playgroud)

或者作为面具

mask = vt.variances_ > threshold
Run Code Online (Sandbox Code Playgroud)

PS:默认阈值为0

编辑:

更直接的做法是使用get_support类的方法VarianceThreshold.从文档:

get_support([indices])  Get a mask, or integer index, of the features selected
Run Code Online (Sandbox Code Playgroud)

你应该在fit或之后调用这个方法fit_transform.

  • 拟合后,可以使用以下命令获得过滤后的数据帧:`df.loc [:,sel.get_support()]`其中`df`是pandas数据帧,`sel`是VarianceThreshold. (2认同)

Jas*_*ich 7

import numpy as np
import pandas as pd
from sklearn.feature_selection import VarianceThreshold

# Just make a convenience function; this one wraps the VarianceThreshold
# transformer but you can pass it a pandas dataframe and get one in return

def get_low_variance_columns(dframe=None, columns=None,
                             skip_columns=None, thresh=0.0,
                             autoremove=False):
    """
    Wrapper for sklearn VarianceThreshold for use on pandas dataframes.
    """
    print("Finding low-variance features.")
    try:
        # get list of all the original df columns
        all_columns = dframe.columns

        # remove `skip_columns`
        remaining_columns = all_columns.drop(skip_columns)

        # get length of new index
        max_index = len(remaining_columns) - 1

        # get indices for `skip_columns`
        skipped_idx = [all_columns.get_loc(column)
                       for column
                       in skip_columns]

        # adjust insert location by the number of columns removed
        # (for non-zero insertion locations) to keep relative
        # locations intact
        for idx, item in enumerate(skipped_idx):
            if item > max_index:
                diff = item - max_index
                skipped_idx[idx] -= diff
            if item == max_index:
                diff = item - len(skip_columns)
                skipped_idx[idx] -= diff
            if idx == 0:
                skipped_idx[idx] = item

        # get values of `skip_columns`
        skipped_values = dframe.iloc[:, skipped_idx].values

        # get dataframe values
        X = dframe.loc[:, remaining_columns].values

        # instantiate VarianceThreshold object
        vt = VarianceThreshold(threshold=thresh)

        # fit vt to data
        vt.fit(X)

        # get the indices of the features that are being kept
        feature_indices = vt.get_support(indices=True)

        # remove low-variance columns from index
        feature_names = [remaining_columns[idx]
                         for idx, _
                         in enumerate(remaining_columns)
                         if idx
                         in feature_indices]

        # get the columns to be removed
        removed_features = list(np.setdiff1d(remaining_columns,
                                             feature_names))
        print("Found {0} low-variance columns."
              .format(len(removed_features)))

        # remove the columns
        if autoremove:
            print("Removing low-variance features.")
            # remove the low-variance columns
            X_removed = vt.transform(X)

            print("Reassembling the dataframe (with low-variance "
                  "features removed).")
            # re-assemble the dataframe
            dframe = pd.DataFrame(data=X_removed,
                                  columns=feature_names)

            # add back the `skip_columns`
            for idx, index in enumerate(skipped_idx):
                dframe.insert(loc=index,
                              column=skip_columns[idx],
                              value=skipped_values[:, idx])
            print("Succesfully removed low-variance columns.")

        # do not remove columns
        else:
            print("No changes have been made to the dataframe.")

    except Exception as e:
        print(e)
        print("Could not remove low-variance features. Something "
              "went wrong.")
        pass

    return dframe, removed_features
Run Code Online (Sandbox Code Playgroud)


Meh*_*Far 6

这对我有用,如果您想确切地查看阈值后保留哪些列,您可以使用此方法:

from sklearn.feature_selection import VarianceThreshold
threshold_n=0.95
sel = VarianceThreshold(threshold=(threshold_n* (1 - threshold_n) ))
sel_var=sel.fit_transform(data)
data[data.columns[sel.get_support(indices=True)]] 
Run Code Online (Sandbox Code Playgroud)