ml课程:特征工程、面试题及相关案例代码

以下是我的学习笔记,以及总结,如有错误之处请不吝赐教。

这篇文章主要介绍机器学习特征工程相关的内容,以及《百面机器学习》中相关高频面试题内容,最后还有相关的案例代码。

特征工程(Feature engineering):

是对原始数据进行一系列工程处理,将其提炼为特征,作为输入供算法和模型使用。从本质上来讲,特征工程是一个表示和展现数据的过程。在实际工作中,特征工程旨在去除原始数据中的杂质和冗余,设计更高效的特征以刻画求解的问题与预测模型之间的关系。

数据类型:

  • 结构化数据:结构化数据类型可以看作关系型数据库的一张表,每列都有清晰的定义,包含了数值型、类别型两种基本类型;每一行数据表示一个样本的信息。
  • 非结构化数据:非结构化数据主要包括文本、图像、音频、视频数据,其包含的信息无法用一个简单的数值表示,也没有清晰的类别定义,并且每条数据的大小各不相同。

数据处理

  • 数据采集:①考虑哪些数据有用;②数据是否能够采集;③线上实时计算是够快捷
  • 数据格式化:①确定存储格式;②数据库存储结构
  • 数据清洗:①去除简单的不可能的值;②组合或同级属性判定;③补齐可对应的缺省值
  • 数据采样:①正负样本不均匀;②模型对正负样本敏感;③随机采样和分层抽样
  • 正负样本不均衡处理:

                    1)正样本>>负样本,且数量较大:采取下采样;

                    2)正样本>>负样本,数量不大:①采集更多数据;②oversamping,比如cv中旋转图像;③修改损失函数

       面试问题:在图像分类任务中,训练数据不足会带来什么问题?如何缓解数据量不足带来的问题?

  • 一个模型所能提供的信息一般来源于两个方面,一是训练数据中蕴含的信息;二是在模型的形成过程中(包括构造、学习、推理等),人们提供的先验信息。当训练数据不足时,说明模型从原始数据中获取的信息比较少,这种情况下要想保证模型的效果,就需要更多先验信息。先验信息可以作用在模型上,例如让模型采用特定的内在结构、条件假设或添加其他一些约束条件;先验信息也可以直接施加在数据集上,即根据特定的先验假设去调整、变换或扩展训练数据,让其展现出更多的、更有用的信息,以利于后续模型的训练和学习。
  • 具体到图像分类任务上,训练数据不足带来的问题主要表现在过拟合方面,即模型在训练样本上的效果可能不错,但在测试集上的泛化效果不佳。根据上述讨论,对应的处理方法大致也可以分两类:1)是基于模型的方法,主要是采用降低过拟合风险的措施,包括简化模型(如将非线性模型简化为线性模型)、添加约束项以缩小假设空间(如L1/L2正则项)、集成学习、Dropout超参数等;2)是基于数据的方法,主要通过数据扩充(Data Augmentation),即根据一些先验知识,在保持特定信息的前提下,对原始数据进行适当变换以达到扩充数据集的效果。
  • 具体到图像分类任务中,在保持图像类别不变的前提下,可以对训练集中的每幅图像进行以下变换。①一定程度内的随机旋转、平移、缩放、裁剪、填充、左右翻转等,这些变换对应着同一个目标在不同角度的观察结果。②对图像中的像素添加噪声扰动,比如椒盐噪声、高斯白噪声等。③颜色变换。例如,在图像的RGB颜色空间上进行主成分分析,得到3个主成分的特征向量p1,p2,p3及其对应的特征值 λ1,λ2,λ3,然后在每个像素的RGB值上添加增量[p1,p2,p3]•[α1λ1,α2λ2,α3λ3]T,其中 α1,α2,α3是均值为0、方差较小的高斯分布随机数。④改变图像的亮度、清晰度、对比度、锐度等。
  • 除了直接在图像空间进行变换,还可以先对图像进行特征提取,然后在图像的特征空间内进行变换,利用一些通用的数据扩充或上采样技术,例如SMOTE(Synthetic Minority Over-sampling Technique)算法。抛开上述这些启发式的变换方法,使用生成模型也可以合成一些新样本,例如当今非常流行的生成式对抗网络模型。此外,借助已有的其他模型或数据来进行迁移学习在深度学习中也十分常见。例如,对于大部分图像分类任务,并不需要从头开始训练模型,而是借用一个在大规模数据集上预训练好的通用模型,并在针对目标任务的小数据集上进行微调(fine-tune),这种微调操作就可以看成是一种简单的迁移学习。

特征处理

类型分为:①数值型②类别型③时间型④文本型⑤统计型⑥组合特征,下面分别介绍如何进行处理:

一、数值型

  1. 幅度调整/线性归一化(Min-Max Scaling):原始数据进行线性变换,使结果映射到[0, 1]的范围,实现对原始数据的等比缩放。主要使用的函数有:min_max_scaler(),公式如下:

    举例:

  2. 标准化/零均值归一化(z-score Normalization):它会将原始数据映射到均值为0、标准差为1的分布上。具体来说,假设原始特征的均值为μ、标准差为σ,那么归一化公式定义为:

    举例:

    面试问题:为什么需要对数值型特征做归一化呢?                                                                                                                借助随机梯度下降的实例来说明归一化的重要性。假设有两种数值型特征,x1的取值范围为 [0, 10],x2的取值范围为[0, 3],于是可以构造一个目标函数符合图1.1(a)中的等值图。在学习速率相同的情况下,x1的更新速度会大于x2,需要较多的迭代才能找到最优解。如果将x1和x2归一化到相同的数值区间后,优化目标的等值图会变成图1.1(b)中的圆形,x1和x2的更新速度变得更为一致,容易更快地通过梯度下降找到最优解。

    注意:归一化和标准化的区别是分别对属性横坐标和特征纵坐标做归一化;通过梯度下降法求解的模型通常是需要归一化的,包括线性回归、逻辑回归、支持向量机、神经网络等模型。但对于决策树模型则并不适用,以C4.5为例,决策树在进行节点分裂时主要依据数据集D关于特征x的信息增益比,而信息增益比跟特征是否经过归一化是无关的,因为归一化并不会改变样本在特征x上的信息增益。
  3. 统计值:主要运用是对分位数的处理进行采样,剔除噪音。

  4. 离散化:即我们常说的分桶处理,对连续值或者离散值分段处理,对label进行非线性的特征进行处理。主要分为等距切分(cut)和等频切分(qcut):

    面试问题:离散化的意义: ①非线性!逻辑回归属于广义线性模型,表达能力受限;单变量离散化为n个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合;②速度快!稀疏向量内积运算速度快,计算结果方便存储,容易扩展;③鲁棒性!离散化后的特征对异常值有很强的鲁棒性:比如一个特征是年龄>30是1,否则为0.如果特征没有离散化,一个异常数据“年龄30岁”会给模型造成很大的干扰;④方便交叉与特征组合:离散化后可以进行特征交叉,有m+n个变量变为m*n个变量,进一步引入非线性,提升表达能力;⑤稳定性!特征离散化后,模型更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成完全不同的一个人,当然处于区间相邻出的样本会刚好相反,所以怎么划分区间是们学问;⑥简化模型:特征离散化后,起到了简化模型的作用,降低了过拟合的风险。
  5. hash分桶
  6. 统计值、柱状分布(比例):每个类别下对应的变量统计值histogram(分布状况):

  7. 数值型转类别型

二、类别型

  1. one-hot编码/哑变量

  2. Hash技巧:与上面的0/1处理不一样,是将其进行频次统计,放入不同Hash标签。

  3. Histogram映射:将一个特征对另一个特征进行映射处理,统计每个类别变量下各个target比例,转换为数值型,从而得到一个新的特征,具体可以看下例:

        面试问题:在对数据进行预处理时,应该怎样处理类别型特征?

  •    序号编码:通常用于处理类别间具有大小关系的数据。例如成绩,可以分为低、中、高三档,并且存在“高>中>低”的排序 关系。序号编码会按照大小关系对类别型特征赋予一个数值ID,例如高表示为3、中表示为2、低表示为1,转换后依然保留了大小关系。
  • 独热编码:通常用于处理类别间不具有大小关系的特征。例如血型,一共有4个取值(A型血、B型血、AB型血、O型血),独热编码会把血型变成一个4维稀疏向量,A型血表示为(1, 0, 0, 0),B型血表示为(0, 1, 0, 0),AB型表示为(0, 0,1, 0),O型血表示为(0, 0, 0, 1)。对于类别取值较多的情况下使用独热编码需要注意以下问题。(1)使用稀疏向量来节省空间。在独热编码下,特征向量只有某一维取值为1,其他位置取值均为0。因此可以利用向量的稀疏表示有效地节省空间,并且目前大部分的算法均接受稀疏向量形式的输入。(2)配合特征选择来降低维度。高维度特征会带来几方面的问题。一是在K近邻算法中,高维空间下两点之间的距离很难得到有效的衡量;二是在逻辑回归模型中,参数的数量会随着维度的增高而增加,容易引起过拟合问题;三是通常只有部分维度是对分类、预测有帮助,因此可以考虑配合特征选择来降低维度。
  •  二进制编码:主要分为两步,先用序号编码给每个类别赋予一个类别ID,然后将类别ID对应的二进制编码作为结果。以A、B、AB、O血型为例,下表是二进制编码的过程。A型血的ID为1,二进制表示为001;B型血的ID为2,二进制表示为010;以此类推可以得到AB型血和O型血的二进制表示。可以看出,二进制编码本质上是利用二进制对ID进行哈希映射,最终得到0/1特征向量,且维数少于独热编码,节省了存储空间。

三、时间型

  1. 连续值:a)持续时间;b)间隔时间
  2. 离散值:a)一天中时间段;b)一周中星期几;c)一年中哪个星期;d)一年中哪个季度;e)工作日/周末

四、文本型

  1. 词袋:将文本数据处理后,去掉停用词,剩下的词组成的list,在词库中映射成稀疏向量:

  2. n-gram:把词袋中的词扩充到n-gram:

  3. TF-IDF:是一种统计方法,用以评估一字词对于一个文件集或一个语料库的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在与联考中出现的频率成反比下降。

  4. word2vec:是一种稠密化的向量映射方式:

        面试问题:有哪些文本表示模型?它们各有什么优缺点?

  • 词袋模型和N-gram模型:最基础的文本表示模型是词袋模型。顾名思义,就是将每篇文章看成一袋子词,并忽略每个词出现的顺序。具体地说,就是将整段文本以词为单位切分开,然后每篇文章可以表示成一个长向量,向量中的每一维代表一个单词,而该维对应的权重则反映了这个词在原文章中的重要程度。常用TF-IDF来计算权重,公式为:

    其中TF(t,d)为单词t在文档d中出现的频率,IDF(t)是逆文档频率,用来衡量单词t对表达语义所起的重要性,表示为

    直观的解释是,如果一个单词在非常多的文章里面都出现,那么它可能是一个比较通用的词汇,对于区分某篇文章特殊语义的贡献较小,因此对权重做一定惩罚。将文章进行单词级别的划分有时候并不是一种好的做法,比如英文中的naturallanguage processing(自然语言处理)一词,如果将natural,language,processing这3个词拆分开来,所表达的含义与三个词连续出现时大相径庭。通常,可以将连续出现的n个词(n≤N)组成的词组(N-gram)也作为一个单独的特征放到向量表示中去,构成N-gram模型。另外,同一个词可能有多种词性变化,却具有相似的含义。在实际应用中,一般会对单词进行词干抽取(Word Stemming)处理,即将不同词性的单词统一成为同一词干的形式。
  • 主题模型:主题模型用于从文本库中发现有代表性的主题(得到每个主题上面词的分布特性),并且能够计算出每篇文章的主题分布。
  • 词嵌入与深度学习模型:词嵌入是一类将词向量化的模型的统称,核心思想是将每个词都映射成低维空间(通常K=50~300维)上的一个稠密向量(Dense Vector)。K维空间的每一维也可以看作一个隐含的主题,只不过不像主题模型中的主题那样直观。由于词嵌入将每个词映射成一个K维的向量,如果一篇文档有N个词,就可以用一个N×K维的矩阵来表示这篇文档,但是这样的表示过于底层。在实际应用中,如果仅仅把这个矩阵作为原文本的表示特征输入到机器学习模型中,通常很难得到令人满意的结果。因此,还需要在此基础之上加工出更高层的特征。在传统的浅层机器学习模型中,一个好的特征工程往往可以带来算法效果的显著提升。而深度学习模型正好为我们提供了一种自动地进行特征工程的方式,模型中的每个隐层都可以认为对应着不同抽象层次的特征。从这个角度来讲,深度学习模型能够打败浅层模型也就顺理成章了。卷积神经网络和循环神经网络的结构在文本表示中取得了很好的效果,主要是由于它们能够更好地对文本进行建模,抽取出一些高层的语义特征。与全连接的网络结构相比,卷积神经网络和循环神经网络一方面很好地抓住了文本的特性,另一方面又减少了网络中待学习的参数,提高了训练速度,并且降低了过拟合的风险。

        面试问题:Word2Vec是如何工作的?它和LDA有什么区别与联系?

  • 谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。
  • Word2Vec实际是一种浅层的神经网络模型,它有两种网络结构,分别是CBOW(Continues Bagof Words)和Skip-gram。CBOW的目标是根据上下文出现的词语来预测当前词的生成概率,如图(a)所示;而Skip-gram是根据当前词来预测上下文中各词的生成概率,如图(b)所示:

    其中w(t)是当前所关注的词,w(t−2)、w(t−1)、w(t+1)、w(t+2)是上下文中出现的词。这里前后滑动窗口大小均设为2。CBOW和Skip-gram都可以表示成由输入层(Input)、映射层(Projection)和输出层(Output)组成的神经网络。输入层中的每个词由独热编码方式表示,即所有词均表示成一个N维向量,其中N为词汇表中单词的总数。在向量中,每个词都将与之对应的维度置为1,其余维度的值均设为0。在映射层(又称隐含层)中,K个隐含单元(Hidden Units)的取值可以由N维输入向量以及连接输入和隐含单元之间的N×K维权重矩阵计算得到。在CBOW中,还需要将各个输入词所计算出的隐含单元求和。同理,输出层向量的值可以通过隐含层向量(K维),以及连接隐含层和输出层之间的K×N维权重矩阵计算得到。输出层也是一个N维向量,每维与词汇表中的一个单词相对应。最后,对输出层向量应用Softmax激活函数,可以计算出每个单词的生成概率。Softmax激活函数的定义为:

    其中x代表N维的原始输出向量,xn为在原始输出向量中,与单词wn所对应维度的取值。
  • 随后训练神经网络的权重,使得语料库中所有单词的整体生成概率最大化。从输入层到隐含层需要一个维度为N×K的权重矩阵,从隐含层到输出层又需要一个维度为K×N的权重矩阵,学习权重可以用反向传播算法实现,每次迭代时将权重沿梯度更优的方向进行一小步更新。但是由于Softmax激活函数中存在归一化项的缘故,推导出来的迭代公式需要对词汇表中的所有单词进行遍历,使得每次迭代过程非常缓慢,由此产生了Hierarchical Softmax和NegativeSampling两种改进方法。训练得到维度为N×K和K×N的两个权重矩阵之后,可以选择其中一个作为N个词的K维向量表示。
  • Word2Vec与LDA的区别:①LDA是利用文档中单词的共现关系来对单词按主题聚类,也可以理解为对“文档-单词”矩阵进行分解,得到“文档-主题”和“主题-单词”两个概率分布。而Word2Vec其实是对“上下文-单词”矩阵进行学习,其中上下文由周围的几个单词组成,由此得到的词向量表示更多地融入了上下文共现的特征。也就是说,如果两个单词所对应的Word2Vec向量相似度较高,那么它们很可能经常在同样的上下文中出现。需要说明的是,上述分析的是LDA与Word2Vec的不同,不应该作为主题模型和词嵌入两类方法的主要差异;②主题模型通过一定的结构调整可以基于“上下文-单词”矩阵进行主题推理。同样地,词嵌入方法也可以根据“文档-单词”矩阵学习出词的隐含向量表示;③主题模型和词嵌入两类方法最大的不同其实在于模型本身,主题模型是一种基于概率图模型的生成式模型,其似然函数可以写成若干条件概率连乘的形式,其中包括需要推测的隐含变量(即主题);而词嵌入模型一般表达为神经网络的形式,似然函数定义在网络的输出之上,需要通过学习网络的权重以得到单词的稠密向量表示。

五:统计型

  1. 加减平均:超过平均多少,高于平均多少;
  2. 分位线属于多少分位线处;
  3. 次序型:排在第几位;
  4. 比例类:好/中/差比例。

六、组合特征

  1. 简单组合特征:拼接型
  2. 模型特征组合:用GBDT产出特征组合路径+LR等算法

        面试问题:什么是组合特征?如何处理高维组合特征?

  • 为了提高复杂关系的拟合能力,在特征工程中经常会把一阶离散特征两两组合,构成高阶组合特征。以逻辑回归为例,假设数据的特征向量为X=(x1,x2,...,xk),则有:,其中<xi, xj>表示xi和xj的组合特征,wij的维度等于|xi|·|xj|,|xi|和|xj|分别代表第i个特征和第j个特征不同取值的个数。

        面试问题:怎样有效地找到组合特征?

  • 介绍一种基于决策树的特征组合寻找方法:以点击预测问题为例,假设原始输入特征包含年龄、性别、用户类型(试用期、付费)、物品类型(护肤、食品等)4个方面的信息,并且根据原始输入和标签(点击/未点击)构造出了决策树,如下图所示:

    于是,每一条从根节点到叶节点的路径都可以看成一种特征组合的方式。具体来说,就有以下4种特征组合的方式。(1)“年龄<=35”且“性别=女”。(2)“年龄<=35”且“物品类别=护肤”。(3)“用户类型=付费”且“物品类型=食品”。(4)“用户类型=付费”且“年龄<=40”。那么第1个样本按照上述4个特征组合就可以编码为(1, 1, 0, 0),因为同时满足(1)(2),但不满足(3)(4)。同理,第2个样本可以编码为(0, 0, 1, 1),因为它同时满足(3)(4),但不满足(1)(2),如下表所示:

特征选择:

原因

  1. 冗余:部分特征的相关的太高,消耗计算性能;
  2. 噪声:部分特征是对预测结果有负影响。

特征选择与降维区别

  1. 特征选择值剃掉原本特征里和结果预测关系不大的,降维是做特征的计算组合构成新特征;
  2. SVD或者PCA也能解决一定的高维度问题。

方式

  • 过滤型:a)评估单个特征和结果值之间的相关程度,排序留下top相关的特征部分;b)pearson相关系数,互信息,距离相关度;

    缺点:没有考虑到特征之间的关联作用,可能把有用的关联特征误剃掉。
  • 包裹型:a)把特征选择看做一个特征自己搜索问题,筛选各种特征子集,用模型评估结果;b)典型的包裹算法为:递归特征删除算法;

  • 嵌入型:a)根据模型来分析特征的重要性(跟包裹型不同,是从生产的模型的权重来分析);b)常用方式为正则化方式来做特征选择,例如将特征上用L1正则化的LR模型,将其他特征系数为0的去除。

总结:

1.幅度缩放
df.Age.apply(np.log)
sklearn:MinMaxScaler
sklearn:StandardScaler

 2.统计结果作为特征:
df_train.loc[:,'FamilySize'] = df_train['SibSp'] + df_train['Parch'] + 1 
df_train.sample(10)

3.缺失值处理
df_train['Age'] = df_train['Age'].fillna(df_train['Age'].mean())

4.高次特征和交叉特征
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2)
poly.fit_transform(df_train[['SibSp','Parch']])

5.归一化
Normalizer()

 6.独热向量编码
pandas.get_dummies()
skelarn:OneHotEncoder
 

7.日期时间
pandas:to_datetime
dt.month dt.dayofweek dt.dayofyear

8.文本
sklearn:CountVectorizer
sklearn:TfidfVectorizer
gensim:word2vec
 

特征选择:
1.过滤式/Filter(较少使用)
根据每一列与target的相关性选择
from sklearn.feature_selection import SelectPercentile
import numpy as np
select = SelectPercentile(percentile=70)

2.包裹式/wrapper
RFE,递归去除列评估结果
from sklearn.feature_selection import RFE
select = RFE(RandomForestClassifier(n_estimators=100, random_state=42), n_features_to_select=40)
select = RFE(LogisticRegression(penalty="l1"), n_features_to_select=40)
 

3.嵌入式/Embedded
from sklearn.feature_selection import SelectFromModel
select = SelectFromModel(RandomForestClassifier(n_estimators=100, random_state=42), threshold="median")

 

案例代码:欢迎关注我的github.


To be continue.....

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值