bla*_*ite 3 python scikit-learn
我正在尝试创建一个sklearn.compose.ColumnTransformer用于转换分类和连续输入数据的管道:
import pandas as pd
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.preprocessing import OneHotEncoder, FunctionTransformer
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer, make_column_transformer
from sklearn.impute import SimpleImputer
df = pd.DataFrame(
{
'a': [1, 'a', 1, np.nan, 'b'],
'b': [1, 2, 3, 4, 5],
'c': list('abcde'),
'd': list('aaabb'),
'e': [0, 1, 1, 0, 1],
}
)
for col in df.select_dtypes('object'):
df[col] = df[col].astype(str)
categorical_columns = list('acd')
continuous_columns = list('be')
categorical_transformer = OneHotEncoder(sparse=False, handle_unknown='ignore')
continuous_transformer = 'passthrough'
column_transformer = ColumnTransformer(
[
('categorical', categorical_transformer, categorical_columns),
('continuous', continuous_transformer, continuous_columns),
]
,
sparse_threshold=0.,
n_jobs=-1
)
X = column_transformer.fit_transform(df)
Run Code Online (Sandbox Code Playgroud)
我想访问此转换管道创建的功能名称,因此我尝试这样做:
column_transformer.get_feature_names()
Run Code Online (Sandbox Code Playgroud)
引起了:
NotImplementedError: get_feature_names is not yet supported when using a 'passthrough' transformer.
Run Code Online (Sandbox Code Playgroud)
因为我不是做技术的列东西b和e,我在技术上可能只是它们附加到X后一个热码的所有其他功能,但有一些方法我可以使用scikit的一个基类(如TransformerMixin,BaseEstimator或FunctionTransformer)加到此管道,以便我可以以非常友好的管道方式获取连续的要素名称?
可能是这样的:
class PassthroughTransformer(FunctionTransformer, BaseEstimator):
def fit(self):
return self
def transform(self, X)
self.X = X
return X
def get_feature_names(self):
return self.X.values.tolist()
continuous_transformer = PassthroughTransformer()
column_transformer = ColumnTransformer(
[
('categorical', categorical_transformer, categorical_columns),
('continuous', continuous_transformer, continuous_columns),
]
,
sparse_threshold=0.,
n_jobs=-1
)
X = column_transformer.fit_transform(df)
Run Code Online (Sandbox Code Playgroud)
但这会引发以下异常:
TypeError: Cannot clone object '<__main__.PassthroughTransformer object at 0x1132ddf60>' (type <class '__main__.PassthroughTransformer'>): it does not seem to be a scikit-learn estimator as it does not implement a 'get_params' methods.
Run Code Online (Sandbox Code Playgroud)
这里有多个问题:
无法克隆对象错误是由于并行处理造成的:
默认情况下,当其在Pipeline和类似版本(FeatureUnion,ColumnTransformer等)或交叉验证(,等等)中工作时,将scikit-learn克隆(使用pickle)提供的变换器和估计器。cross_val_scoreGridSearchCV
现在,您已n_jobs=-1在中指定ColumnTransformer,这在代码中引入了多处理。Python的内置酸洗不适用于多处理。因此,错误。
选项:
设置n_jobs = 1为不使用多处理。仍然需要根据第2点和第3点更正代码。
如果要使用多处理,那么最简单的解决方案是在单独的文件(模块)中定义自定义类,然后将其导入到主文件中。像这样:
在同一个名为custom_transformers.py的文件夹中新建一个包含以下内容的文件:
from sklearn.base import TransformerMixin, BaseEstimator
# Changed the base classes here, see Point 3
class PassthroughTransformer(BaseEstimator, TransformerMixin):
# I corrected the `fit()` method here, it should take X, y as input
def fit(self, X, y=None):
return self
def transform(self, X):
self.X = X
return X
# I have corrected the output here, See point 2
def get_feature_names(self):
return self.X.columns.tolist()
Run Code Online (Sandbox Code Playgroud)
现在在您的主文件中,执行以下操作:
from custom_transformers import PassthroughTransformer
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参见以下问题:
您返回self.X.values.tolist():-
这X是一个Pandas DataFrame,因此X.values.tolist()将返回您指定的列的实际数据,而不是列名。因此,即使您解决了第一个错误,您也会在此遇到错误。更正为:
return self.X.columns.tolist()
Run Code Online (Sandbox Code Playgroud)(次要)类继承:
您将PassthroughTransformer定义为:
PassthroughTransformer(FunctionTransformer, BaseEstimator)
Run Code Online (Sandbox Code Playgroud)
FunctionTransformer已经从继承,BaseEstimator所以我认为没有必要从继承BaseEstimator。您可以通过以下方式进行更改:
class PassthroughTransformer(FunctionTransformer):
OR
# Standard way
class PassthroughTransformer(BaseEstimator, TransformerMixin):
Run Code Online (Sandbox Code Playgroud)希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
2256 次 |
| 最近记录: |