J'essaie de créer un transformateur personnalisé pour un pipeline Python sklearn basé sur les conseils de ce tutoriel: http://danielhnyk.cz/creating-your-own-estimator-scikit-learn/

À l'heure actuelle, ma classe / transformateur personnalisé ressemble à ceci:

class SelectBestPercFeats(BaseEstimator, TransformerMixin):
    def __init__(self, model=RandomForestRegressor(), percent=0.8,
                 random_state=52):
        self.model = model
        self.percent = percent
        self.random_state = random_state


    def fit(self, X, y, **fit_params):
        """
        Find features with best predictive power for the model, and
        have cumulative importance value less than self.percent
        """
        # Check parameters
        if not isinstance(self.percent, float):
            print("SelectBestPercFeats.percent is not a float, it should be...")
        elif not isinstance(self.random_state, int):
            print("SelectBestPercFeats.random_state is not a int, it should be...")

        # If checks are good proceed with fitting...
        else:
            try:
                self.model.fit(X, y)
            except:
                print("Error fitting model inside SelectBestPercFeats object")
                return self

            # Get feature importance
            try:
                feat_imp = list(self.model.feature_importances_)
                feat_imp_cum = pd.Series(feat_imp, index=X.columns) \
                    .sort_values(ascending=False).cumsum()

                # Get features whose cumulative importance is <= `percent`
                n_feats = len(feat_imp_cum[feat_imp_cum <= self.percent].index) + 1
                self.bestcolumns_ = list(feat_imp_cum.index)[:n_feats]
            except:
                print ("ERROR: SelectBestPercFeats can only be used with models with"\
                       " .feature_importances_ parameter")
        return self


    def transform(self, X, y=None, **fit_params):
        """
        Filter out only the important features (based on percent threshold)
        for the model supplied.

        :param X: Dataframe with features to be down selected
        """
        if self.bestcolumns_ is None:
            print("Must call fit function on SelectBestPercFeats object before transforming")
        else:
            return X[self.bestcolumns_]

J'intègre cette classe dans un pipeline sklearn comme ceci:

# Define feature selection and model pipeline components
rf_simp = RandomForestRegressor(criterion='mse', n_jobs=-1,
                                n_estimators=600)
bestfeat = SelectBestPercFeats(rf_simp, feat_perc)
rf = RandomForestRegressor(n_jobs=-1,
                           criterion='mse',
                           n_estimators=200,
                           max_features=0.4,
                           )

# Build Pipeline
master_model = Pipeline([('feat_sel', bestfeat), ('rf', rf)])

# define GridSearchCV parameter space to search, 
#   only listing one parameter to simplify troubleshooting
param_grid = {
    'feat_select__percent': [0.8],
}

# Fit pipeline model
grid = GridSearchCV(master_model, cv=3, n_jobs=-1,
                    param_grid=param_grid)

# Search grid using CV, and get the best estimator
grid.fit(X_train, y_train)

Chaque fois que j'exécute la dernière ligne de code (grid.fit(X_train, y_train)), j'obtiens le "PicklingError" suivant. Quelqu'un peut-il voir ce qui cause ce problème dans mon code?

ÉDITER:

Ou, y a-t-il quelque chose dans ma configuration Python qui ne va pas ... Puis-je manquer un package ou quelque chose de similaire? Je viens de vérifier que je peux import pickle avec succès

Traceback (dernier appel le plus récent): fichier "", ligne 5, dans Fichier "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ site-packages \ sklearn \ model_selection_search.py", ligne 945, en forme return self._fit (X, y, groups, ParameterGrid (self.param_grid)) Fichier "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ site-packages \ sklearn \ model_selection_search.py", ligne 564, dans _fit pour les paramètres dans le fichier paramétrable "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ site-packages \ sklearn \ externals \ joblib \ parallel.py", ligne 768, en appel self.retrieve () Fichier "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ site-packages \ sklearn \ externals \ joblib \ parallel.py", ligne 719, en récupération lever le fichier d'exception "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ site-packages \ sklearn \ externals \ joblib \ parallel.py", ligne 682, en récupération self._output.extend (job.get (timeout = self.timeout)) Fichier "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ multiprocessing \ pool.py", ligne 608, dans get lever self._value File "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ multiprocessing \ pool.py", ligne 385, dans _handle_tasks put (task) File "C: \ Users \ jjaaae \ AppData \ Local \ Programs \ Python \ Python36 \ lib \ site-packages \ sklearn \ externals \ joblib \ pool.py", ligne 371, dans envoyer CustomizablePickler (tampon, self._reducers) .dump (obj) _pickle.PicklingError: impossible de pickle: échec de la recherche d'attribut SelectBestPercFeats sur les fonctions intégrées

5
Jed 26 juil. 2017 à 22:09

2 réponses

Meilleure réponse

Le package pickle a besoin que la ou les classes personnalisées soient définies dans un autre module, puis importées. Alors, créez un autre fichier de package python (par exemple transformation.py) puis importez-le comme ceci from transformation import SelectBestPercFeats. Cela résoudra l'erreur de décapage.

7
Jed 7 sept. 2017 à 23:29

J'ai eu le même problème, mais dans mon cas, le problème était d'utiliser des transformateurs de fonction où pickle a parfois des difficultés à sérialiser des fonctions. La solution pour moi était d'utiliser dill à la place, bien que ce soit un peu plus lent.

0
Sebi 6 mars 2019 à 15:29