特征工程之特征关联
- 2019 年 10 月 6 日
- 笔记
特征工程之特征关联
0.说在前面
1.皮尔逊
2.pointbiserialr系数
3.Spearman's 系数
4.总结
5.作者的话
0.说在前面
昨天学习了seaborn
绘制图形,以及单变量与多变量之间的绘图,那么今天从统计学角度实战分析在处理特征工程过程中所涉及的三个相关系数(具体的三个系数数学推导,在后续更新)。
为了更好的便于大家的交流,先建立一个微信总群,二维码在文章最后放出!
【关键字】
- 相关系数
- 微信总群
1.皮尔逊
皮尔逊相关系数:Pearson correlation coefficient,通常用r或是ρ表示,是用来度量两个变量X和Y之间的相互关系的,取值范围在[-1,+1]之间。Pearson相关系数(相关系数的绝对值越大,相关性越强:相关系数越接近于1或-1,相关度越强,相关系数越接近于0,相关度越弱)。
下面我们来实战一下如何求Pearson系数!
【导包】
import warnings warnings.filterwarnings('ignore')#忽略一些警告 import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # jupter内部使用 %matplotlib inline
【数据】
从网上选取如下几行数据,每列的字段意思如下:
- 第一列“销售日期”(date)
- 第二列“销售价格”(price):房屋交易价格,单位为美元,是目标预测值;
- 第三列“卧室数”(bedrooms):房屋中的卧室数目;
- 第四列“浴室数”(bathrooms):房屋中的浴室数目;
- 第五列“房屋面积”(sqft_living):房屋里的生活面积;
- 第六列“停车面积”(sqft_lot):停车坪的面积;
- 第七列“楼层数”(floors):房屋的楼层数;
- 第八列“房屋评分”(grade):King County房屋评分系统对房屋的总体评分;
- 第九列“建筑面积”(sqft_above):除了地下室之外的房屋建筑面积;
- 第十列“地下室面积”(sqft_basement):地下室的面积;
- 第十一列“建筑年份”(yr_built):房屋建成的年份;
- 第十二列“修复年份”(yr_renovated):房屋上次修复的年份;
- 第十三列"纬度"(lat):房屋所在纬度;
- 第十四列“经度”(long):房屋所在经度。

【读取数据】
由于原数据没有列字段名,那么我们这里通过pandas读取原数据,在name处设置每列的参数,那么我们便可以对每一列方便的操作!
# 读取数据 columns = ['date', 'price', 'bedrooms', 'bathrooms', 'sqft_living', 'sqft_lot', 'floors', 'grade', 'sqft_above', 'sqft_basement', 'yr_built', 'yr_renovated', 'lat', 'long'] kc_train = pd.read_csv('./data/kc_train.csv', names=columns)

在这里,我们看到了每一列的数据直方分布图,为什么要绘制图?
我们在这里绘制图形的目的是,查看数据的离散程度,判定数据是连续性,还是离散的,还是二分类等。
在这里吧,我们可以注意到以下几种特征都是连续变量:
lat long sqft_above sqft_basement sqft_living sqft_lot yr_built yr_renovated
针对连续变量,我们在做特征工程时,需要做的便是皮尔逊系数分析!
【皮尔逊系数】
- 封装上述的连续变量为list数组
- 遍历循环,绘制每个散点图
continuous_cols = ['sqft_living', 'sqft_lot', 'sqft_above', 'sqft_basement', 'yr_built', 'yr_renovated', 'lat', 'long'] # alpa表示散点透明度,size表示图的大小 for col in continuous_cols: sns.jointplot(x=col, y="price", data=kc_train, alpha=0.3, size=5)

由于运行的结果众多,这里拿一个说明,如上图所示,pearsonr系数为0.7,说明与price的关联程度很强,那么在提取特征时,就得着重关注!
【pearson系数排序】
首先我们来获取关联矩阵,从矩阵中抽取相关信息
这里使用corr()
方法,该方法有三个系数可以选择,分别是'pearson’, ‘kendall’, ‘spearman’
。默认为pearson
plt.figure(figsize=(12,6)) # kc_train.corr()打印的是所有的列之间的一个对称矩阵相关关系 # method : {‘pearson’, ‘kendall’, ‘spearman’} kc_train.corr()

从大到小排序提取出上述定义的continuous_cols相关列与price的关联程度
# 从大到小排序提取出上述定义的continuous_cols相关列与price的关联程度 # continuous_cols前面定义了,看前面,提取与price行,特定v列的数据,并降序排序 degree_data = kc_train.corr()['price'][continuous_cols].sort_values(ascending=False) degree_data.plot.barh(figsize=(12,6),title='Variable Correlation with Price')

到这里,连续数据关联程度分析完毕!
2.pointbiserialr系数
我们现在回头看一下yr_renovated,sqft_basement,发现有很多的0数据,那么我们可以考虑将这两列建立二分类数据,分别代表的是是否翻新,是否有地下室。
【数据转化】
0数据不动,非0为1
kc_train['basement_present'] = kc_train['sqft_basement'].apply(lambda x: 1 if x > 0 else 0) kc_train['renovated'] = kc_train['yr_renovated'].apply(lambda x: 1 if x > 0 else 0)
对于上面构建的sqft_basement、yr_renovated都是属于分类变量(categorical variable),我们可以使用点二列相关系数来计算两个变量之间的关系!
【两列相关系数】
# 二列相关系数来计算两个变量之间的关系 from scipy.stats import pointbiserialr # 绘制箱形图 plt.figure(figsize=(12, 4)) sns.boxplot(y='renovated', x='price', data=kc_train, orient='h') plt.show() # 计算点二列相关系数 r, p = pointbiserialr(kc_train['renovated'], kc_train['price']) print ('renovated 与 price 的点二列相关系数中 r = %s,p = %s' %(r, p)) r, p = pointbiserialr(kc_train['basement_present'], kc_train['price']) print ('basement_present 与 price 的点二列相关系数中 r = %s,p = %s' %(r, p))

可以看出来:
- 没有翻新过的箱形图比较窄,这表明整体而言这组屋价非常接近
- 有无翻新对于屋价高低没有太大的影响,一般而言翻新后屋价可能会高一点
- renovated、basement_present和price变量之间的相关性都较小
3.Spearman's 系数
各个顺序变量(ordinal variable)和price之间的关系,可以用斯皮尔曼等级相关系数(Spearman's rank-order correlation)来计算相关性。
顺序变量可以理解为等级变量
对于上述几个变量分析,我们知道顺序变量为bedrooms,bathrooms,grade!
plt.figure(figsize=(12, 10)) plt.subplot(311) sns.boxplot(y='bedrooms', x='price', data=kc_train, orient='h') plt.subplot(312) sns.boxplot(y='bathrooms', x='price', data=kc_train, orient='h') plt.subplot(313) sns.boxplot(y='grade', x='price', data=kc_train, orient='h') plt.show()

from scipy.stats import spearmanr r, p = spearmanr(kc_train['floors'], kc_train['price']) print ('floors 和 price 斯皮尔曼相关系数为 %s,其中 p = %s' %(r,p)) r, p = spearmanr(kc_train['bedrooms'], kc_train['price']) print ('bedrooms 和 price 斯皮尔曼相关系数为 %s,其中 p = %s' %(r,p)) r, p = spearmanr(kc_train['bathrooms'], kc_train['price']) print ('bathrooms 和 price 斯皮尔曼相关系数为 %s,其中 p = %s' %(r,p)) r, p = spearmanr(kc_train['grade'], kc_train['price']) print ('grade 和 price 斯皮尔曼相关系数为 %s,其中 p = %s' %(r,p))
输出
floors 和 price 斯皮尔曼相关系数为 0.3127190036471108,其中 p = 9.586333125228778e-226 bedrooms 和 price 斯皮尔曼相关系数为 0.3458697748314727,其中 p = 5.6801269872902106e-279 bathrooms 和 price 斯皮尔曼相关系数为 0.5012034892956143,其中 p = 0.0 grade 和 price 斯皮尔曼相关系数为 0.6603554146361819,其中 p = 0.0
4.总结
结论1:
- 连续变量中sqft_living、sqft_above、sqft_basement与price之间存在极强的相关关系
- 二元变量basement_present、renovated与price之间存在一定的相关关系,但是关联度较小
- 几个顺序变量(floors、bedrooms、bathrooms、grade)都与price之间存在相关关系
结论2:
首先拿到数据看看是什么类型的数据,满足哪种相关的条件
Pearson相关条件:
1.x y都是连续变量
2.双变量正态分布
3.各观测值相互独立,并且根据因变量y和自变量x所做的散点图要服从线性趋势。
Spearman相关条件:
1.xy不服从双变量正态分布
2.总体分布类型未知
3.数据本身有不确定值
4.等级资料。
Pearson Vs Spearman
1.连续数据,正态分布,线性关系,用pearson相关系数是最恰当,当然用spearman相关系数也可以,就是效率没有pearson相关系数高。
2.上述任一条件不满足,就用spearman相关系数,不能用pearson相关系数。
3.两个定序测量数据之间也用spearman相关系数,不能用pearson相关系数。
pointbiserialr相关条件:
数据必须是二分类!
5.作者的话
最后,您如果觉得本公众号对您有帮助,欢迎您多多支持,转发,谢谢!
更多内容,请关注本公众号机器学习系列!