训练数据集和变压器中不存在分类变量值的测试数据集

数据挖掘 分类数据 变压器
2021-10-07 18:53:26

我想用我的目标变量(名为 'target' )的平均值替换分类变量(名为 'six' )的值。

我在火车数据集 df 上安装一个变压器,然后转换测试数据集 df2。

如何处理仅出现在测试数据集中的值?

当在火车数据集上拟合时,变压器在该值上没有收到目标变量的平均值。

例如 :

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

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

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

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

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

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

df 是我的训练数据集,df2 我的测试数据集。

我们可以看到变量“六”的 k 值在训练数据集中不存在。

下一个 :

df[ 'target' ] = df[ 'target' ].astype( 'float64' )

下一个(我自制的变压器):

class Cat2TargetMean( BaseEstimator , TransformerMixin ) :

    def __init__( self , col2trans , tgt_col ) :
        self._col2trans = col2trans
        self._tgt_col = tgt_col

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

        for col in self._col2trans :
            p = X.groupby( col ).mean()[ self._tgt_col ]
            self._dic_col_p.update( { col : p.to_dict() } )
        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

然后 :

 tsf = Cat2TargetMean( [ 'four' , 'five' , 'six' ] , 'target' )

 tsf.fit( df )

 tsf.transform( df )

 tsf.transform( df2 )

结果 :

    one two three   four    five    six target
    0   2.0 7.0 3.0 0.333333    0.0 0.5 0.0
    1   9.0 2.0 2.0 0.333333    0.0 1   0.0
    2   4.0 5.0 1.0 1.000000    1.0 k   1.0

“六”列的“k”值尚未转换。

3个回答

我通常用全局目标平均值替换 unseen 和 NaN 值。

还有已经实现的用于目标编码的转换器,您可以使用它为您提供一些选项,例如平滑:scikit contrib-target encoder

按照 Simon Larsson 的提示(我通常用全局目标平均值替换 unseen 和 NaN 值)这是我自制变压器的新版本:

class Cat2TargetMean( BaseEstimator , TransformerMixin ) :

def __init__( self , col2trans , tgt_col ) :
    self._col2trans = col2trans
    self._tgt_col = tgt_col

def fit( self , X , y = None ) :
    self._dfl_val = X[ self._tgt_col ].mean()
    self._dic_col_p = {}

    for col in self._col2trans :
        p = X.groupby( col ).mean()[ self._tgt_col ]
        self._dic_col_p.update( { col : p.to_dict() } )
    return self 

def transform( self , X , y = None ) :
    for col , dic_p in self._dic_col_p.items() : 
        X[ col ] = X[ col ].map( dic_p ).fillna( self._dfl_val )
    return X

我使用 map 函数并通过在转换器的 fit 方法中计算的目标变量均值( self._dfl_val(默认值)填充生成的 NaN 值:

self._dfl_val = X[ self._tgt_col ].mean()

最佳实践应该是使用现有的编码器http://contrib.scikit-learn.org/categorical-encoding/targetencoder.html#

您必须在所有数据上安装自制变压器:

tsf.fit( pd.concat([df, df2]))