
标准化流 是一系列生成式模型,它们将司空见惯的某些简单概率分布“转换”为更复杂的概率分布。
标准化流模型学习易处理的逆变换,以及雅可比行列式的变换。若能有效地计算这两个量,我们可以使用变量代换规则,计算变换后的分布的对数概率密度:
绝大多数标准化流程序在连续密度函数上运行(因此需要计算表示体积变化的雅可比行列式项)。不过最近有一些关于“离散流”的研究,使模型学习转换概率质量函数而不是密度函数( Tran et al. 2019 , Hoogeboom et al. 2019 )。我们在这篇博文中不讨论它们,只是说明,它们通过设计离散的基本分布,实现了双向离散变换。
除了前面提到的随机实数化之外,在训练图像数据的标准化流时,还有一些额外的技巧。
根据经验,在最大似然估计之前,将数据从[0,256]的范围缩放到单位间隔[0,1]上,有助于稳定训练,因为神经网络偏差通常在零附近。
为了防止越界问题,如果采样到基础分布的样本、通过流函数映射到区间(0,1)之外的点,我们可以通过逻辑斯蒂函数(sigmoid函数的反函数)将其重新缩放到( )。
我们可以将范围缩放和逻辑变换视为模型开始时的“预处理”流程。像对待任何其他双向映射函数一样,我们这里也必须考虑变换引起的体积变化。
这里要认识到的重要一点是,出于评估目的,像素密度函数应始终在连续区间[0,256]中计算,以便比较不同的流模型和自回归模型在同一数据中的似然值(最多可相差由于随机实数化引起的变分空隙【变分下限与真值之间的差】)。
下图显示了RGB图像的标准归一化流程,左侧是原始离散数据,右侧是基本密度函数(可以是高斯分布、逻辑分布或任何你喜欢的易处理的密度分布)。
使用分类分布对像素进行建模的一个缺点是,分类交叉熵损失不能告诉我们值为127的像素比值为0的像素、距离值为128的像素更接近。【也就是丢失了类别之间的相对关系。】对于观察到的像素值 ,分类交叉熵的梯度相对于像素值是恒定的(因为损失将类别视为无序的)。尽管交叉熵梯度非零,但它被认为“稀疏”的,因为它不提供关于当下的分布与目标分布(以像素值衡量)的距离信息。理想情况下,当预测值远离观测值时,我们希望梯度的幅度更大;而当模型接近观测值时,我们希望梯度更小。
将像素建模为分类分布的一个更严重的缺点是,如果我们选择的特征表示高达或超过256个类别,就会遇到麻烦。例如,模拟R,G和B像素联合分布(有256 ^ 3类别!)或模拟比uint8更高精度像素编码的HDR图像。当我们试图存储神经网络激活值映射到上述类别所需的投影矩阵时,我们很快就会耗尽内存。
两篇同时发表的论文 Inverse Autoregressive Flow 和 PixelCNN++ ,通过将RGB像素建模为 序数数据 的概率分布来解决这些问题,来自交叉熵损失的梯度信息可以在正确方向上推动模型,同时模型仍保留离散概率。
我们可以通过逻辑斯蒂混合模型来建模连续像素概率密度,这是一种连续分布。为了恢复离散像素值的概率质量,我们可以使用逻辑斯蒂分布的属性方便地计算它的概率积分函数,即sigmoid函数。通过计算两个逻辑斯蒂函数的差值 ,我们可以恢复介于两个整数像素值之间的总概率质量。
以这种方式表示像素的另一个好处,是提供了一次性处理更多类别的“奢侈”。这意味着PixelCNN ++可以一次性地模拟R、G和B像素通道。需要注意的是,你必须充分调整混合成分的数量(在Cifar 10上,5似乎已经足够了)。
类似于 Tran et al. 2019 在类别分布上设计离散的流函数, Hoogeboom et al. 2019 通过使用离散化的逻辑斯蒂混合似然作为基本分布,来设计序数格式的离散流。后者的方法具备两个方面的优势:既能使用标准化流,很容易地处理了求逆和采样;同时避免了求解实数化的似然目标(这可能会优化对似然函数的标准差进行估计的损失下限)。两篇论文都令人非常兴奋,我希望将来对此写更多内容!
对数似然也是评估语言建模领域中的生成式模型的常用度量。 没有排序的离散字母表的分布律构成的分类分布,是概率密度建模的最自然的选择。
起源于自然语言处理(NLP)领域的一个怪癖,语言模型的似然通常以 “困惑度” 为单位进行评估,其由下式给出: 。 困惑度的倒数的对数 ,即是平均对数似然 。 困惑度是一个直观的概念,因为逆概率是随机变量的“分支因子”,或着叫做随机变量的加权平均可选择数。 困惑度和对数似然之间的关系是如此简单,以至于一些论文( Image Transformer )将“困惑度”与对数似然互换地使用。
在这篇博文中,我们推导出最大化平均对数似然和信息压缩之间的关系。我们还提到了像素的离散似然模型和连续似然模型的几种建模选择。
一个更深层次的问题是,似然值是否是衡量/优化的正确目标。在 NIPS 2016 (现称为NeurIPS会议)上,我记得在生成式建模研讨会上曾有一翻非常激烈的争论,研究人员们辩论优化易处理的似然模型是否是一个好主意。
事实证明,优化和评估最大化似然模型是一个好主意,因为从那以后研究人员已经想出如何构建和扩展 更灵活的似然模型 ,同时保持计算的易处理性。像Glow、GPT-2、WaveNet和Image Transformer这样的模型经过最大化似然的训练,可以生成具有惊人质量的图像、音频和文本。另一方面,有人可能会争辩说,生成式建模最终目的是与实际任务相结合,提高实际应用的性能,例如提高在标记数据集上、对模型进行微调时的分类准确性。【即数据增广。】对于这一点,我的同事Niki Parmar关于图像与文本的似然模型做出以下评论:
在未来的博客文章中,我将在本教程基础上,继续讨论优化对数似然的变分下界的生成模型的评估方法(例如变分自动编码器、重要性加权自动编码器)。
非常感谢 Dustin Tran , Niki Parmar 和 Vincent Vanhoucke 审阅这篇博文的草稿。一如既往地,感谢你的阅读!
首页博客
研修院
VIP
APP
问答
下载
社区
推荐频道
活动
招聘
专题
打开CSDN APP
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
风控模型特征工程
打开APP
风控建模二、特征工程---通用 原创
2022-09-17 11:46:33
1点赞
沐自礼
码龄8年
关注
目录
一、数据预处理
1.1 缺失值
1.2 异常值处理
1.3 样本不均衡处理
二、特征生成
2.1 特征归一化(or 标准化)
2.2 特征放缩(统计信息+ 简单加减乘除)
2.3 哑变量
2.3 分桶
2.4 日期类
2.5 组合特征
2.6 文本型(风控场景中应用比较少,传统nlp应用较多)
2.6.1 词袋模型+Ngram
2.6.2 tf-idf
2.6.3 word2vev/fastext
2.7 embedding
2.8 特征分解 (应用较少)
三、特征筛选
3.1 移除低方差的特征 (Removing features with low variance)
3.2. 单变量特征选择 (Univariate feature selection)
3.2.1 卡方(Chi2)检验
3.2.2 Pearson相关系数 (Pearson Correlation)
3.3 递归特征消除 (Recursive Feature Elimination)
3.4 基于L1的特征选择 (L1-based feature selection)
3.5 xgboost, lightGBM
参考文献
“特征决定了模型的上限, 而算法只是逼近这个上限”,由此可见特征工程在风控建模中的重要程度。 特征工程的本质是基于原始数据的信息提炼, 风控场景中的很多数据源, 单独来看可能和风险表现关联性并不强,但是加工成特征后, 却会与我们想要预测的目标产生紧密的联系。
下面我们将从特征预处理,特征生成,特征筛选三个模块对特征工程进行拆解。
一、数据预处理
1.1 缺失值
一般来说,未经处理的原始数据中通常会存在缺失值,因此在建模训练之前需要处理好缺失值。
1)缺失数据占比小于 20%。可以通过直接填充法,连续特征一般取均值填充,离散特征可以取众数填充;可以模型预测法,通过随机森林或者决策树进行预测结果填充;也可以通过插值法填充。
2)缺失数据占比大于 20% 小于 50%,这个时候可以把缺失值构建为新的特征,增加一列离散特征,即有缺失数据和无缺失数据。
3)缺失数据占比大于 50%,因为信息量较少,模型可能会学到大量噪音建议直接删除该特征。
像 xgboost 模型自带缺失值处理功能,可以不进行缺失值处理。
缺失值填充方法:
1). 如果是连续性,就使用平均值插补,如果是离散性,就使用众数来插补。 当然也可以用特殊值、中位数等代替。 其中采用均值填充的缺点:大大降低数据的方差
2). 随机插补法----从总体中随机抽取某个样本代替缺失样本
3). 引入预测模型,可考虑辅助回归,通过变量间的关系来预测缺失数据
下面代码就是均值填充的两种方案:
df_train['Age'].fillna(value=df_train['Age'].mean()).sample(10)
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
df_train.loc[:,'Age'] = df_train['Age'].fillna(value=df_train['Age'].mean()).copy()
df_train.head(10)
1.2 异常值处理
异常值,即在数据集中存在不合理的值,又称离群点、极值等。可以通过统计分析、箱线图、聚类、3σ 原则、孤立森林等方法进行检查。
一般的处理方法如下:
1)直接删除含有异常值的样本。
2)视为缺失值。利用缺失值处理的方法进行处理。
3)最近值修正。可以用相近的观测值修正该异常值。
4)不处理。可以直接在具有异常值的数据集上进行数据建模。
大部分建模时,通过画图的方式进行看一下即可。
提供的方法:
统计分析,看四分位数,看数据分布。
箱线图:使用画图工具比如seaborn库 调用boxplot,distplot看一下。
聚类:使用sklearn中的聚类函数。
3σ: 需要自己同统计,类似看四分位数。
1.3 样本不均衡处理
推荐包:imbalance learn (https://imbalanced-learn.org/stable/references/index.html)
后面章节会对样本不均衡做详细的介绍,暂时可以先简单了解一下。一般应用场景中,常用样本不均衡的是解决方案为1,2。
样本不均衡现象是指正样本数目与负样本数目比列相差很大。处理方法如下:
1)下采样/欠采样(under sampling):从多数类中随机抽取样本从而减少多数类别样本数据,使数据达到平衡的方式。比如本来样本正负例的比例是 10:1,可以对正样本进行下采样构建 10 个正负样本比例为 1:1 的模型,回归结果取平均值,分类结果进行投票。
2)上采样/过采样(Over Sampling):和欠采样采用同样的原理,通过抽样来增加少数样本的数目,从而达到数据平衡的目的。同样比如本来样本正负例的比例是 10:1,可以对负样本进行上采样构建正负样本比例为 1:1 的模型。
3)Smote 算法:Smote 算法属于上采样的一种,通过人工合成的方法来生成少类别的样本。方法也很简单,对于某一个缺少样本的类别,它会随机找出几个该类别的样本,再找出最靠近这些样本的若干个该类别样本,组成一个候选合成集合,然后在这个集合中不停的选择距离较近的两个样本,在这两个样本之间,比如中点,构造一个新的该类别样本。举个例子,比如该类别的候选合成集合有两个样本(x1,y),(x2,y)(x1,y),(x2,y),那么Smote采样后,可以得到一个新的训练样本(x1+x22,y)(x1+x22,y),通过这种方法,我们可以得到不改变训练集分布的新样本,让训练集中各个类别的样本数趋于平衡。
4)Focal loss :主要解决分类样本不平衡问题,通过修改交叉熵损失函数,通过增加类别权重 α 和样本难度权重调因子(modulating factor)(1−pt)γ(1−pt)γ,来减缓上述问题。
5)设置损失函数的权重:使得少数类别数据判断错误的损失大于多数类别数据判断错误的损失,即当我们的少数类别数据预测错误的时候,会产生一个比较大的损失值,从而导致模型参数往让少数类别数据预测准确的方向偏。
二、特征生成
2.1 特征归一化(or 标准化)
应用于数值类特征。
归一化(标准化),就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。其目的一是把不同量纲的东西放在同一量纲下,保正程序运行时收敛加快,大部分模型归一化后收敛速度会加快。但像树模型不受特征归一化影响,所以不需要特征归一化。
归一化处理:最大最小值归一化或者叫 0-1 归一化,取值范围在 [0,1] 处理,max 为样本最大值, min 为样本最小值。
标准化处理:这里只介绍一种经常使用的 z-score 标准化,经过处理后的数据均值为 0,标准差为 1,符合标准的正态分布。其中 mean 为平均值,б 为标准差。
# 幅度缩放,最大最小值缩放到[0,1]区间内
from sklearn.preprocessing import MinMaxScaler
mm_scaler = MinMaxScaler()
fare_trans = mm_scaler.fit_transform(df_train[['Fare']])
# 幅度缩放,将每一列的数据标准化为正态分布的
from sklearn.preprocessing import StandardScaler
std_scaler = StandardScaler()
fare_std_trans = std_scaler.fit_transform(df_train[['Fare']])
#中位数或者四分位数去中心化数据,对异常值不敏感
from sklearn.preprocessing import robust_scale
fare_robust_trans = robust_scale(df_train[['Fare','Age']])
#将同一行数据规范化,前面的同一变为1以内也可以达到这样的效果
from sklearn.preprocessing import Normalizer
normalizer = Normalizer()
fare_normal_trans = normalizer.fit_transform(df_train[['Age','Fare']])
fare_normal_trans
2.2 特征放缩(统计信息+ 简单加减乘除)
应用于数值类特征,可以引入log非线性进行放缩。
import numpy as np
log_age = df_train['Age'].apply(lambda x:np.log(x))
df_train.loc[:,'log_age'] = log_age
# 最大最小值
max_age = df_train['Age'].max()
min_age = df_train["Age"].min()
# 分位数,极值处理,我们最粗暴的方法就是将前后1%的值抹去
age_quarter_01 = df_train['Age'].quantile(0.01)
print(age_quarter_01)
age_quarter_99 = df_train['Age'].quantile(0.99)
print(age_quarter_99)
df_train.loc[:,'family_size'] = df_train['SibSp']+df_train['Parch']+1
df_train.head()df_train.loc[:,'tmp'] = df_train['Age']*df_train['Pclass'] + 4*df_train['family_size']
df_train.head()
2.3 哑变量
哑变量用于类别,一般如性别,分为男女两列。
embarked_oht = pd.get_dummies(df_train[['Embarked']])
embarked_oht.head()
2.3 分桶
应用于数值。
可以等频分桶,也可以自行指定区间分桶。非线性变化。
# 等频切分
df_train.loc[:,'fare_qcut'] = pd.qcut(df_train['Fare'], 10)
df_train.head()
df_train = df_train.sort_values('Fare')
alist = list(set(df_train['fare_qcut']))
badrate = {}
for x in alist:
a = df_train[df_train.fare_qcut == x]
bad = a[a.label == 1]['label'].count()
good = a[a.label == 0]['label'
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)