特征工程_特征理解

511 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

特征工程(Feature Engineering)是机器学习中不可或缺的一部分,在机器学习领域中,也扮演着一个十分重要的角色。

特征工程的目的:将数据转换为更好的能够表示潜在问题的特征,应用在机器学习学习器中,可以更好的提高机器学习的性能。 基础方向,可以分为以下几点:

  1. 特征理解:我拿到的数据中,里面都有什么?
  2. 特征增强:清洗拿到的原始数据
  3. 特征构建:通过现有的数据和特征,我可以生成新的特征吗?
  4. 特征选择:选取对后续机器学习有用的特征,排除效果不好的属性

特征理解

特征工程的第一步。观察数据,理解数据,以及对数据进行简单的描述性统计。

数据的本质:

  - 定量数据:本质上是数值,应该是用来衡量某种数量

  - 定性数据:本质上是类别,应该是用来区别某种类别

但是有些数据是可以同时定量和定性的。例如,对于某个餐厅的评分(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)

心脏病数据集截图.png

不难看出,红色方框所示的都是这个数据集的定类数据。

接下来选取 “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')

output.png

另外,也可以绘制饼状图查看数据占比。这次我们用“Asthma” 哮喘 进行查看。

heart_data['Asthma'].value_counts().sort_values(ascending=False).plot(kind='pie')

output1.png

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')

健康情况柱状图.png

plt.figure(figsize=(10,10))
heart_data['GenHealth'].value_counts().sort_values(ascending=False).plot(kind='pie')

健康状况饼状图.png

也可以通过箱线图对数据进行描述:

heart_data['GenHealth'].value_counts().sort_values(ascending=False).plot(kind='box')

健康等级箱线图.png

p.s.箱线图的具体理解方式:箱线图可以看出横着的有5条线,上下两端分别为上边缘和下边缘;中间柱体的上下两端分别为上四分位数和下四分位数,箱体中间的横线为中位数。如果有异常值,将会在上下边缘外,以点的形式表示。

3.定距等级

这个级别的数据,较前两个等级的数据相比,可操作性更高了。

因为除了可以对它进行排序以外,定距数据还可以进行加减。如果数据的值可以求和求差,那么就可以引入更熟悉的概念了(算数平均值,标准差)。

这次我们用 “BMI” 身体质量指数观察。由于BMI的数据分布十分广泛,数值可以说是因人而异了,那么用这样的数据去画柱状图和饼状图显然不明智(数据项目太多,完全无法理解图标的含义)。那么对于定距数据,常用的可以用直方图去观察:

heart_data["BMI"].hist()

BMI直方图.png

通过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")

不同年龄的睡眠时间.png

总结:

数据等级属性例子描述性统计图表
定类离散无序True/False人名频率/占比众数条形图/饼状图
定序有序类别可比较评分等级李克特量表频数/众数/中位数/百分位数条形图/饼状图/茎叶图
定距数值差别具有意义摄氏度频数/众数/中位数/均值/方差条形图/饼状图/茎叶图/箱线图/直方图
定比连续,数据存在绝对零点金钱/重量等均值/方差箱线图/直方图