删除scikit中的特定功能

时间:2015-02-03 10:30:36

标签: python scikit-learn

有没有办法从scikit.learn数据集中删除特定功能?例如,我知道可以使用sklearn.feature_selection删除功能,但这些都是自动删除功能 决定无用的功能。有没有办法实现自定义功能删除算法而不进入数据的脏内部?例如,假设我有一个评分功能的功能,这里提供了一个玩具示例:

def score(feature_index):
    return 0 if feature_index == 1 else 1

现在说我要删除iris数据集中得分低于0.5的所有功能。我想做这样的事情:

from sklearn import datasets
iris = datasets.load_iris()
#this is the function I want:
iris.filter_features(score, threshold=0.5)

之后我希望虹膜数据集的功能少一个。现在,我可以这样做:

from sklearn import datasets
iris = datasets.load_iris()
for feature_index in range(len(iris.feature_names)):
    if score(feature_index) < 0.5:
        iris.feature_names.pop(feature_index)
        iris.data = np.delete(iris.data, feature_index, 1)

但这看起来很脏。

2 个答案:

答案 0 :(得分:2)

没有像scikit-learn数据集这样的思考。 scikit-learn使用常见的数据结构只是numpy数组(或scipy稀疏矩阵):

>>> from sklearn.datasets import load_iris
>>> iris = load_iris
>>> type(iris.data)
<class 'numpy.ndarray'>

您可以使用常规的numpy数组索引来生成新版本的数据。例如,使用布尔掩码删除第二个特征:

>>> import numpy as np
>>> X = iris.data
>>> mask = np.array([True, False, True, True])
>>> X_masked = X[:, mask]

注意,第一个位置的:符号表示“所有行”。

要检查,您可以打印每个数组的前5行:

>>> print(X[:5])
[[ 5.1  3.5  1.4  0.2]
 [ 4.9  3.   1.4  0.2]
 [ 4.7  3.2  1.3  0.2]
 [ 4.6  3.1  1.5  0.2]
 [ 5.   3.6  1.4  0.2]]
>>> print(X_masked[:5])
[[ 5.1  1.4  0.2]
 [ 4.9  1.4  0.2]
 [ 4.7  1.3  0.2]
 [ 4.6  1.5  0.2]
 [ 5.   1.4  0.2]]

您还可以使用基于整数的花式索引来获得相同的结果:

>>> index = np.array([0, 2, 3])
>>> X_indexed = X[:, index]
>>> print(X_indexed[:5])
[[ 5.1  1.4  0.2]
 [ 4.9  1.4  0.2]
 [ 4.7  1.3  0.2]
 [ 4.6  1.5  0.2]
 [ 5.   1.4  0.2]]

要了解有关基本numpy操作的更多信息,请查看以下教程:

http://scipy-lectures.github.io/

答案 1 :(得分:0)

虽然sklearn中没有内置的类可以做到这一点,但是您可以使用标准的fit和transform方法轻松地创建一个类:

from sklearn.base import TransformerMixin

class ManualFeatureSelector(TransformerMixin):
    """
    Transformer for manual selection of features using sklearn style 
    transform 
    method.  
    """

    def __init__(self, features):
        self.features = features
        pass

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        return X[:,self.features]

通常最好在sklearn框架之外进行这样的手动特征选择,但是我遇到了将手动特征选择作为管道一部分的情况会有所帮助的情况。

例如,如果对象将数组既传递给分类器又传递给其他对象(如显示功能),则可能只希望将某些字段传递给分类器。通过将分类器更改为结合了上述变换和原始分类器的管道,可以最轻松地做到这一点。

希望有帮助!