【机器学习(7)】特征工程:共线性、降维、扩展

1. 共线性

1) 特征间共线性:
        两个或多个特征包含了相似的信息,期间存在强烈的相关关系

2) 常用判断标准:
        两个或两个以上的特征间的相关性系数高于0.8

3) 共线性的影响:
        降低运算效率
        降低一些模型的稳定性
        弱化一些模型的预测能力

4) 处理方式:
        删除:一组相互共线的特征中只保留与y相关性最高的一个
        变换:对共线的两列特征进行求比值、求差值等计算

1.1 数据导入及查看

1)查看数据量

# 特征工程的演示
import pandas as pd
import matplotlib.pyplot as plt
import os
os.chdir(r'C:\Users\86177\Desktop')
# 样例数据读取
df = pd.read_excel('realestate_sample_preprocessed.xlsx')
# 数据集基本情况查看
print(df.shape)

–> 输出的结果为:(数据已经由原来的1000条变成了898条)

(898, 10)

2) 查看各字段数据类型

print(df.dtypes)

–> 输出的结果为:

id                 int64
complete_year      int64
average_price    float64
area             float64
daypop           float64
nightpop         float64
night20-39       float64
sub_kde          float64
bus_kde          float64
kind_kde         float64
dtype: object

3) 查看数据缺失值情况

id               0
complete_year    0
average_price    0
area             0
daypop           0
nightpop         0
night20-39       0
sub_kde          0
bus_kde          0
kind_kde         0
dtype: int64

4) 查看基本数据

print(df.head())

–> 输出的结果为:

		id	complete_year average_price  area	  daypop	 nightpop	night20-39	  sub_kde		 bus_kde		kind_kde
0	107000909879	2008	33464.0		25.70	119.127998	150.060287	53.842050	5.241426e-11	0.279422	7.210007e-11
1	107000908575	1996	38766.0		26.57	119.127998	150.060287	53.842050	5.241426e-11	0.279422	7.210007e-11
2	107000846227	2005	33852.0		28.95	436.765809	376.523010	183.301881	1.523092e-24	0.231135	2.922984e-01
3	107000676489	1995	39868.0		30.10	247.545324	385.412857	142.819971	4.370519e-11	0.321443	2.401811e-01
4	107000676873	1995	42858.0		30.10	247.545324	385.412857	142.819971	4.370519e-11	0.321443	2.401811e-01
1.2 变量相关性矩阵

既然要判断共线性,就需要查看各变量之间的相关性系数

correlation_table = df.drop(columns='id').corr()
print(correlation_table)

–> 输出的结果为:


			complete_year	average_price	area	daypop		nightpop	night20-39	sub_kde		bus_kde		kind_kde
complete_year	1.000000	0.203111	0.317025	-0.103519	-0.110359	-0.078844	-0.007865	-0.424366	-0.198453
average_price	0.203111	1.000000	0.128352	0.113801	0.084533	0.111855	0.312138	0.091660	0.256919
area			0.317025	0.128352	1.000000	-0.054506	-0.060293	-0.047174	0.350410	-0.199929	0.045079
daypop			-0.103519	0.113801	-0.054506	1.000000	0.946124	0.935621	0.015707	0.486652	0.139208
nightpop		-0.110359	0.084533	-0.060293	0.946124	1.000000	0.982556	-0.008679	0.468839	0.140402
night20-39		-0.078844	0.111855	-0.047174	0.935621	0.982556	1.000000	-0.012920	0.415522	0.141861
sub_kde			-0.007865	0.312138	0.350410	0.015707	-0.008679	-0.012920	1.000000	-0.090661	0.041546
bus_kde			-0.424366	0.091660	-0.199929	0.486652	0.468839	0.415522	-0.090661	1.000000	0.397623
kind_kde		-0.198453	0.256919	0.045079	0.139208	0.140402	0.141861	0.041546	0.397623	1.000000
1.3 相关性矩阵进行可视化

通过上表绘制相关性矩阵热力图

import seaborn as sns
sns.heatmap(correlation_table,cmap='OrRd')
plt.show()

–> 输出的结果为:(可以看出中间的几个特征变量的相关性特别的高,也就对应了上一篇博文中的可以采用daypop nightpop night20-39三个变量进行彼此缺失值的填充)
=,size_16,color_FFFFFF,t_70)

1.4 查看共线的变量与标签之间的关系
print(df[['average_price','daypop','nightpop','night20-39']].corr())

–> 输出的结果为:(从第一列可以看出,与标签数据相关性最高的是daypop特征)

               average_price    daypop  nightpop  night20-39
average_price       1.000000  0.113801  0.084533    0.111855
daypop              0.113801  1.000000  0.946124    0.935621
nightpop            0.084533  0.946124  1.000000    0.982556
night20-39          0.111855  0.935621  0.982556    1.000000
1.5 保留与标签相关性最高的特征变量,其余变量进行比例处理
def age_percent(row):
    if row['nightpop'] == 0:
        return 0
    else:
        return row['night20-39']/row['nightpop']
df['per_a20_39'] = df.apply(age_percent,axis=1)
df = df.drop(columns=['nightpop','night20-39'])
correlation_table = df.corr()
sns.heatmap(correlation_table)

–> 输出的结果为:(注意处理的时候,可能含有0在分母上)
在这里插入图片描述

2. 数据降维与特征提取

1) 处理目的:
        降低不相关特征对于模型准确性的干扰
        降低模型复杂度,提高模型泛化能力
        减少建模特征,提高模型训练与预测速度

2) 处理方法:
        基于数据理解,直接删除
        使用主成分分析法(PCA)对特征进行变换
        使用机器学习模型对特征进行筛选

2.1 查看特征参数
print(df.columns)

–> 输出的结果为:(一共有的是7个特征)

Index(['id', 'complete_year', 'average_price', 'area', 'daypop', 'sub_kde',
       'bus_kde', 'kind_kde', 'per_a20_39'],
      dtype='object')
2.2 PCA主成分分析

主成分对于数据的解释方差百分比,数值越大,说明选取的主成分对于数据特征的提取的程度就越高,下面假设选取其中的5个特征数据,进行判断

from sklearn.decomposition import PCA
pca = PCA(n_components=5)
x = df[['complete_year','area', 'daypop', 'sub_kde',
       'bus_kde', 'kind_kde', 'per_a20_39']]
# 使用x进行pca模型训练同时对x进行转换
x_transform = pca.fit_transform(x)
print(pca.explained_variance_ratio_.sum())

–> 输出的结果为:(这里只是尝试输入主成分为5,累计解释方差百分比已经达到了0.999,如何确定主成分的个数?)

0.9999999094429124

可以通过遍历的方式,把主成分的数量分别进行输入,然后查看一下累计解释方差百分比

for i in range(1,8):
    pca = PCA(n_components=i)
    x_transform = pca.fit_transform(x)
    print(f'components={i},explanined_variance={pca.explained_variance_ratio_.sum()}')

–> 输出的结果为:(对各个成分进行输出)

components=1,explanined_variance=0.9726544078736945
components=2,explanined_variance=0.999572122074863
components=3,explanined_variance=0.9999995768050572
components=4,explanined_variance=0.999999809994995
components=5,explanined_variance=0.9999999094429124
components=6,explanined_variance=0.999999987099206
components=7,explanined_variance=1.0000000000000002
2.3 提取主成分个数,进行Pipeline整合

主成分的个数是如何确定???

常用判断标准:保留数据的解释方差累计百分比达到95%的所有特征

# 使用pipeline整合数据标准化、主成分分析与模型
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
# 构建模型工作流
pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('pca',PCA(n_components=1)),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)

–> 输出的结果为:(构建工作流)

Pipeline(memory=None,
         steps=[('sc',
                 StandardScaler(copy=True, with_mean=True, with_std=True)),
                ('pca',
                 PCA(copy=True, iterated_power='auto', n_components=1,
                     random_state=None, svd_solver='auto', tol=0.0,
                     whiten=False)),
                ('lm_regr',
                 LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
                                  normalize=False))],
         verbose=False)
2.4 使用模型进行特征筛选,提取主成分(特征数据)

上面一部是确定了主成分的个数,这一部要完成的就是确定具体的主成分,也就是获得特征数据,之前讲到的惩罚模型Lasso,具有特征筛选的功能,这里就可以使用上

from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import Lasso
# 准备筛选数据
x = df[['complete_year','area', 'daypop', 'sub_kde',
       'bus_kde', 'kind_kde', 'per_a20_39']]
print(x.shape[1])
y = df[['average_price']]
# 定义筛选模型
lasso_lm = Lasso(alpha = 500)
# 定义特征筛选器
select_m = SelectFromModel(lasso_lm)
# 训练筛选器
select_m.fit(x,y)
# 运行筛选结果
print(select_m.transform(x).shape[1])

–> 输出的结果为:(输出显示,特征数量的变化7 -> 3)

7
3
2.5 进行Pipeline整合
pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('lasso_select',SelectFromModel(lasso_lm)),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)

–> 输出的结果为:

Pipeline(memory=None,
         steps=[('sc',
                 StandardScaler(copy=True, with_mean=True, with_std=True)),
                ('lasso_select',
                 SelectFromModel(estimator=Lasso(alpha=500, copy_X=True,
                                                 fit_intercept=True,
                                                 max_iter=1000, normalize=False,
                                                 positive=False,
                                                 precompute=False,
                                                 random_state=None,
                                                 selection='cyclic', tol=0.0001,
                                                 warm_start=False),
                                 max_features=None, norm_order=1, prefit=False,
                                 threshold=None)),
                ('lm_regr',
                 LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
                                  normalize=False))],
         verbose=False)

3. 特征扩展

1) 处理目的:
        解决模型欠拟合
        捕捉自变量与应变量之间的非线性关系

2) 常见处理方法,多项式拓展:
        假设数据集中包含自变量a、b
        如果对自变量做二项式扩展
        自变量集从两个变量扩展为5个变量(a、b、a×a、b×b、a×b)

有时候数据特征是有限的,可以通过特征扩展的方式进行扩充(针对欠拟合)

from sklearn.preprocessing import PolynomialFeatures
# 准备筛选数据
x = df[['complete_year','area', 'daypop', 'sub_kde',
       'bus_kde', 'kind_kde', 'per_a20_39']]
print(x.shape[1])
# 定义特征扩展模型并扩展特征
polynomy = PolynomialFeatures(degree=2)
# 训练筛选器
new_x = polynomy.fit_transform(x)
print(new_x.shape[1])

–> 输出的结果为:(特征向量从7个变成了36个,注意线性回归中,特征数量不可以超过样本数量)

7
36

整合Pipeline

pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('poly_trans',PolynomialFeatures(degree=2)),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)

–> 输出的结果为:(先标准化,然后特征扩展,接着是进行线性回归)

Pipeline(memory=None,
         steps=[('sc',
                 StandardScaler(copy=True, with_mean=True, with_std=True)),
                ('poly_trans',
                 PolynomialFeatures(degree=2, include_bias=True,
                                    interaction_only=False, order='C')),
                ('lm_regr',
                 LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
                                  normalize=False))],
         verbose=False)
  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lys_828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值