尝试构建我自己的 skean 变压器时遇到问题

数据挖掘 scikit-学习 变压器
2022-02-09 21:23:50

我构建了以下 sklearn 转换器:

class Cat2Rat( BaseEstimator , TransformerMixin ) :
   def __init__( self , col2trans ) :
      self._col2trans = col2trans

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

   def transform( self , X , y = None ) :
      for col in self._col2trans : 
         p = X[ col ].value_counts() / X.shape[0]
         dic = dict( [ ( i , p[i] ) for i in ( X[ col ].value_counts() ).index ] )
         X.replace( { col : dic } , inplace = True )
      return X

这个变压器正在用它们的速率代替分类值。

例如 :

myarray = np.array([ [ 1 , 1 , 3 , 'v' , 0 ] , 
                 [ 2 , 2 , 2 , 'v' , 1 ] ,
                 [ 4 , 5 , 1 , 'w' , 1 ] ,
                 [ 2 , 1 , 9 , 'w' , 1 ] , 
                 [ 1 , 0 , 4 , 'w' , 1 ] ] )

colnames = [ 'one', 'two', 'three' , 'four' , 'target' ]

df = pd.DataFrame( myarray , columns = colnames )

列 'four' 的值 'v' ( 'w' ) 替换为 2/5 ( 3/5 )。

我的目的是将变压器安装在 df 上并将其应用于另一个数据帧 df2 :

myarray2 = np.array([ [ 2 , 7 , 3 , 'v' , 0 ] , 
                    [ 9 , 2 , 2 , 'v' , 0 ] ,
                    [ 4 , 5 , 1 , 'w' , 1 ] ]  )

colnames2 = [ 'one', 'two', 'three' , 'four' , 'target' ]

df2 = pd.DataFrame( myarray2 , columns = colnames2 )

我这样做是这样的:

# Transformer instance
trsf = Cat2Rat( [ 'four' ] )

# Fitting
trsf.fit( df )

# Then applying
trsf.transform( df2 )

但费率是 df2 的“四”列值,而不是 df(安装了变压器)。

在正确构建这种变压器的过程中,我一定遗漏了一些东西。

有人可以就如何修复变压器提供一些线索,使其产生正确的结果吗?

谢谢。

2个回答

的定义dic应该发生在fit方法内部;您希望费率基于传递给fit. 因此,您需要设置dic为另一个类属性,以便在transform方法中引用。

(这种替换称为目标编码,在 sklearn 中有一个现有的包可以做到这一点。)

考虑到 Ben Reiniger 的回答,我对我的 sklearn 转换器进行了一些更改:

class Cat2Rat( BaseEstimator , TransformerMixin ) :
   def __init__( self , col2trans ) :
       self._col2trans = col2trans


   def fit( self , X , y = None ):
       self._dic_col_p = {}

       for col in self._col2trans :
           p = X[ col ].value_counts() / X.shape[0]
           dic = dict( [ ( i , p[i] ) for i in ( X[ col ].value_counts() ).index ] )
           self._dic_col_p.update( { col : dic } )

       return self


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

       for col , dic_p in self._dic_col_p.items() : 
           X.replace( { col : dic_p } , inplace = True )
       return X

fit 方法现在生成一个字典,其中的键包含列名,值包含每列值的比例。

例如, self._dic_col_p 包含拟合后:

{ 'four' : {'w': 0.6, 'v': 0.4} , 'five' : {'c': 0.4, 'b': 0.4, 'a': 0.2} }

在哪里 :

myarray = np.array([ [ 1 , 1 , 3 , 'v' , 'a' , 0 ] , 
                   [ 2 , 2 , 2 , 'v' , 'b' , 1 ] ,
                   [ 4 , 5 , 1 , 'w' , 'c' , 1 ] ,
                   [ 2 , 1 , 9 , 'w' , 'c' , 1 ] , 
                   [ 1 , 0 , 4 , 'w' , 'b' , 1 ] ] )

colnames = [ 'one', 'two', 'three' , 'four' , 'five' , 'target' ]

df = pd.DataFrame( myarray , columns = colnames )

谢谢。