【问题标题】:AttributeError while implementing FAMD with SMOTENC in a imblearn pipeline在 imblearn 管道中使用 SMOTENC 实现 FAMD 时出现 AttributeError
【发布时间】:2021-06-02 00:01:39
【问题描述】:

我正在尝试使用 FAMD、SMOTENC 和其他预处理步骤来实现管道。但是,它每次都会出错。如果我从管道中删除 FAMD,它工作正常。

我的代码:

#Seperate the dataset in two parts
num_df= X_train_new.select_dtypes(include=[np.number]).columns
cat_df= X_train_new.select_dtypes(exclude=[np.number]).columns

#Create a mask for categorical features
categorical_feature_mask = X_train_new.dtypes == object
print(categorical_feature_mask)

from sklearn.pipeline import make_pipeline
from sklearn.compose import make_column_transformer
from sklearn.compose import make_column_selector as selector

#Create a pipeline to automate the preprocessing steps and SMOTENC together
num_pipe = make_pipeline(SimpleImputer(strategy='median'))
cat_pipe = make_pipeline(SimpleImputer(strategy='most_frequent'),
                          OneHotEncoder(handle_unknown='ignore'))
transformer= make_column_transformer((num_pipe, selector(dtype_include='number')),
                                      (cat_pipe, selector(dtype_include='object')),n_jobs=2)
#Undersampling with SMOTENC
from imblearn.over_sampling import SMOTENC
smote= SMOTENC(categorical_features=categorical_feature_mask,random_state=99)

!pip install prince
from prince import FAMD
famd=FAMD(n_components=4,random_state=99)

from imblearn.pipeline import make_pipeline as imb_pipeline
#Fit the random forest learner
rf=RandomForestClassifier(n_estimators=300random_state=99)
pipe=imb_pipeline(transformer,smote,famd,rf)
pipe.fit(X_train_new,y_train_new)
print('Training Accuracy:%s'%pipe.score(X_train_new,y_train_new))

错误:

AttributeError                            Traceback (most recent call last)

<ipython-input-24-2b7ea084a318> in <module>()
      3 rf=RandomForestClassifier(n_estimators=300,max_features=3,criterion='entropy',random_state=99)
      4 pipe=imb_pipeline(transformer,smote,famd,rf)
----> 5 pipe.fit(X_train_new,y_train_new)
      6 print('Training Accuracy:%s'%pipe.score(X_train_new,y_train_new))

6 frames

/usr/local/lib/python3.7/dist-packages/imblearn/pipeline.py in fit(self, X, y, **fit_params)
    235 
    236         """
--> 237         Xt, yt, fit_params = self._fit(X, y, **fit_params)
    238         if self._final_estimator is not None:
    239             self._final_estimator.fit(Xt, yt, **fit_params)

/usr/local/lib/python3.7/dist-packages/imblearn/pipeline.py in _fit(self, X, y, **fit_params)
    195                     Xt, fitted_transformer = fit_transform_one_cached(
    196                         cloned_transformer, None, Xt, yt,
--> 197                         **fit_params_steps[name])
    198                 elif hasattr(cloned_transformer, "fit_resample"):
    199                     Xt, yt, fitted_transformer = fit_resample_one_cached(

/usr/local/lib/python3.7/dist-packages/joblib/memory.py in __call__(self, *args, **kwargs)
    350 
    351     def __call__(self, *args, **kwargs):
--> 352         return self.func(*args, **kwargs)
    353 
    354     def call_and_shelve(self, *args, **kwargs):

/usr/local/lib/python3.7/dist-packages/imblearn/pipeline.py in _fit_transform_one(transformer, weight, X, y, **fit_params)
    564 def _fit_transform_one(transformer, weight, X, y, **fit_params):
    565     if hasattr(transformer, 'fit_transform'):
--> 566         res = transformer.fit_transform(X, y, **fit_params)
    567     else:
    568         res = transformer.fit(X, y, **fit_params).transform(X)

/usr/local/lib/python3.7/dist-packages/sklearn/base.py in fit_transform(self, X, y, **fit_params)
    572         else:
    573             # fit method of arity 2 (supervised transformation)
--> 574             return self.fit(X, y, **fit_params).transform(X)
    575 
    576 

/usr/local/lib/python3.7/dist-packages/prince/famd.py in fit(self, X, y)
     27 
     28         # Separate numerical columns from categorical columns
---> 29         num_cols = X.select_dtypes(np.number).columns.tolist()
     30         cat_cols = list(set(X.columns) - set(num_cols))
     31 

/usr/local/lib/python3.7/dist-packages/scipy/sparse/base.py in __getattr__(self, attr)
    689             return self.getnnz()
    690         else:
--> 691             raise AttributeError(attr + " not found")
    692 
    693     def transpose(self, axes=None, copy=False):

AttributeError: select_dtypes not found

【问题讨论】:

  • 是否有任何理由相信(文档、示例等)FAMD 确实可以在 imblearn 管道中工作?
  • 文档说 FAMD 熟悉 scikit learn API...SMOTENC 必须在 imblearn 管道中使用。然后我如何在管道中一起实现 SMOTENC 和 FAMD?对此的任何想法将不胜感激。
  • 一个最小的例子确实有助于调试,但我可能已经发现了问题。

标签: python machine-learning scikit-learn imblearn


【解决方案1】:

tl;dr:尝试将sparse=False 添加到您的OneHotEncoder。考虑使用prince 提出问题,以处理稀疏输入。

从回溯中可以看出,问题在于FAMD.fit 尝试X.select_dtypes 来分离分类数据和数值数据。 select_dtypes 是一个 pandas 函数,所以通常我会假设 prince 被编写为对数据帧进行操作,而不是 sklearn 内部使用的 numpy 数组(必要时在从帧转换之后)。但是,查看源代码,他们确实将其从 numpy 数组转换为数据帧。 但是,最后一条跟踪消息来自 scipy。这暗示您的 X 实际上可能是一个稀疏数组。事实上OneHotEncoder(在你的管道中的早期)更喜欢输出稀疏数组,ColumnTransformer 根据其组成部分和参数sparse_threshold 确定是转换为稀疏数组还是密集数组。

【讨论】:

  • thanx..u 一个救生员
猜你喜欢
  • 2019-06-15
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
相关资源
最近更新 更多