不犯错误的人不会尝试新事物。——爱因斯坦
【机器学习课程】第三章特征工程 1.特征构造
文章目录
0.特征工程介绍
在数据准备过程中,增加了数据质量检查环节,目的是让模型从高质量的数据中学到正确的知识,从而提升模型的性能,尽可能的降低“garbage in, garbage out”的状况。
如果说数据准备过程的质量分析是初步的筛查,那么特征工程就是专家检查。
特征工程就是从一个原始数据集中提取特征的过程,这些特征能很好的描述这些数据,在业务流程中可能具有巨大的贡献。
底层数据已经决定了模型预测能力的上限(100),模型用的特征是在逼近底层数据所决定的上限(90),而模型算法则是在逼近特征所决定的上限(80)。 特征提取的质量越高,所建立的模型对业务完成质量就越高。就好比找到的了影响问题解决的关键信息,模型性能,预测精度都会有很大提高。
特征工程主要包括:特征构造(Feature construction)、 特征选择(Feature Selection)、 特征提取( Feature Extraction)环节。
1.特征构造
特征构造: 利用底层数据加工构建出新的特征。以结构化的表格数据为例,一般使用特征交叉、分解原有的特征来创建新的特征。
特征构造的需要业务人员具有很强的观察能力和分析能力。
# 从数据的整理进行观察分析
data.shape
data.isnull()
data.info()
data.describe()
# 从数据类别角度进行观察分析
data[data[label]==0].describe() #标签A
data[data[label]==1].describe() #标签B
1.1 单变量特征构造(数据重编码)
1.连续变量 等宽离散化(等宽重编码)
确定连续数值变量的最大值和最小值,将区间进行等分规划,
panda的cut函数进行等宽离散化。
例如:0-100的成绩,按10份进行等分得到1,2,2,3,…9,10.
'''
cut函数(x, bins,labels=None)
x:分类变量
bins:分类依据
labels:分类后标签
注意默认范围左边开区间
'''
import pandas as pd
data=[[1,1,111],[2,22,222],[3,60,333],[3,99,333],[3,100,333]]
df = pd.DataFrame(data)
df.columns=['x1','x2','x3']
#分类依据
bin=[0,10,20,30,40,50,60,70,80,90,100]
#重编码
df['x2_new']=pd.cut(df['x2'],bin)
print(df)
2.连续变量 等频离散化(等频重编码)
panda的cut函数进行等频离散化。
实际上是数学里的中位数,就是1/2分位数,25%分位数。
data=[[1,1,111],[2,77,222],[3,60,333],[3,62,333],[3,99,333],[3,88,333]]
df = pd.DataFrame(data)
df.columns=['x1','x2','x3']
k=4 #分位数设置
w = [1.0*i/k for i in range(k+1)]
#使用describe函数自动计算分位数
w = df.describe(percentiles = w)[4:4+k+1]
print(w)
w['x2'] = w['x2']*(1-1e-10)
print(w['x2'])
'''
0% 1.00
25% 60.50
50% 69.50
75% 85.25
100% 99.00
'''
d2 = pd.cut(df['x2'], w['x2'])
print(d2)
3.连续变量 利用聚类进行离散化
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans #引入KMeans
data=[[1,1,111],[2,77,222],[3,60,333],[3,62,333],[3,99,333],[3,88,333]]
data = pd.DataFrame(data)
data.columns=['x1','x2','x3']
data=data['x2']
k = 4
kmodel = KMeans(n_clusters = k) #建立模型,n_jobs是并行数,一般等于CPU数较好
kmodel.fit(data.values.reshape((len(data), 1))) #训练模型
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0)#输出聚类中心,并且排序(默认是随机序的)
print(np.shape(c))
print("-------------")
print(c)
w = c.rolling( 2).mean().iloc[1:] #相邻两项求中点,作为边界点
w = [0] + list(w[0]) + [data.max()] #把首末边界点加上
print("*****************")
print(w)
d3 = pd.cut(data, w, labels = range(k))
#自定义作图函数来显示聚类结果
def cluster_plot(d, k):
import matplotlib.pyplot as plt
#用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']
#用来正常显示负号
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize = (8, 3))
for j in range(0, k):
plt.plot(data[d==j], [j for i in d[d==j]], 'o')
plt.ylim(-0.5, k-0.5)
return plt
'''
使用这句代码: temp = pd.rolling_mean(temp, 2) 会报以下错误:
AttributeError: module 'pandas' has no attribute 'rolling_mean'
解决方法
将代码改为:temp = temp .rolling(2).mean()
'''
# 绘图
cluster_plot(d1, k).show()
cluster_plot(d2, k).show()
cluster_plot(d3, k).show()
4.连续变量 标准化(规范化)
数据标准化处理是特征工程的一项基础工作,为了消除指标之间的量纲和取值范围差异的影响。
数据标准化又叫做数据规划化,主要方法有:
1.最大最小标准化又叫做离差标准化
2.标准差标准化也叫零均值标准化或分数标准化
3.小数定标标准化
import pandas as pd
import numpy as np
# 数据标准化
data=[[1,1,111],[2,77,222],[3,60,333],[3,62,333],[3,99,333],[3,88,333]]
data = pd.DataFrame(data)
data.columns=['x1','x2','x3']
# 最大最小标准化
'''
# 最大最小标准化又叫做离差标准化
# 将数据转化为【0,1】之间
# 容易受到异常点的影响
'''
print((data - data.min()) / (data.max() - data.min()))
print()
# 零-均值标准化
'''
标准差标准化也叫零均值标准化或分数标准化
'''
print((data - data.mean())/ data.std())
print()
# 小数定标标准化
'''
小数定标标准化 --- x/10^k
# k -- lg(|x|.max())在向上取整【lg是以10为低的对数函数】
# 通过移动小数点来使得数据转化到【-1,1】之间
'''
print(data/10**np.ceil(np.log10(data.abs().max())))
5.离散变量 自然数编码/字典编码
以性别为例,性别特征的取值只有"男"和"女"。在进行使用的时候我们可以0和1来映射两个值,将离散型文本转换成数值。
import pandas as pd
data=[[1,1,111,'男'],[2,77,222,'男'],[3,60,333,'女']]
data = pd.DataFrame(data)
data.columns=['x1','x2','x3','gender']
#映射内容保存为字典
map_dict = {'男':0,'女':1}
#根据字典进行编码
data['gender'] = data['gender'].map(map_dict)
data
6.离散变量 独热编码/哑变量变换
对于一个离散变量,若其取值有m个,则经过哑变量处理后就变成了m个二元特征,并且这些特征互斥,每次只有一个激活,这使得数据变得稀疏。
以下列数据中的天气状况为例,4个取值分别是’阴天’,‘晴天’,‘雨天’,‘雪天’。在进行编码后,增加了4个特征列,每一条记录中,只有一个特征列为1,其他3个特征均为0。
import pandas as pd
data=[[1,1,111,'阴天'],[2,77,222,'晴天'],[3,60,333,'雨天'],[3,60,333,'雪天']]
data = pd.DataFrame(data)
data.columns=['x1','x2','x3','天气状况']
# 将离散化数据转化为哑变量矩阵
res_dum = pd.get_dummies(data,prefix='天气状况',prefix_sep=':')
print(res_dum)
'''Out:
x1 x2 x3 天气状况:晴天 天气状况:阴天 天气状况:雨天 天气状况:雪天
0 1 1 111 0 1 0 0
1 2 77 222 1 0 0 0
2 3 60 333 0 0 1 0
3 3 60 333 0 0 0 1
'''