特征工程(Feature Engineering)是机器学习中不可或缺的一部分,在机器学习领域中,也扮演着一个十分重要的角色。
特征工程的目的:将数据转换为更好的能够表示潜在问题的特征,应用在机器学习学习器中,可以更好的提高机器学习的性能。 基础方向,可以分为以下几点:
- 特征理解:我拿到的数据中,里面都有什么?
- 特征增强:清洗拿到的原始数据
- 特征构建:通过现有的数据和特征,我可以生成新的特征吗?
- 特征选择:选取对后续机器学习有用的特征,排除效果不好的属性
特征理解
特征工程的第一步。观察数据,理解数据,以及对数据进行简单的描述性统计。
数据的本质:
- 定量数据:本质上是数值,应该是用来衡量某种数量
- 定性数据:本质上是类别,应该是用来区别某种类别
但是有些数据是可以同时定量和定性的。例如,对于某个餐厅的评分(1~5分),这个评分虽然是数值,但是依然可以代表类别(1:不喜欢,2:一般,3:喜欢,4:特别喜欢,5:强烈推荐)。所以需要有一种更好的方法去理解数据,以便于区分定量数据和定性数据之间模糊的界限。
数据的4个等级:
定类等级,定序等级,定距等级,定比等级。
1.定类等级:
这个类型的数据只能够按照数据的名称进行分类,例如:人名,商品的类别等。这个等级的数据是无法进行大多数的数学操作的,例如加减乘除。因为在数学角度来看,没有“平均名称”,“平均工作”这类说法的。
但是,这一类数据可以进行简单的统计相关的操作,例如统计个数,分析比例。
"Talk is cheap, show me the code." ------ Linus Torvalds
做个小实验验证一下定类数据。
先看一下数据大概的列都有哪些。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use('fivethirtyeight')
# 导入选取的数据集
heart_data = pd.read_csv('E:\10_docs\02_Python_Practise\01_data\heart_2020_cleaned.csv')
# 查看前几行数据
heart_data.head(5)
复制代码
不难看出,红色方框所示的都是这个数据集的定类数据。
接下来选取 “AgeCategory” 年龄分类 ,“Asthma” 哮喘 进行查看。
# 查看年龄分类的数据分布
heart_data['AgeCategory'].value_counts()
复制代码
65-69 34151
60-64 33686
70-74 31065
55-59 29757
50-54 25382
80 or older 24153
45-49 21791
75-79 21482
18-24 21064
40-44 21006
35-39 20550
30-34 18753
25-29 16955
Name: AgeCategory, dtype: int64
可以看出,数据集中年龄在65-69这一群体人数最多。
因为定类数据可以计数,那么也可以绘制图表。
heart_data['AgeCategory'].value_counts().sort_values(ascending=False).plot(kind='bar')
复制代码
另外,也可以绘制饼状图查看数据占比。这次我们用“Asthma” 哮喘 进行查看。
heart_data['Asthma'].value_counts().sort_values(ascending=False).plot(kind='pie')
复制代码
2.定序等级
从上面的数据分类可以看出 “GenHealth”是一个定序等级的数据。因为它代表着健康程度的等级。接下来看一下这个字段都提供了哪些信息。
# 查看GenHealth的数据分布
heart_data['GenHealth'].value_counts()
复制代码
Very good 113858
Good 93129
Excellent 66842
Fair 34677
Poor 11289
Name: GenHealth, dtype: int64 那么这个数据集关于健康等级的划分就一目了然了。
查看柱状图以及饼状图:
heart_data['GenHealth'].value_counts().sort_values(ascending=False).plot(kind='bar')
复制代码
plt.figure(figsize=(10,10))
heart_data['GenHealth'].value_counts().sort_values(ascending=False).plot(kind='pie')
复制代码
也可以通过箱线图对数据进行描述:
heart_data['GenHealth'].value_counts().sort_values(ascending=False).plot(kind='box')
复制代码
p.s.箱线图的具体理解方式:箱线图可以看出横着的有5条线,上下两端分别为上边缘和下边缘;中间柱体的上下两端分别为上四分位数和下四分位数,箱体中间的横线为中位数。如果有异常值,将会在上下边缘外,以点的形式表示。
3.定距等级
这个级别的数据,较前两个等级的数据相比,可操作性更高了。
因为除了可以对它进行排序以外,定距数据还可以进行加减。如果数据的值可以求和求差,那么就可以引入更熟悉的概念了(算数平均值,标准差)。
这次我们用 “BMI” 身体质量指数观察。由于BMI的数据分布十分广泛,数值可以说是因人而异了,那么用这样的数据去画柱状图和饼状图显然不明智(数据项目太多,完全无法理解图标的含义)。那么对于定距数据,常用的可以用直方图去观察:
heart_data["BMI"].hist()
复制代码
通过describe()方法检查一下:
heart_data["BMI"].describe()
复制代码
count 319795.000000
mean 28.325399
std 6.356100
min 12.020000
25% 24.030000
50% 27.340000
75% 31.420000
max 94.850000
Name: BMI, dtype: float64
确认一下,均值在28左右,和直方图描述的很接近。
4.定比等级
定比等级是最高的数据等级,那么这一类数据的可操作性也是最强的。
但是现在使用的数据集有点牵强,勉强使用 “SleepTime”睡眠时长进行观察。
这一类数据除了继承定距等级可以进行加减计算外,还可以进行乘除计算。因为这一类数据有了一个“绝对零点”的概念。
例如:睡眠时间8小时是睡眠时间5小时的1.6倍。
因为存在0这个概念,这种比较还是有意义的。
那么接下来观察一下不同年龄段的睡眠时长的情况:
fig = plt.figure(figsize=(15,15))
ax = fig.gca()
heart_data.groupby("AgeCategory")[['SleepTime']].mean().sort_values('SleepTime',ascending=False).plot.bar(stacked=False, ax=ax, color='darkorange')
ax.set_title("Average sleep duration by age")
复制代码
总结:
数据等级 | 属性 | 例子 | 描述性统计 | 图表 |
---|---|---|---|---|
定类 | 离散无序 | True/False人名 | 频率/占比众数 | 条形图/饼状图 |
定序 | 有序类别可比较 | 评分等级李克特量表 | 频数/众数/中位数/百分位数 | 条形图/饼状图/茎叶图 |
定距 | 数值差别具有意义 | 摄氏度 | 频数/众数/中位数/均值/方差 | 条形图/饼状图/茎叶图/箱线图/直方图 |
定比 | 连续,数据存在绝对零点 | 金钱/重量等 | 均值/方差 | 箱线图/直方图 |