Quiero crear mi propio transformador para usarlo con sklearn Pipeline. Por lo tanto, estoy creando una clase que implementa métodos de ajuste y transformación. El propósito del transformador será eliminar filas de la matriz que tengan más de un número específico de NaN. Entonces, el problema que estoy enfrentando es ¿cómo puedo cambiar las matrices X e Y que se pasan al transformador? Creo que esto debe hacerse en el método de ajuste, ya que tiene acceso a X e y. Dado que Python pasa los argumentos por asignación una vez que reasigno X a una nueva matriz con menos filas, la referencia a la X original se pierde (y, por supuesto, lo mismo es cierto para y). ¿Es posible mantener esta referencia?

Estoy usando un DataFrame de pandas para soltar fácilmente las filas que tienen demasiados NaN, esta puede no ser la forma correcta de hacerlo para mi caso de uso. El código actual se ve así:

class Dropna():

    # thresh is max number of NaNs allowed in a row
    def __init__(self, thresh=0):
        self.thresh = thresh

    def fit(self, X, y):
        total = X.shape[1]
        # +1 to account for 'y' being added to the dframe                                                                                                                            
        new_thresh = total + 1 - self.thresh
        df = pd.DataFrame(X)
        df['y'] = y
        df.dropna(thresh=new_thresh, inplace=True)
        X = df.drop('y', axis=1).values
        y = df['y'].values
        return self

    def transform(self, X):
        return X
17
MarkAWard 28 ago. 2014 a las 05:20

3 respuestas

La mejor respuesta

Modificar el eje de muestra, p. eliminando muestras, ¿no cumple (todavía) con la API del transformador scikit-learn. Entonces, si necesita hacer esto, debe hacerlo fuera de cualquier llamada a scikit learn, como preprocesamiento.

Tal como está ahora, la API del transformador se utiliza para transformar las características de una muestra dada en algo nuevo. Esto puede contener implícitamente información de otras muestras, pero las muestras nunca se eliminan.

Otra opción es intentar imputar los valores faltantes. Pero, de nuevo, si necesita eliminar muestras, trátelo como un preprocesamiento antes de usar scikit learn.

9
eickenberg 28 ago. 2014 a las 11:47

Utilice " copias profundas " más adelante, más adelante y X , y permanezca protegido

.fit() puede asignar primero en cada llamada copia profunda a nuevas variables de clase

self.X_without_NaNs = X.copy()
self.y_without_NaNs = y.copy()

Y luego reduzca / transforme estos para que no tengan más NaN - s que los ordenados por self.treshold

-1
user3666197 28 ago. 2014 a las 02:26

Puede resolver esto fácilmente utilizando el método sklearn.preprocessing.FunctionTransformer (http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.FunctionTransformer.html)

Solo necesitas poner tus alternancias a X en una función

def drop_nans(X, y=None):
    total = X.shape[1]                                           
    new_thresh = total - thresh
    df = pd.DataFrame(X)
    df.dropna(thresh=new_thresh, inplace=True)
    return df.values

Entonces obtienes tu transformador llamando

transformer = FunctionTransformer(drop_nans, validate=False)

Que puedes usar en la tubería. El umbral se puede establecer fuera de la función drop_nans.

0
MarkAWard 5 ene. 2016 a las 21:09