老卫带你学---特征工程

在数据挖掘中,非常核心的步骤就是特征工程。对于项目来说,算法的调优需要一个月的时间,可是特征迭代的周期只需要2周。并且特征处理的好,决定了项目模型的上限,而我们的算法只是一步步去逼近这个上限。

介绍

在这里插入图片描述
其实在互联网公司的数据挖掘岗位,做的大部分的工作就是数据的处理
在这里插入图片描述
在这里插入图片描述
当我们需要哪些数据的时候,我们可以给数据收集人员提出需求。比如我们要做广告推荐,我们可能不光需要ctr(点击率),我们还需要用户在页面停留的时间。这时候,我们就可以将我们的需求告诉开发人员,开发人员在前端页面上进行“埋点”,来收集这些信息。
如果我们正在做的项目是一个商品推荐,那么我们需要的数据可以从三方面收集:店家,用户,商品。店家方面,我们可以收集评分评论发货时间。商品方面,可以收集材质购买数量退换货情况评论。用户方面,可以收集历史数据好友列表
在这里插入图片描述
简单的说,可以有以下几个流程:数据收集数据格式化数据清洗
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那么数据清洗都需要注意哪些方面:
单一属性的数据组合属性的数据缺省值数据
举例,身高三米的人肯定不正常。
打篮球的用户中,百分之85的人是女生,这数据也不好。
有很多缺省值的数据也不好。
在这里插入图片描述
对于数据正负样本比例不正常,我们可以采用上下采样来平衡数据。
上采样就是增加数据量,常见的操作比如说图像的增多
下采样及时减少数据量,常见的操作比如说成比例缩小
在这里插入图片描述

特征处理

如果按照数据对象的类别划分,可以划分以下几类特征。
数值型,文本型,图像型,类别型,时间型,统计型,组合特征。
在这里插入图片描述

1.数值型

首先我们看一下数值型数据的特征处理,因为大部分的数据都是数值型。
在这里插入图片描述
首先看一下归一化。如果我们的数据存在很大的幅度,有的是个位数,有的是千位数,那么这样的数据放入我们的模型中,很容易训练出有问题的模型。我们需要使用数据归一化来将数据归一化至统一幅度之间。

import numpy as np
import pandas
from sklearn import preprocessing

arr=np.random.randn(20,20) ###生成一个二维随机矩阵
print(arr)
min_max_scale=preprocessing.MinMaxScaler().fit_transform(arr) ###使用sklean的预处理模块preprocessing进行数据预处理,MinMaxScaler().fit_transform(arr)可以进行数据归一化。
print(min_max_scale)

紧接着,我们看一下数据的统计值。这里我们使用pandas进行数据的分析,因为pandas是一款专门用于处理数据的python包。

import numpy as np
import pandas

arr1=np.random.randn(50) ###产生一串随机数
print(arr1)
series=pd.Series(arr1)  ###将数据按照pandas序列化
print(series.describe())   ###Series的describe可以计算统计值

#####
count    50.000000
mean     -0.092880
std       0.847667
min      -1.738970
25%      -0.713173
50%      -0.215304
75%       0.395048

然后我们看一下数据的离散化。之所以需要数据离散化,是因为我们可以将用户的连续值数据,通过离散化,变成矩阵形式,便于我们训练模型。

所谓的数据离散化,是根据数据分布,来划分多个数据段,构造矩阵向量。然后将原数据进行匹配,看落在哪个数据段中,并将向量对应的值置为1.

当然,一般情况我们是对数据进行等距划分,但是如果我们的数据密度不一致,我们需要使用等频次进行划分。

arr1=np.random.randn(10)
print(arr1)
x=pd.cut(arr1,4)   ###pandas的cut可以将数据区间,按照我们的需要切分成我们需要的数据区间
print(x)

#####
[(-0.0473, 0.548], (-1.24, -0.642], (0.548, 1.143], (-0.0473, 0.548], (0.548, 1.143], (-0.0473, 0.548], (-0.0473, 0.548], (-0.642, -0.0473], (0.548, 1.143], (-1.24, -0.642]]
Categories (4, interval[float64]): [(-1.24, -0.642] < (-0.642, -0.0473] < (-0.0473, 0.548] <
                                    (0.548, 1.143]]

最后我们看一下分析数据的柱状分布。

arr1=np.random.randint(0,10,size=50)
print(arr1)
series=pd.Series(arr1)
print(series.value_counts())   ###采用Series的value_counts进行柱状分析,也就是统计每种数据有多少个。

#####
5    9
3    8
6    7
7    6
8    5
9    4
1    4
4    3
2    2
0    2

2.类别型

因为我们有很多的类别是无法用数值来表示的。比如我们的衣服的颜色类别,产品的类别。那么这时候我们需要将类别进行一定的处理。
对于类别数据的处理,我们可以分为三种方法:
one-hot编码;hash与聚类处理;统计每个类别变量下各个target比例,转成数值型。

1.one-hot编码与离散化很类似。离散化是将原数据分布,划分成多个数据段,然后将原数据进行段匹配,如果数据落入某个数据段内,将向量对应位置置为1(如[0,0,0,1,0])。而one-hot是将每个类别看做一个数据段,将数据进行匹配,并将向量对应位置置为1。

pandas有one-hot的处理方法,get_dummies可以通过one-hot编码对类别进行处理。

pd.get_dummies()

2.特征hash(hash技巧):
这部分可以看我的另一篇博客 老卫带你学—Feature hashing(特征哈希)

3.histogram直方图映射

根据该类别在总类别数所占的比列,比如下图中男生的向量:足球有两个,那么占总体的2/3。
在这里插入图片描述

3.时间型(我们需要将时间分析出,该天的季节,是否是周内周末,天气等等因素)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.文本型(词袋;n-gram;TF-IDF;word2vec)

在这里插入图片描述
sklearn提供了这样的接口CountVectorizer,具体可以看我的这篇博客老卫带你学—sklearn的CountVectorizer()类解析
在这里插入图片描述
我们可以将词袋进行扩充,变为n-gram。也就是以前我们是根据一个单词一个单词分,现在我们加连词的形式。

from sklearn.feature_extraction.text import CountVectorizer

test=[
    "this is the first document",
    "this is the second second document"]
bigram_vectorizer=CountVectorizer(ngram_range=(1,2),token_pattern=r'\b\w+\b',min_df=1)
x2=bigram_vectorizer.fit_transform(test).toarray()
print(x2)
print(bigram_vectorizer.get_feature_names())
feature_index=bigram_vectorizer.vocabulary_.get("second")
print(x2[:,feature_index])

另外一种方法是TF-IDF。该方法衡量一个词对于一篇文档的重要性。
如果一个词在一个文档中出现的次数越多,则代表可能是重要的;
如果一个词在所有的语料库中出现的次数多,那么它很可能是一个常用词(比如the),那么它就不是相对重要。
在这里插入图片描述
还有一种方法是word2vec。
它可以将词与词之间的关系衡量出来。
比如说“国王”与“女王”的距离,会和“男人”和“女人”的距离一样。
谷歌有一个word2vec的包,大家可以直接去使用
在这里插入图片描述
在这里插入图片描述

5. 统计特征(加减平均;分位数;次序;比例)

在这里插入图片描述

6.组合特征

组合特征将各个单一特征结合起来,形成更好的特征。
在这里插入图片描述
目前很多的公司都使用 GBDT+LR的方式;
GBDT所产生的特征路径,就是我们所生成的组合特征。
在这里插入图片描述

特征处理案例

下面这个是《天池大数据之移动推荐算法大赛》的一道题目:
根据以下的数据,预测未来用户的消费点
在这里插入图片描述
然后有部分同学是这样处理数据的:
在这里插入图片描述
在这里插入图片描述

特征选择与降维(过滤型;包裹性;嵌入型)

在这里插入图片描述

过滤型

在这里插入图片描述
sklearn中也包含了过滤型特征选择的模块。
SelectKBest可以选出k个特征;
SelectPercentile可以选出一定比例的特征。
在这里插入图片描述

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectPercentile,SelectKBest
from sklearn.feature_selection import chi2

iris=load_iris()
x,y=iris.data,iris.target
print(x)
x_new=SelectPercentile(chi2,50).fit_transform(x,y)
x_new_2=SelectKBest(chi2,2).fit_transform(x,y)
print(x_new)
包裹型

我们可以采用包裹型的特征选择方法。
其基本思想是,我们每次选择一定的子集,然后运行该模型,如果该子集的模型与原模型的性能相比,差别不大。那么我们就说子集之外的特征是多余的特征。

在这里插入图片描述
我们的sklearn中包含了这样的接口,RFE

from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_iris,load_boston
from sklearn.feature_selection import SelectPercentile,SelectKBest,RFE

boston=load_boston()
x=boston['data']
print(x)
y=boston['target']
names=boston['feature_names']

lr=LinearRegression()
rfe=RFE(lr,n_features_to_select=1)

rfe.fit(x,y)
print(rfe.ranking_,names)
嵌入型

对于我们的模型中,每个x前面会有一个θ权重,当权重很小时,我们就可以将这个特征去掉。一般我们采用L1正则化来做特征选择。
在这里插入图片描述
python中有这样的接口,SelectFromModel来实现 使用L1来消除冗余特征。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值