假设我想通过交叉验证和使用pipeline
类比较特定(监督)数据集的不同降维方法,该数据集包含n> 2个特征.
例如,如果我想尝试使用PCA和LDA,我可以做类似的事情:
from sklearn.cross_validation import cross_val_score, KFold
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import GaussianNB
from sklearn.preprocessing import StandardScaler
from sklearn.lda import LDA
from sklearn.decomposition import PCA
clf_all = Pipeline(steps=[
('scaler', StandardScaler()),
('classification', GaussianNB())
])
clf_pca = Pipeline(steps=[
('scaler', StandardScaler()),
('reduce_dim', PCA(n_components=2)),
('classification', GaussianNB())
])
clf_lda = Pipeline(steps=[
('scaler', StandardScaler()),
('reduce_dim', LDA(n_components=2)),
('classification', GaussianNB())
])
# Constructing the k-fold cross validation iterator (k=10)
cv = KFold(n=X_train.shape[0], # total number of samples
n_folds=10, # number of folds the dataset is divided into
shuffle=True,
random_state=123)
scores = [
cross_val_score(clf, X_train, y_train, cv=cv, scoring='accuracy')
for clf in [clf_all, clf_pca, clf_lda]
]
Run Code Online (Sandbox Code Playgroud)
但是现在,让我们说 - 基于一些"领域知识" - 我假设特征3和4可能是"好的特征"(数组的第三和第四列X_train
),我想将它们与其他方法.
我如何在pipeline
?中包含这样的手动功能选择?
例如
def select_3_and_4(X_train):
return X_train[:,2:4]
clf_all = Pipeline(steps=[
('scaler', StandardScaler()),
('feature_select', select_3_and_4),
('classification', GaussianNB())
])
Run Code Online (Sandbox Code Playgroud)
显然不会奏效.
所以我假设我必须创建一个特征选择类,它具有一个返回数组的两列的transform
虚方法和fit
方法numpy
?或者,还有更好的方法?
小智 26
我只想发布我的解决方案的完整性,也许它对一个或另一个有用:
class ColumnExtractor(object):
def transform(self, X):
cols = X[:,2:4] # column 3 and 4 are "extracted"
return cols
def fit(self, X, y=None):
return self
Run Code Online (Sandbox Code Playgroud)
然后,它可以用在Pipeline
这样的:
clf = Pipeline(steps=[
('scaler', StandardScaler()),
('reduce_dim', ColumnExtractor()),
('classification', GaussianNB())
])
Run Code Online (Sandbox Code Playgroud)
对于更通用的解决方案,如果要选择并堆叠多个列,基本上可以使用以下类,如下所示:
import numpy as np
class ColumnExtractor(object):
def __init__(self, cols):
self.cols = cols
def transform(self, X):
col_list = []
for c in self.cols:
col_list.append(X[:, c:c+1])
return np.concatenate(col_list, axis=1)
def fit(self, X, y=None):
return self
clf = Pipeline(steps=[
('scaler', StandardScaler()),
('dim_red', ColumnExtractor(cols=(1,3))), # selects the second and 4th column
('classification', GaussianNB())
])
Run Code Online (Sandbox Code Playgroud)
如果您想使用该Pipeline
对象,那么是的,干净的方法是编写一个转换器对象。这样做的肮脏方法是
select_3_and_4.transform = select_3_and_4.__call__
select_3_and_4.fit = lambda x: select_3_and_4
Run Code Online (Sandbox Code Playgroud)
并select_3_and_4
按照您在管道中的方式使用它。显然你也可以写一个类。
否则,X_train[:, 2:4]
如果您知道其他功能不相关,您也可以只提供给您的管道。
数据驱动的特征选择工具可能偏离主题,但总是有用的:在您的情况下检查例如sklearn.feature_selection.SelectKBest
使用sklearn.feature_selection.f_classif
或sklearn.feature_selection.f_regression
与例如。k=2
归档时间: |
|
查看次数: |
6721 次 |
最近记录: |