Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 自定义变压器单独工作,但在将它们组合到一个管道中时会发生故障_Python_Pandas_Scikit Learn_Pipeline - Fatal编程技术网

Python 自定义变压器单独工作,但在将它们组合到一个管道中时会发生故障

Python 自定义变压器单独工作,但在将它们组合到一个管道中时会发生故障,python,pandas,scikit-learn,pipeline,Python,Pandas,Scikit Learn,Pipeline,我需要一些帮助。我正在使用scikit学习处理一些数据,并训练一个ML模型来预测房价。我已经提出了2个自定义变压器,以照顾不需要的功能,还结合了一些功能,以创建新的功能。当我调用这两个自定义转换器时,它们各自工作,但当我将它们合并到一个管道中以改进工作流时,就会出现错误。我不确定是什么问题。 例如,这里是第一个变压器: from sklearn.base import BaseEstimator, TransformerMixin class ColumnSelector(BaseEstima

我需要一些帮助。我正在使用scikit学习处理一些数据,并训练一个ML模型来预测房价。我已经提出了2个自定义变压器,以照顾不需要的功能,还结合了一些功能,以创建新的功能。当我调用这两个自定义转换器时,它们各自工作,但当我将它们合并到一个管道中以改进工作流时,就会出现错误。我不确定是什么问题。 例如,这里是第一个变压器:

from sklearn.base import BaseEstimator, TransformerMixin

class ColumnSelector(BaseEstimator, TransformerMixin):

    def __init__(self, columns):
        self.columns = columns

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

    def transform(self, X):
        return X[self.columns]
然后进行测试:

relevant_columns = ['OverallQual','GrLivArea','GarageCars','GarageArea','YearBuilt','BsmtFinSF1','FullBath', 
                    'GarageYrBlt', 'TotalBsmtSF', '2ndFlrSF', '1stFlrSF', 'HalfBath']

cs = ColumnSelector(columns=relevant_columns)
transformed = cs.fit_transform(X_train)

transformed.head()

同样地



class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
    total_bsmt_sa_ix, second_flr_ix, first_flr_ix, full_bath_ix, half_bath_ix = [
    list(transformed.columns).index(col) for col in ('TotalBsmtSF', '2ndFlrSF', '1stFlrSF', 'FullBath', 'HalfBath')]

    def __init__(self, add_total_sa=True, add_total_baths=True):
        self.add_total_sa = add_total_sa
        self.add_total_baths = add_total_baths

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

    def transform(self, X, y=None):

            if self.add_total_sa and self.add_total_baths:
                total_sa = X[:, total_bsmt_sa_ix] + X[:, second_flr_ix] + X[:, first_flr_ix]
                total_bath = X[:, full_bath_ix] + X[:, half_bath_ix]/2
                return np.c_[X, total_sa, total_bath]

            elif self.add_total_sa:
                total_sa = X[:, total_bsmt_sa_ix] + X[:, second_flr_ix] + X[:, first_flr_ix]
                return np.c_[X, total_sa]

            elif self.add_total_baths:
                total_bath = X[:, full_bath_ix] + X[:, half_bath_ix]/2
                return np.c_[X, total_bath]

            else:
                pass

atr_adder = CombinedAttributesAdder()
housing_extra_attr = atr_adder.transform(transformed.values)

housing_extra_attr = pd.DataFrame(housing_extra_attr, columns=relevant_columns+['total_sa', 'total_bath'], index=transformed.index)
housing_extra_attr.head()

但是,当我制作这样的管道时:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

pipeline = Pipeline([
    ('column_selector', ColumnSelector(columns=relevant_columns)),
    ('attr adder', CombinedAttributesAdder()),
    ('scaler', StandardScaler())
])

X_train_prepd = pipeline.fit(X_train)
我收到了这个错误消息


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-107-ab78197544be> in <module>
      8 ])
      9 
---> 10 X_train_prepd = pipeline.fit(X_train)

~\Anaconda3\envs\ml_book\lib\site-packages\sklearn\pipeline.py in fit(self, X, y, **fit_params)
    350             This estimator
    351         """
--> 352         Xt, fit_params = self._fit(X, y, **fit_params)
    353         with _print_elapsed_time('Pipeline',
    354                                  self._log_message(len(self.steps) - 1)):

~\Anaconda3\envs\ml_book\lib\site-packages\sklearn\pipeline.py in _fit(self, X, y, **fit_params)
    315                 message_clsname='Pipeline',
    316                 message=self._log_message(step_idx),
--> 317                 **fit_params_steps[name])
    318             # Replace the transformer of the step with the fitted
    319             # transformer. This is necessary when loading the transformer

~\Anaconda3\envs\ml_book\lib\site-packages\joblib\memory.py in __call__(self, *args, **kwargs)
    353 
    354     def __call__(self, *args, **kwargs):
--> 355         return self.func(*args, **kwargs)
    356 
    357     def call_and_shelve(self, *args, **kwargs):

~\Anaconda3\envs\ml_book\lib\site-packages\sklearn\pipeline.py in _fit_transform_one(transformer, X, y, weight, message_clsname, message, **fit_params)
    714     with _print_elapsed_time(message_clsname, message):
    715         if hasattr(transformer, 'fit_transform'):
--> 716             res = transformer.fit_transform(X, y, **fit_params)
    717         else:
    718             res = transformer.fit(X, y, **fit_params).transform(X)

~\Anaconda3\envs\ml_book\lib\site-packages\sklearn\base.py in fit_transform(self, X, y, **fit_params)
    551         if y is None:
    552             # fit method of arity 1 (unsupervised transformation)
--> 553             return self.fit(X, **fit_params).transform(X)
    554         else:
    555             # fit method of arity 2 (supervised transformation)

<ipython-input-94-607115cdc09e> in transform(self, X, y)
     13 
     14             if self.add_total_sa and self.add_total_baths:
---> 15                 total_sa = X[:, total_bsmt_sa_ix] + X[:, second_flr_ix] + X[:, first_flr_ix]
     16                 total_bath = X[:, full_bath_ix] + X[:, half_bath_ix]/2
     17                 return np.c_[X, total_sa, total_bath]

~\Anaconda3\envs\ml_book\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)
   2978             if self.columns.nlevels > 1:
   2979                 return self._getitem_multilevel(key)
-> 2980             indexer = self.columns.get_loc(key)
   2981             if is_integer(indexer):
   2982                 indexer = [indexer]

~\Anaconda3\envs\ml_book\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   2895                 )
   2896             try:
-> 2897                 return self._engine.get_loc(key)
   2898             except KeyError:
   2899                 return self._engine.get_loc(self._maybe_cast_indexer(key))

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

TypeError: '(slice(None, None, None), 8)' is an invalid key

---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在里面
8 ])
9
--->10 X_列预处理=管道安装(X_列)
~\Anaconda3\envs\ml\u book\lib\site packages\sklearn\pipeline.py中的fit(self、X、y、**fit\u参数)
350这个估计器
351         """
-->352 Xt,拟合参数=自拟合(X,y,**拟合参数)
353带有“打印”经过的时间(“管道”,
354自我记录信息(len(self.steps)-1):
~\Anaconda3\envs\ml\u book\lib\site packages\sklearn\pipeline.py in\u fit(self,X,y,**fit\u参数)
315消息_clsname='Pipeline',
316消息=自身日志消息(步骤idx),
-->317**配合参数步骤[名称])
318#用安装的变压器更换阶梯变压器
319#变压器。这在加载变压器时是必要的
~\Anaconda3\envs\ml\u book\lib\site packages\joblb\memory.py in\uuuuu调用(self,*args,**kwargs)
353
354定义调用(self,*args,**kwargs):
-->355返回self.func(*args,**kwargs)
356
357 def呼叫和搁置(self、*args、**kwargs):
~\Anaconda3\envs\ml\u book\lib\site packages\sklearn\pipeline.py in\u fit\u transform\u one(transformer,X,y,weight,message\u clsname,message,**fit\u params)
714带有_print_exposed_time(消息名称,消息):
715如果hasattr(变压器,“拟合变换”):
-->716 res=变换器。拟合变换(X,y,**拟合参数)
717其他:
718 res=变换器.fit(X,y,**拟合参数).transform(X)
拟合变换中的~\Anaconda3\envs\ml\u book\lib\site packages\sklearn\base.py(self,X,y,**拟合参数)
551如果y为无:
552算术1的拟合方法(无监督变换)
-->553返回自拟合(X,**拟合参数).transform(X)
554其他:
555算术2的拟合方法(监督变换)
变换中(自、X、y)
13
14如果self.add_total_sa和self.add_total_bath:
--->15总计=X[:,总计+X[:,第二层+X[:,第一层]
16总浴池=X[:,全浴池+X[:,半浴池]/2
17返回np.c[X,总计,总计]
~\Anaconda3\envs\ml\u book\lib\site packages\pandas\core\frame.py in\uuuuuuu getitem\uuuuuuu(self,key)
2978如果self.columns.nlevels>1:
2979返回自我。\u获取项目\u多级(键)
->2980索引器=self.columns.get_loc(键)
2981如果是_整数(索引器):
2982索引器=[索引器]
get\u loc中的~\Anaconda3\envs\ml\u book\lib\site packages\pandas\core\index\base.py(self、key、method、tolerance)
2895                 )
2896尝试:
->2897自动返回发动机。获取位置(钥匙)
2898除按键错误外:
2899返回self.\u引擎。获取self.\u loc(self.\u可能\u cast\u索引器(键))
熊猫\\u libs\index.pyx在熊猫中。\ u libs.index.IndexEngine.get_loc()
熊猫\\u libs\index.pyx在熊猫中。\ u libs.index.IndexEngine.get_loc()
TypeError:“(片(无,无,无),8)”是无效的键
有人知道会出什么问题吗?我真的很震惊。
谢谢你的帮助

找出了问题所在。 问题来自于我如何调用
CombinedAttributesAdder()
中列的索引。解决方案是将计算更改为以下内容:

if self.add_total_sa and self.add_total_baths:
            total_sa = X.iloc[:, total_bsmt_sa_ix] + X.iloc[:, second_flr_ix] + X.iloc[:, first_flr_ix]
            total_bath = X.iloc[:, full_bath_ix] + X.iloc[:, half_bath_ix]/2
            return np.c_[X, total_sa, total_bath]

        elif self.add_total_sa:
            total_sa = X.iloc[:, total_bsmt_sa_ix] + X.iloc[:, second_flr_ix] + X.iloc[:, first_flr_ix]
            return np.c_[X, total_sa]

        elif self.add_total_baths:
            total_bath = X.iloc[:, full_bath_ix] + X.iloc[:, half_bath_ix]/2
            return np.c_[X, total_bath]

        else:
            pass

我所做的就是在每次计算中添加
X.iloc
,找出了问题所在。 问题来自于我如何调用
CombinedAttributesAdder()
中列的索引。解决方案是将计算更改为以下内容:

if self.add_total_sa and self.add_total_baths:
            total_sa = X.iloc[:, total_bsmt_sa_ix] + X.iloc[:, second_flr_ix] + X.iloc[:, first_flr_ix]
            total_bath = X.iloc[:, full_bath_ix] + X.iloc[:, half_bath_ix]/2
            return np.c_[X, total_sa, total_bath]

        elif self.add_total_sa:
            total_sa = X.iloc[:, total_bsmt_sa_ix] + X.iloc[:, second_flr_ix] + X.iloc[:, first_flr_ix]
            return np.c_[X, total_sa]

        elif self.add_total_baths:
            total_bath = X.iloc[:, full_bath_ix] + X.iloc[:, half_bath_ix]/2
            return np.c_[X, total_bath]

        else:
            pass

我所做的只是在每个计算中添加
X.iloc
,你能试着移动
total\u bsmt\u sa\u ix,second\u flr\u ix…
命令中的
CombinedAttributesAdder
\u init\u\u\u\u
并将self附加到每个变量吗?我可以尝试一下,看看它是否有效。不过,我想我知道问题是什么ombinedAttributesAdder()出于某种原因需要一个numpy数组作为输入,但是如果我转换
ColumnSelector()的返回值
若要提供数组而不是数据帧,则索引选择会中断。否,管道可以处理数据帧。无需转换为numpy。但什么是
转换的。列
。单独使用时,
转换的
存在,但在未
转换的管道中。列
是来自数据F的列在
ColumnSelector()处理它之后,
我用它来选择我想在
combinedAttributeReader()中合并的列
。也许有一种我不知道的更好的方法可以做到这一点。你是在问什么类型的对象
转换。列
是什么?你能试着将
total\u bsmt\u sa\u ix,second\u flr\u ix…
命令中的
CombinedAttributesAdder
移动到
中并将self附加到每个变量吗我明白了