删除 scikit 学习中的特定功能
Remove a specific feature in scikit learn
有没有办法从 scikit.learn
数据集中删除特定特征?例如,我知道可以使用 sklearn.feature_selection
删除功能,但这些都是删除功能的自动化程序 他们 认为没有用。有没有什么方法可以在不进入数据的脏内部的情况下实现自定义特征删除算法?例如,假设我有一个对特征进行评分的函数,这里提供了一个玩具示例:
def score(feature_index):
return 0 if feature_index == 1 else 1
现在假设我想删除鸢尾花数据集中得分低于 0.5
的所有特征。我想做这样的事情:
from sklearn import datasets
iris = datasets.load_iris()
#this is the function I want:
iris.filter_features(score, threshold=0.5)
之后我希望 iris 数据集少一个特征。现在,我可以这样做:
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)
但这看起来……很脏。
没有像 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]
注意,第一个位置的 :
符号表示 "all the rows"。
要检查,您可以打印每个数组的前 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 操作的更多信息,请查看教程,例如:
虽然 sklearn 中没有内置 class 来执行此操作,但您可以使用标准的拟合和转换方法轻松创建一个:
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 框架之外进行这样的手动特征选择,但我遇到过将手动特征选择作为流水线的一部分会有所帮助的情况。
例如,如果对象将数组传递给 classifier 和其他对象(如显示函数),您可能只想将某些字段传递给 classifier。通过将 classifier 更改为包含上述转换和原始 classifier.
的 Pipeline,最容易做到这一点。
希望对您有所帮助!
有没有办法从 scikit.learn
数据集中删除特定特征?例如,我知道可以使用 sklearn.feature_selection
删除功能,但这些都是删除功能的自动化程序 他们 认为没有用。有没有什么方法可以在不进入数据的脏内部的情况下实现自定义特征删除算法?例如,假设我有一个对特征进行评分的函数,这里提供了一个玩具示例:
def score(feature_index):
return 0 if feature_index == 1 else 1
现在假设我想删除鸢尾花数据集中得分低于 0.5
的所有特征。我想做这样的事情:
from sklearn import datasets
iris = datasets.load_iris()
#this is the function I want:
iris.filter_features(score, threshold=0.5)
之后我希望 iris 数据集少一个特征。现在,我可以这样做:
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)
但这看起来……很脏。
没有像 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]
注意,第一个位置的 :
符号表示 "all the rows"。
要检查,您可以打印每个数组的前 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 操作的更多信息,请查看教程,例如:
虽然 sklearn 中没有内置 class 来执行此操作,但您可以使用标准的拟合和转换方法轻松创建一个:
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 框架之外进行这样的手动特征选择,但我遇到过将手动特征选择作为流水线的一部分会有所帮助的情况。
例如,如果对象将数组传递给 classifier 和其他对象(如显示函数),您可能只想将某些字段传递给 classifier。通过将 classifier 更改为包含上述转换和原始 classifier.
的 Pipeline,最容易做到这一点。希望对您有所帮助!