数据预处理与特征工程

本文详细介绍了数据预处理与特征工程的重要方法,包括缺失值处理、特征变化、特征增加与删减。通过实例展示了如何使用均值、中位数填充缺失值,利用线性回归预测缺失数据,以及处理离群值。同时,讨论了标准化、纠偏、特征工程中的共线性问题,以及如何通过主成分分析和特征筛选降低维度。这些步骤旨在提高模型的训练表现和泛化能力。
摘要由CSDN通过智能技术生成

数据预处理与特征工程

概念: 数据预处理与特征工程泛指对训练数据集进行特征增加、删除、变换的方法

目标: 通过对训练数据的处理变换,提高模型的训练表现和泛化能力。

类别:

  • 特征变化:预处理、标准化、纠偏
  • 特征增加与删减:特征降维与变量扩展

模型评价体系:

  • 模型:规律和经验
  • 学习:从数据中总结规律的过程
  • 误差:衡量模型准确性的指标
  • 训练集:训练模型的数据集
  • 验证集:测试机器学习模型繁华能力的数据集
  • 应用数据:模型实际应用场景中的特征集

数据预处理

缺失值:样本的部分特征信息缺失

处理方式:

  • 删除:缺失样本量非常大,删除整个变量,如果缺失了较少,且难以填充,则删除缺失值
  • 填充:缺失量小于10%,根据缺失变量的数据分布采取均值或中位数进行填充
  • 模拟或预测缺失样本:根据样本的数据分布,生成随机值填充;使用与缺失值相比相关性非常高的特征,建立模型,预测缺失值
数据预处理演示

用到的数据集:https://download.csdn.net/download/d1240673769/20910882

import pandas as pd
import matplotlib.pyplot as plt
# 样例数据读取
df = pd.read_excel('realestate_sample.xlsx')
# 数据集基本情况查看
print(df.shape)
print(df.dtypes)
df.head()

在这里插入图片描述
查看数据样本中的缺失情况

# 缺失值处理
# 查看数据样本中的缺失情况
print(df.isnull().sum())

在这里插入图片描述
查看房价分布

# 逐一查看特征,进行缺失值填充
df['average_price'].hist()
plt.show()

在这里插入图片描述
类似正态分布,选择均值填充

# 选择均值填充
price_mean = df['average_price'].mean()
print(price_mean)
# 使用均值进行缺失值填充
df.loc[df['average_price'].isna(),'average_price'] = price_mean
print(df.isnull().sum())

在这里插入图片描述
查看面积数据分布情况

df['area'].hist()
plt.show()

在这里插入图片描述
偏态分布,适合中位数填充

# 选择中位数填充
area_median = df['area'].median()
print(area_median)
# 使用均值进行缺失值填充
df.loc[df['area'].isna(),'area'] = area_median
print(df.isnull().sum())

在这里插入图片描述
查看’daypop’,‘nightpop’,'night20-39’三个特征的相关性系数

# 查看相关性系数
print(df[['daypop','nightpop','night20-39']].corr())

在这里插入图片描述
日间人口和夜间人口相关性较高,因此选择用日间人口数据来预测夜间人口

# 训练线性回归模型对夜间人口进行填补
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score
train = df.copy().loc[~df['nightpop'].isna(),['daypop','nightpop']].reset_index(drop=True)

x = train[['daypop']]
y = train[['nightpop']]
model = LinearRegression()
model.fit(x,y)
print(f'R squared is: {r2_score(y, x)}')

在这里插入图片描述

#  填充夜间人口缺失数据
df.loc[df['nightpop'].isna(),['nightpop']] = model.predict(df.loc[df['nightpop'].isna(),['daypop']])
print(df.isnull().sum())

在这里插入图片描述
特殊类型的缺失值

# 特殊类型的缺失值
print(df.complete_year.value_counts())  # 房屋建成年代字段中存在未知

在这里插入图片描述

# 做切片删除缺失房龄的样本
df = df[df.complete_year!='未知'].reset_index(drop=True)

离群值:远离数据主要部分的样本(极大值或极小值)

处理方式:

  • 删除:直接删除离群样本
  • 填充样本:使用 box-plot 定义变量的数值上下界,以上界填充极大值,以下界填充最小值

查看房价的离群情况

# 查看房价的离群情况
df['average_price'].hist()
plt.show()
df[['average_price']].boxplot()
plt.show()

在这里插入图片描述
根据箱线图的上下限进行异常值的填充

# 根据箱线图的上下限进行异常值的填充
def boxplot_fill(col):
    # 计算iqr:数据四分之三分位值与四分之一分位值的差
    iqr = col.quantile(0.75)-col.quantile(0.25)
    # 根据iqr计算异常值判断阈值
    u_th = col.quantile(0.75) + 1.5*iqr # 上界
    l_th = col.quantile(0.25) - 1.5*iqr # 下界
    
    # 定义转换函数:如果数字大于上界则用上界值填充,小于下界则用下界值填充。
    def box_trans(x):
        if x > u_th:
            return u_th
        elif x < l_th:
            return l_th
        else:
            return x
    return col.map(box_trans)

# 填充效果查看
boxplot_fill(df['average_price']).hist()
# 进行赋值
df['average_price'] = boxplot_fill(df['average_price'])
plt.show()

在这里插入图片描述

标准化

标准化目的:

  • 去除数据量纲的影响
  • 提高模型的解释性
  • 加快模型收敛速度

标准化的方法:

  • 中心化:减去均值再除以标准差
  • 0-1标准化:减去最小值再除以最大值与最小值的差

sklearn 中标准化的方法

# sklearn 中标准化的方法
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler

# 以中心化为例讲解sklearn中标准化的使用方法
scaler = StandardScaler()
df['daypop'].hist()
plt.show()

trans_data = df.copy()[['daypop']]
scaler.fit(trans_data)
trans_data['daypop'] = scaler.transform(trans_data)
trans_data['daypop'].hist()
plt.show()

在这里插入图片描述
使用pipeline整合数据标准化与模型

# 使用pipeline整合数据标准化与模型
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

# 构建模型工作流
pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)

在这里插入图片描述

纠偏

  • 正态分布:数据呈现对称的钟型分布
  • 右偏态:样本大量集中在均值左边(均值偏到了右边)
  • 左偏态:样本大量集中在均值右边(均值偏到了左边)

处理方法:

  • 右偏态:常用对数函数处理
  • 左偏态:常用指数函数处理

通用变换方法:以降低数据的偏态系数为目标,使得数据分布更加接近正态分布的变换方法

  • yeo-johnson 变换:可以处理包含正数、负数和零的变量
  • box-cox 变换:只能处理数值皆为正数的变量

sklearn 中纠偏的方法

# sklearn 中纠偏的方法
from sklearn.preprocessing import PowerTransformer
# 参数讲解
# method = 'yeo-johnson' or 'box-cox’
# 使用pipeline进行纠偏过程的整合
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline

# 构建模型工作流
pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('pow_trans',PowerTransformer(method='yeo-johnson')),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)

特征工程

共线性

特征间共线性:

  • 两个或多个特征包含了相似的信息,其间存在强烈的相关关系

常用判断标准:

  • 两个或两个以上的特征间的相关性系数高于0.8

共线性的影响:

  • 降低运算效率
  • 降低一些模型的稳定性
  • 弱化一些模型的预测能力

处理方式:

  • 删除:一组相互共线的特征中只保留与y相关性最高的一个
  • 变换:对共线的两列特征进行求比值、求差值等计算
特征工程的演示
# 特征工程的演示
import pandas as pd
import matplotlib.pyplot as plt
# 样例数据读取
df = pd.read_excel('realestate_sample_preprocessed.xlsx')

# 数据集基本情况查看
print(df.shape)
print(df.dtypes)
print(df.isnull().sum())
df.head()

在这里插入图片描述
变量相关性矩阵

# 变量相关性矩阵
correlation_table = df.drop(columns='id').corr()
print(correlation_table)

在这里插入图片描述
对相关性矩阵进行可视化

# 对相关性矩阵进行可视化
import seaborn as sns
# 绘制相关性矩阵热力图
sns.heatmap(correlation_table)
plt.show()

在这里插入图片描述
查看共线的日间、夜间、夜间20-39岁人口与房价的关系

# 查看共线的日间、夜间、夜间20-39岁人口与房价的关系
print(df[['average_price','daypop','nightpop','night20-39']].corr())

在这里插入图片描述
根据共线性矩阵,保留与房价相关性最高的日间人口,将夜间人口和20-39岁夜间人口进行比例处理

# 根据共线性矩阵,保留与房价相关性最高的日间人口,将夜间人口和20-39岁夜间人口进行比例处理
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)

在这里插入图片描述

数据降维与特征提取

处理目的:

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

处理方法:

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

查看样例数据特征表

# 查看样例数据特征表
df.columns

在这里插入图片描述
查看主成分对于数据的解释方差百分比

# 载入sklearn里的pca模块
from sklearn.decomposition import PCA

pca = PCA(n_components=5) # 降维到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())

在这里插入图片描述

# 查看保留主成分数量与方差解释百分比
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()}')

在这里插入图片描述
常用判断标准:保留数据的解释方差累计百分比达到95%的所有特征

使用pipeline整合数据标准化、主成分分析与模型

# 使用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)

在这里插入图片描述
使用模型进行特征筛选

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

在这里插入图片描述
构建模型工作流

# 构建模型工作流
pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('lasso_select',SelectFromModel(lasso_lm)),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)

在这里插入图片描述

特征扩展

处理目的:

  • 解决模型欠拟合
  • 捕捉自变量与因变量之间的非线性关系

常见处理方法:多项式拓展

  1. 假设数据集中包含自变量a、b
  2. 如果对自变量做二项式扩展
  3. 自变量集从两个变量扩展为5个变量(a、b、axa、bxb、axb)
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) #进行2级扩展

# 训练筛选器
new_x = polynomy.fit_transform(x)
print(new_x.shape[1])  # 处理之后的特征个数

在这里插入图片描述
构建模型工作流

# 构建模型工作流
pipe_lm = Pipeline([
        ('sc',StandardScaler()),
        ('poly_trans',PolynomialFeatures(degree=2)),
        ('lm_regr',LinearRegression())
        ])
print(pipe_lm)
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jepson2017

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

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

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

打赏作者

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

抵扣说明:

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

余额充值