7 votes

Erreur de transformateur de colonne Scikitlearn : L'ordre des colonnes doit être le même pour l'ajustement et la transformation lors de l'utilisation du mot-clé remainder.

J'ai un modèle simple avec un pipeline utilisant ColumnTransformer.

Je suis en mesure d'entraîner le modèle et de le sauvegarder sous forme de fichier pickle.

Lorsque je charge le fichier pickle et que je prédis les données en temps réel, je reçois l'erreur suivante concernant ColumnTransformer

L'ordre des colonnes doit être le même pour l'ajustement et pour la transformation lors de l'utilisation du mot-clé remainder.

Les données d'entraînement et les données utilisées pour la prédiction ont exactement le même nombre de colonnes, par exemple 50. Je ne vois pas comment l'ordre des colonnes aurait pu changer.

Pourquoi l'ordre des colonnes est-il important pour le transformateur de colonnes ? Comment résoudre ce problème ? Existe-t-il un moyen de garantir l'ordre des colonnes après l'exécution d'un transformateur de colonnes ?

Merci.

   pipeline = Pipeline([
        ('RepalceInf', ReplaceInf()),
        ('impute_30_100', ColumnTransformer(
            [
                ('oneStdNorm', OneStdImputer(), self.cont_feature_strategy_dict['FEATS_30_100']),
            ],
            remainder='passthrough'
        )),
        ('regress_impute', IterativeImputer(random_state=0, estimator=self.cont_estimator)),
        ('replace_outlier', OutlierReplacer(quantile_range=(1, 99))),
        ('scaler', StandardScaler(with_mean=True))
    ])

class OneStdImputer(TransformerMixin, BaseEstimator):
def __init__(self):
    """
    Impute the missing data with random value in the range of mean +/- one standard deviation
    This is a simplified implementation without sparse/dense fit and check.
    """
    self.mean = None
    self.std = None

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

def transform(self, X):
    # X_imp = X.fillna(np.random.randint()*2*self.std+self.mean-self.std)
    for col in X:
        self._fill_randnorm(X[col], col)
    return X

def _fill_randnorm(self, df, col):
    val = df.values
    mask = np.isnan(df)
    mu, sigma = self.mean[col], self.std[col]
    val[mask] = np.random.normal(mu, sigma, size=mask.sum())
    return df

4voto

小笼包 Points 46

Vous pouvez utiliser df_new =pd.DataFrame(df_origin, columns=df_train.columns pour s'assurer que les données à prédire sont les mêmes colonnes avec des données d'apprentissage.

Et d'après l'exemple donné, il est évident que ColumnTransformer prendra la numéro de commande d'une colonne choisie comme marque de traitement (bien que vous puissiez utiliser le nom exact pour choisir une colonne, mais je pense que cela se transformera aussi en nombre).

>>> import numpy as np
>>> from sklearn.compose import ColumnTransformer
>>> from sklearn.preprocessing import Normalizer
>>> ct = ColumnTransformer(
...     [("norm1", Normalizer(norm='l1'), [0, 1]),
...      ("norm2", Normalizer(norm='l1'), slice(2, 4))])
>>> X = np.array([[0., 1., 2., 2.],
...               [1., 1., 0., 1.]])
>>> # Normalizer scales each row of X to unit norm. A separate scaling
>>> # is applied for the two first and two last elements of each
>>> # row independently.
>>> ct.fit_transform(X)
array([[0. , 1. , 0.5, 0.5],
       [0.5, 0.5, 0. , 1. ]])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X