机器学习特征工程经验总结二

机器学习特征工程经验总结一
机器学习特征工程经验总结二

--------------------------------------------

如何做特征处理和构建

特征处理和构建一般对以下几种数据类型做处理:

  •     数值型
  •     类别型
  •     时间型
  •     文本型
  •     统计型
  •     组合特征

一、数值型

1 幅度调整/归一化:python中会有一些函数比如preprocessing.MinMaxScaler()将幅度调整到 [0,1] 区间。

2.统计值:包括max, min, mean, std等。python中用pandas库序列化数据后,可以得到数据的统计值。

3.离散化:把连续值转成非线性数据。例如电商会有各种连续的价格表,从0.03到100元,假如以一元钱的间距分割成99个区间,用99维的向量代表每一个价格所处的区间,1.2元和1.6元的向量都是 [0,1,0,…,0]。pd.cut() 可以直接把数据分成若干段。

4.柱状分布:离散化后统计每个区间的个数做柱状图。

二、类别型

类别型一般是文本信息,比如颜色是红色、黄色还是蓝色,我们存储数据的时候就需要先处理数据。处理方法有:
1. one-hot编码,编码后得到哑变量。统计这个特征上有多少类,就设置几维的向量,pd.get_dummies()可以进行one-hot编码。
2. 序数编码
3. Histogram映射:把每一列的特征拿出来,根据target内容做统计,把target中的每个内容对应的百分比填到对应的向量的位置。优点是把两个特征联系起来。
上表中,我们来统计“性别与爱好的关系”,性别有“男”、“女”,爱好有三种,表示成向量 [散步、足球、看电视剧],分别计算男性和女性中每个爱好的比例得到:男[1/3, 2/3, 0],女[0, 1/3, 2/3]。即反映了两个特征的关系。

三、时间型

时间型特征的用处特别大,既可以看做连续值(持续时间、间隔时间),也可以看做离散值(星期几、几月份)。数据挖掘中经常会用时间作为重要特征,比如电商可以分析节假日和购物的关系,一天中用户喜好的购物时间等。

四、地理位置

对地理位置信息(类别型变量)最简单的处理方式是独热编码(one-hot encoding), 但是这样会得到很高维的稀疏特征,影响模型的学习。所以我们可以在独热编码的基础上,做了特征选择。我们可以将地理位置和目标变量做相关性分析,比如违约中可以挑违约率较高的地方,然后做独热编码 ,如果地理位置变量是城市,那独热编码后会产生很高维的特征,这时就要用模型(xgboost)进行特征选择,选出相关性较高的特征。

另外,地理位置还可以做城市等级合并,经纬度特征引入等。

城市等级合并按照城市等级,将类别变量合并,例如一 线城市北京、上海、广州、深圳合并,赋值为 1,同样地,二线城市合并为 2,三线城市合 并为 3。

我们另外收集了各个城市的经纬度, 将城市名用经纬度替换,这样就可以将类别型的变量转化为数值型的变量,比如北京市,用 经纬度(39.92,116.46)替换,得到北纬和东经两个数值型特征。加入经纬度后,线下的 cross validation 一般都有千分位的提升。

五、文本型

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

2. 把词袋中的词扩充到n-gram:n-gram代表n个词的组合。比如“我喜欢你”、“你喜欢我”这两句话如果用词袋表示的话,分词后包含相同的三个词,组成一样的向量:“我 喜欢 你”。显然两句话不是同一个意思,用n-gram可以解决这个问题。如果用2-gram,那么“我喜欢你”的向量中会加上“我喜欢”和“喜欢你”,“你喜欢我”的向量中会加上“你喜欢”和“喜欢我”。这样就区分开来了。

3. 使用TF-IDF特征:TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF(t) = (词t在当前文中出现次数) / (t在全部文档中出现次数),IDF(t) = ln(总文档数/ 含t的文档数),TF-IDF权重 = TF(t) * IDF(t)。自然语言处理中经常会用到。

六、统计型

历届的Kaggle/天池比赛, 天猫/京东排序和推荐业务线里模型用到的特征。统计的内容包括加减平均、分位线、次序型、比例类等。

比如“天池大数据之移动推荐算法大赛”中,给比赛选手两张表,介绍用户和商品信息,要求预测把哪些商品推荐给用户,用户最有可能购买。
(1)加减平均:商品价格高于平均价格多少,用户在某个品类下消费超过平均用户多少,用户连续登陆天数超过平均多少
(2)分位线:商品属于售出商品价格的多少分位线处
(3)次序:排位第几
(4)比例:超过百分之多少

七、组合特征

1.拼接型
简单的组合特征。例如挖掘用户对某种类型的喜爱,对用户和类型做拼接。正负权重,代表喜欢或不喜欢某种类型。
- user_id&&category: 10001&&女裙 10002&&男士牛仔
- user_id&&style: 10001&&蕾丝 10002&&全棉

2.模型特征组合
- 用GBDT产出特征组合路径
- 组合特征和原始特征一起放进LR训练

3.两两特征相除/相乘/相加/相减
乘法特征(取对数):log(x*y),选择出重要度高的特征,加入到原始特征体系中,会有千分位提高。这种特征组合有助于表示非线性关系。

我们可以创建很多不同种类的特征组合。例如:
[A X B]:将两个特征的值相乘形成的特征组合。
[A x B x C x D x E]:将五个特征的值相乘形成的特征组合。
[A x A]:对单个特征的值求平方形成的多项式特征组合。(二阶,三阶等)

争对第三个的可以生成n次方,A的二次方,三次方等,还可以对多个特征进行不同的n次方,比如A的2次方乘与B的三次方等,增加非线性。

4.交互特征:组合独热矢量
在实践中,机器学习模型很少会组合连续特征。不过,机器学习模型却经常组合独热特征矢量,将独热特征矢量的特征组合视为逻辑连接.例如,假设我们具有以下两个特征:国家/地区和语言。对每个特征进行独热编码会生成具有二元特征的矢量,这些二元特征可解读为 country=USA, country=France 或language=English,language=Spanish。然后,如果您对这些独热编码进行特征组合,则会得到可解读为逻辑连接的二元特征。

假设我们的模型需要根据以下两个特征来预测狗主人对狗狗的满意程度:

行为类型(吠叫、叫、偎依等)
时段

如果我们根据这两个特征构建特征组合。我们最终获得的预测能力将远远超过任一特征单独的预测能力。例如,如果狗狗在下午 5 点主人下班回来时(快乐地)叫喊,可能表示对主人满意度的正面预测结果。如果狗狗在凌晨 3 点主人熟睡时(也许痛苦地)哀叫,可能表示对主人满意度的强烈负面预测结果。

5.分桶特征(分箱)

例如,我们可以将 population 分为以下 3 个分桶:

bucket_0 (< 5000):对应于人口分布较少的街区
bucket_1 (5000 - 25000):对应于人口分布适中的街区
bucket_2 (> 25000):对应于人口分布较多的街区
根据前面的分桶定义,以下 population 矢量:

[[10001], [42004], [2500], [18000]]
将变成以下经过分桶的特征矢量:

[[1], [2], [0], [1]]
这些特征值现在是分桶索引。请注意,这些索引被视为离散特征。通常情况下,这些特征将被进一步转换为独热编码表示。

6.最大最小特征
最小最大值一直都是特征提取的重点,当前值与最大最小值之间的差更是值得尝试的特征。

7.还可以用FM模型进行特征组合和降维

总结:组合两个(或更多个)特征是使用线性模型来学习非线性关系的一种聪明做法。在我们的问题中,如果我们只使用 latitude 特征进行学习,那么该模型可能会发现特定纬度(或特定纬度范围内,因为我们已经将其分桶)的城市街区更可能比其他街区住房成本高昂。longitude 特征的情况与此类似。但是,如果我们将 longitude 与 latitude 组合,产生的组合特征则代表一个明确的城市街区。如果模型发现某些城市街区(位于特定纬度和经度范围内)更可能比其他街区住房成本高昂,那么这将是比单独考虑两个特征更强烈的信号。

 

如何做特征选择

在特征工程部分,我们构建了一系列位置信息相关的特征、组合特征、成交时间特征、 排序特征、类别稀疏特征等,这么多维特征一方面可能会导致维数灾难,另一方面很容易导致过拟合,需要做降维处理,降维方法常用的有如 PCA,t-SNE 等,这类方法的计算复杂度比较高。并且根据以往工作经验,PCA 或 t-SNE 效果不是特别好。

除了采用降维算法之外,也可以通过特征选择来降低特征维度。

特征选择的方法很多: 最大信息系数(MIC)、皮尔森相关系数(衡量变量间的线性相关性)、正则化方法(L1, L2)、基于模型的特征排序方法。

用正则化来做特征选择,L1,L2,对于特征维度很大的情况,作L1, 对于特征维度很小的情况,作L2。

比较高效的是最后一种,即基于学习模型的特征排序方法, 这种方法有一个好处:模型学习的过程和特征选择的过程是同时进行的,因此我们采用这种 方法,基于 xgboost 来做特征选择,xgboost 模型训练完成后可以输出特征的重要性,据此我们可以保留 Top N 个特征,从而达到特征选择的目的。

还有其他的总结。

特征选择,就是从多个特征中,挑选出一些对结果预测最有用的特征。因为原始的特征中可能会有冗余和噪声。

特征选择和降维有什么区别呢?前者只踢掉原本特征里和结果预测关系不大的, 后者做特征的计算组合构成新特征。

3.1 过滤型
方法: 评估单个特征和结果值之间的相关程度, 排序留下Top相关的特征部分。

-评价方式:通过方差选择法、Pearson相关系数,相关系数法、卡方检验法、互信息法来对特征进行评分,设定阈值或者待选择的阈值的个数来选择 。

-缺点:只评估了单个特征对结果的影响,没有考虑到特征之间的关联作用, 可能把有用的关联特征误踢掉。比如多项式组合特征,pearson相关系数不是很大,因为是非线性,所以相关系数也不一定大,但如果用这个方法有可能会被去掉,因此工业界使用比较少。

还有方差计算其实可以放在特征处理。计算各个特征的方差,剔除小于设定的阈值的特征,剔除特征值 波动较小的特征,例如一个特征的所有值都为1,那这个特征对于预测目标变量就没什么作用;方法很简单,但实际应用中只有少数变量才会存在只取某个值的情况,对特征选择作用比较小,可以当做数据预处理部分,之后再用其他方法进行特征选择。

3.2 包裹型

-方法:把特征选择看做一个特征子集搜索问题, 筛选各种特 征子集, 用模型评估效果。

-典型算法:“递归特征删除算法”。

-应用在逻辑回归的过程:用全量特征跑一个模型;根据线性模型的系数(体现相关性),删掉5-10%的弱特征,观察准确率/auc的变化;逐步进行, 直至准确率/auc出现大的下滑停止。

3.3 嵌入型

-方法:根据模型来分析特征的重要性,最常见的方式为用正则化方式来做特征选择。

-举例:最早在电商用LR做CTR预估, 在3-5亿维的系数特征上用L1正则化的LR模型。上一篇介绍了L1正则化有截断作用,剩余2-3千万的feature, 意味着其他的feature重要度不够。

正则化主要包括L1正则化和L2正则化:

L1正则化将系数W的L1范数作为惩罚项加到损失函数中,L1正则方法具有稀疏解的特性,因此天然具有特征选择的特性,但是不代表没被选到的特征就不重要,有可能是因为两个高度相关的特征最后只保留了一个;另外L1正则化和非正则化模型一样是不稳定的,如果特征集合中具有相关联的特征,当数据发生细微变化时也有可能导致很大的模型差异。

L2正则化将系数向量的L2范数添加到损失函数中,由于L2惩罚项中的系数是二次方的,会让系数的取值变得平均,对于有相关性的变量,会得到相近的系数;L2正则化也较L1稳。L1会令特征权重变成0,L2会使特征权重趋向于零。

"""1.过滤型"""
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

iris=load_iris()
X,y=iris.data,iris.target
print X.shape
X_new=SelectKBest(chi2,k=2).fit_transform(X,y)
print X_new.shape

"""输出:
(150L, 4L)
(150L, 2L)
"""

"""2.包裹型"""
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_boston

boston=load_boston()
X=boston["data"]
Y=boston["target"]
names=boston["feature_names"]

lr=LinearRegression()
rfe=RFE(lr,n_features_to_select=1)#选择剔除1个
rfe.fit(X,Y)

print "features sorted by their rank:"
print sorted(zip(map(lambda x:round(x,4), rfe.ranking_),names))

"""输出:按剔除后AUC排名给出
features sorted by their rank:
[(1.0, 'NOX'), (2.0, 'RM'), (3.0, 'CHAS'), (4.0, 'PTRATIO'), (5.0, 'DIS'), (6.0, 'LSTAT'), (7.0, 'RAD'), (8.0, 'CRIM'), (9.0, 'INDUS'), (10.0, 'ZN'), (11.0, 'TAX')
, (12.0, 'B'), (13.0, 'AGE')]"""


"""3.嵌入型 ,老的版本没有SelectFromModel"""
from sklearn.svm import  LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel

iris=load_iris()
X,y=iris.data,iris.target
print X.shape

lsvc=LinearSVC(C=0.01,penalty='l1',dual=False).fit(X,y)
model=SelectFromModel(lsvc,prefit=True)
X_new=model.transform(X)
print X_new.shape

"""输出:
(150,4)
(150,3)
"""

还可以用逻辑回归。
from sklearn.linear_model import LogisticRegression

LogisticRegression 里的参数有penalty,可以调用来做特征选择

参考:

https://blog.csdn.net/weixin_42736194/article/details/83050297

https://blog.csdn.net/weixin_42736194/article/details/83051487

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值