开发者社区> 致Great_VIP> 正文

转 Target Encoding之Smoothing

简介: 转 Target Encoding之Smoothing
+关注继续查看

Smoothing,简单来说,就是将原来独立的高数量类别特征的每个值映射到概率估计上。基本来讲,这个预处理方法将原始的值放置到实际的机器学习模型之前先通过一个简单的特征处理模型(如贝叶斯模型)。


下面以binary target为例进行方法分析:

当target属性 Y∈{0,1}时,假设要处理的特征为X,该特征的每一个不同的值为Xi。我们要做的是, 将高数量类别特征将映射到一个标量Si中,Si代表一个条件概率,即


Xi→Si≅P(Y|X=Xi)−−−(1)

注意到Si代表的是条件概率,那么他的值被归一到了0和1之间,这对于神经网络模型也是一个好的预处理。

下一步就是概率估计的过程。我们假设数据集被分成了nTR个训练集和nTS个测试集。因为这个概率估计成为了模型训练的一部分,所以只有训练集的数据被使用。注意到不是所有的X的可能值都会出现在训练集中,有的值可能只出现在测试集或者新进来的数据中。所以,这个映射过程必须要能够处理这个特征的不可预见性的值。

如果该特征某个值如X=Xi出现的数量足够多,那么这个概率估计可以这样计算:


Si=niYni−−−(2)

这是一个后验概率的计算过程。然而不幸的是,特征的值的数量分布通常是不均匀的,有很多值的数量非常少。所以这种使用P(Y|X=Xi)的直接估计是不太可靠的。

为了减小这种小数量值的影响,Si的计算可能被分成两个概率的组合。后验概率的计算如公式(2),先验概率的计算如P(Y)=nYnTR。整个组合计算公式为:


Si=λ(ni)niYni+(1−λ(ni))nYnTR−−−(3)

nY代表在整个数据集中Y=1的数量。λ(ni)是一个在0-1之间的单调递增函数。

原理:一方面,当特征的某个值的数量很多,即λ≅1时,公式即为(2),计算后验概率。另一方面,当特征的某个值的数量很少时,即λ≅0时,公式前项为0,只计算先验概率。

所以,关键我们怎么选取λ(ni)这个函数呢?有一个典型函数如下:


λ(n)=11+exp−n−kf−−−(4)

这个公式是一个s形状的函数,当 n=k 时值为 0.5 。

参数 f 控制函数在转折处的斜率,决定了先验概率和后验概率之间的平衡。如果f→∞,那么公式(3)变为一个硬间隔,即先验概率和后验概率各占0.5。

参数 k 决定于我们允许的特征值数量的最小值的一半。so important!

我们在来看看经验贝叶斯估计(Empirical Bayes estimation) 的一般公式:


P=Biyi+(1−Bi)y¯¯¯−−−(5)

y¯¯¯是先验概率,yi是经验后验概率。收缩系数Bi根据不同的估计方法有不同的形式。当所有概率分布服从高斯分布的时候:


Bi=niτ2σ2+niτ2−−−(6)

σ2是值的方差,τ2是样本方差。事实上,公式(6)是公式(4)的一般形式。

以下是我在kaggle中看到大佬对该方法的coding实现,借以参考,帮助理解:

def add_noise(series, noise_level):
    return series * (1 + noise_level * np.random.randn(len(series)))
def target_encode(trn_series=None, 
                  tst_series=None, 
                  target=None, 
                  min_samples_leaf=1, 
                  smoothing=1,
                  noise_level=0):
    """
    trn_series : training categorical feature as a pd.Series
    tst_series : test categorical feature as a pd.Series
    target : target data as a pd.Series
    min_samples_leaf (int) : minimum samples to take category average into account
    smoothing (int) : smoothing effect to balance categorical average vs prior  
    """ 
    assert len(trn_series) == len(target)
    assert trn_series.name == tst_series.name
    temp = pd.concat([trn_series, target], axis=1)
    # Compute target mean 
    averages = temp.groupby(by=trn_series.name)[target.name].agg(["mean", "count"])
    # Compute smoothing
    smoothing = 1 / (1 + np.exp(-(averages["count"] - min_samples_leaf) / smoothing))
    # Apply average function to all target data
    prior = target.mean()
    # The bigger the count the less full_avg is taken into account
    averages[target.name] = prior * (1 - smoothing) + averages["mean"] * smoothing
    averages.drop(["mean", "count"], axis=1, inplace=True)
    # Apply averages to trn and tst series
    ft_trn_series = pd.merge(
        trn_series.to_frame(trn_series.name),
        averages.reset_index().rename(columns={'index': target.name, target.name: 'average'}),
        on=trn_series.name,
        how='left')['average'].rename(trn_series.name + '_mean').fillna(prior)
    # pd.merge does not keep the index so restore it
    ft_trn_series.index = trn_series.index 
    ft_tst_series = pd.merge(
        tst_series.to_frame(tst_series.name),
        averages.reset_index().rename(columns={'index': target.name, target.name: 'average'}),
        on=tst_series.name,
        how='left')['average'].rename(trn_series.name + '_mean').fillna(prior)
    # pd.merge does not keep the index so restore it
    ft_tst_series.index = tst_series.index
    return add_noise(ft_trn_series, noise_level), add_noise(ft_tst_series, noise_level)


两个方法比较


smoothing方法可以只要通过对本地数据集的操作就可完成预处理,而clustering方法需要更复杂的算法而且可能导致信息量的减少(因为最后仍然需要进行one-hot编码)。

当然,对于smoothing方法来说, λ函数的选择直接影响到了结果,可能不同的λ函数可以适用于不同的分支领域,这都需要实验的考证。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
18900 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
28107 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
13109 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
22097 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
15591 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
20179 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14871 0
+关注
400
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载