【机器学习】数据预处理-特征工程与特征选择

目录

一、特征工程

二、数据变换

1.变换

2.归一化

三、数据清洗

1.异常数据

2.数据清洗

四、特征选择

1.Filter过滤法

[2.Wrapper包裹法 ...](#2.Wrapper包裹法 ...)

[3.Embedded嵌入法 ...](#3.Embedded嵌入法 ...)

五、降维算法

1.SVD

2.PCA


一、特征工程

特征工程就是从原始数据提取特征的过程,这些特征可以很好地描述数据,并且利用特 征建立的模型在未知数据上的性能表现可以达到最优 (或者接近最佳性能)。特征工程一般包括特征使用、特征获取、特征处理、特征选择和特征监控。

特征工程的处理流程为首先去掉无用特征,接着去除冗余的特征,如共线特征,并利用存在的特征、转换特征、内容中的特征以及其他数据源生成新特征,然后对特征进行转换(数值化、类别转换、归一化等),最后对特征进行处理(异常值、最大值、最小值,缺失值等), 以符合模型的使用。 简单来说,特征工程的处理一般包括数据预处理、特征处理、特征选择等工作,而特征选择视情况而定,如果特征数量较多,则可以进行特征选择等操作。

主要任务:

数据清理(清洗):去掉数据中的噪声,纠正不一致。

数据集成:将多个数据源合并成一致的数据存储,构成完整的数据集,如数据仓库。

数据归约(消减):通过聚集、删除冗余属性或聚类等方法来压缩数据。

数据变换(转换):将一种格式的数据转换为另一格式的数据(如规范化)。

二、数据变换

1.变换

左偏偏态分布→(指数变换)→正态分布←(对数变换)←右偏偏态分布

2.归一化

(数据存在显著数量级差异的情况)

(1) 最小-最大规范化

也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 , 1]之间。

其中max为样本数据的最大值,min为样本数据的最小值,max-min为极差。

(2) 零-均值规范化

也叫标准差标准化,经过处理的数据的平均数为0,标准差为1。转化函数为∶

其中为原始数据的均值,为原始数据的标准差。

(3) 小数定标规范化

通过移动属性值的小数位数,将属性值映射到[-1 , 1]之间,移动的小数位数取决于属性值绝对值的最大值。转化函数为︰

三、数据清洗

1.异常数据

噪声数据:数据中存在着错误或异常(偏离期望值)

  • 收集数据的时候难以得到精确的数据,收集数据的设备可能出现故障;
  • 数据输入时可能出现错误;
  • 数据传输过程中可能出现错误;
  • 存储介质有可能出现损坏等。

缺失值:由于实际系统设计时存在的缺陷以及使用过程中的一些人为因素,数据记录可能会出现数据值的丢失或不确定。

2.数据清洗

数据清洗主要是删除原始数据集中的无关数据、重复数据,平滑噪声数据,处理缺失值、异常值等。

(1) 缺失值处理

删除记录、数据插补和不处理

|-------------|------------------------------------------------------|
| 插补方法 | 方法描述 |
| 均值/中位数/众数插补 | 根据属性值的类型,用该属性取值的平均数/中位数/众数进行插补 |
| 使用固定值 | 将缺失的属性值用一个常量替换 |
| 最近临插补 | 在记录中找到与缺失样本最接近的样本的该属性值插补 |
| 回归方法 | 对带有缺失值的变量,根据已有数据和与其有关的其他变量(因变量)的数据建立拟合模型来预测缺失的属性值 |
| 插值法 | 插值法是利用已知点建立合适的插值函数f(x),未知值由对应点xi 求出的函数值f(xi)近似代替 |

欧几里得距离

(Euclidean Distance)又称直线距离。

令i=()和j=()是两个被p个数值属性描述的对象。对象i和j之间的欧几里得距离为:

拉格朗日插值法

能给出一条最低次数函数穿过样本点。

①求已知的n个点对(x1 ,y1 ), (x2 ,y2 )...(xn ,yn)的基函数

②求已知的n个点对(x1 ,y1 ), (x2 ,y2 )...(xn ,yn)的插值多项式

③将缺失的函数值对应的点代入插值多项式得到缺失值的近似值L(x)

牛顿插值法

① 求已知的n个点对(x1 ,y1 ), (x2 ,y2 )...(xn ,yn)的所有阶差商公式

② 联立以上差商公式建立插值多项式f(x)

③ 将缺失的函数值对应的点代入插值多项式得到缺失值的近似值f(x)

(2) 异常值处理

|------------|--------------------------|
| 异常值处理方法 | 方法描述 |
| 删除含有异常值的记录 | 直接将含有异常值的记录删除 |
| 视为缺失值 | 将异常值视为缺失值,利用缺失值处理的方法进行处理 |
| 平均值修正 | 可用前后两个观测值的平均值修正该异常值 |
| 不处理 | 直接在具有异常值的数据集上进行挖掘建模 |

原则

若数据服从正态分布,则异常值被定义为一组结果值中与平均值的偏差超过三倍标准差的值。即在正态分布的假设下,距离平均值三倍σ之外的值出现的概率很小,因此可认为是异常值。

python 复制代码
import pandas as pd  
data_filepath = 'data.xls'  
data = pd.read_excel(data_filepath)  #导入数据表
data['销量1'] = data['销量']  
l_fence = data['销量1'].mean() - 3*data['销量1'].std()#建立下界  
u_fence = data['销量1'].mean() + 3*data['销量1'].std()#建立上界  
#将小于下界和大于上界的值放入  
value_l = data['销量1'][data['销量1'] < l_fence]  
value_u = data['销量1'][data['销量1'] > u_fence]  
#找到对应异常值的索引  
list_lindex = data[ '销量1'][data[ '销量1'] < l_fence].index.tolist()  
list_uindex = data[ '销量1'][data[ '销量1'] > u_fence].index.tolist()  
#对异常值赋空  
data['销量1'][(data['销量1']< l_fence)|(data['销量1'] > u_fence)] = None  
data['销量2'] = data['销量1']  
#对处于异常值列表里的元素分上下界赋值  
for i in list_lindex:  
    data['销量2'][i] = l_fence  
for i in list_uindex:  
    data['销量2'][i] = u_fence  
print(data['销量2'].isnull().sum())  
#空值因为无法比较 所以单独将其赋为平均值  
data['销量2'] = data['销量2'].fillna(data[ '销量2' ].mean())  
print(data['销量2'].isnull().sum())  
#导出数据表  
outputfile='outdata.xlsx'  
data.to_excel(outputfile)  
箱线图

中横线:中位数

IQR:75%分位数(下四分位数)(Q3)-25%分位数(上四分位数)(Q1)

最小观察值(下边缘)= Q1 -- 1.5 IQR

最大观察值(上边缘)= Q3 + 1.5 IQR

python 复制代码
sta = data['销量'].describe()  
iqr = sta.loc['iqr'] = sta.loc['75%'] - sta.loc['25%']  
l_fence = sta.loc['l_fence']=sta.loc['25%']-1.5*sta.loc['iqr']  
u_fence = sta.loc['u_fence']=sta.loc['75%']+1.5*sta.loc['iqr']  
#范围比3σ原则收紧  

四、特征选择

1.Filter过滤法

按照发散性或者相关性对各个特征进行评分,通过设定阒值或者待选择阈的个数来选择特征。过滤方法通常用作预处理步骤,特征选择完全独立于任何机器学习算法。它是根据各种统计检验中的分数以及相关性的各项指标来选择特征。

  • 过程:全部特征→最佳特征子集→算法→模型评估
  • 主要对象:需要遍历特征或升维的算法
  • 主要目的:在维持算法表现的前提下降低计算成本

|------|---------------------------------|-----------------------------------------------|
| | 阈值很小 被过滤掉得特征比较少 | 阈值比较大 被过滤掉的特征有很多 |
| 模型表现 | 不会有太大影响 | 可能变更好,代表被滤掉的特征大部分是噪音 也可能变糟糕,代表被滤掉的特征中很多都是有效特征 |
| 运行时间 | 可能降低模型的运行时间 当方差很小特征不多时对模型没有太大影响 | 一定能够降低模型的运行时间 算法在遍历特征时的计算越复杂,运行时间下降得越多 |

python 复制代码
import pandas as pd  
data = pd.read_csv(r"data.csv")#导入数据  
X = data.iloc[:,1:]  
y = data.iloc[:,0]  
from sklearn.feature_selection import VarianceThreshold  
X_var0 = VairanceThreshold().fit_transform(X)  
#实例化 不填参数默认方差为0 获取删除不合格特征之后的新特征矩阵  
X_var0.shape#(42000,708) #707个特征  
import numpy as np  
#X.var()每一列的方差  
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X)  
X.var().values#查看方差的值  
np.median(X.var().values)#查看具体构造  
X_fsvar.shape#(42000,392) #筛选之后剩余391个  
#若特征是伯努利随机变量,假设p=0.8,即二分类特征中某种分类占到80%以上的时候删除特征  
X_bvar = VarianceThreshold(.8*(1 -.8)).fit_transform(X)  
X_bvar.shape#(42000,685) 

最近邻算法KNN,单棵决策树,支持向量机 SVM,神经网络,回归算法,都需要遍历特征或升维来进行运算,所以他们本身的运算量就很大,需要的时间就很长,因此方差过滤这样的特征选择对他们来说就尤为重要。

python 复制代码
#KNN vs 随机森林在不同方差过滤效果下的对比  
from sklearn.ensemble import RandomForestClassifier as RFC  
from sklearn.neighbors import KNeighborsClassifier as KNN  
from sklearn.model_selection import cross_val_score  
import numpy as np  
X = data.iloc[:,1:]  
y = data.iloc[:,0]  
#KNN  
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X)  
cross_val_score(KNN(),X,y,cv=5).mean()  
#0.965857142857143  
cross_val_score(KNN(),X_fsvar,y,cv=5).mean()  
#0.966  
#随机森林(结果有微弱上升 时间也有提升)  
cross_val_score(RFC(n_estimators=10,random_state=0),X,y,cv=5).mean()  
#0.9373571428571429  
cross_val_score(RFC(n_estimators=10,random_state=0),X_fsvar,y,cv=5).mean()  
#0.9390476190476191  

(1) 卡方过滤 ...

python 复制代码
from sklearn.ensemble import RandomForestClassifier as RFC  
from sklearn.model_selection import cross_val_score  
from sklearn.feature_selection import SelectKBest  
from sklearn.feature_selection import chi2  
X_fschi = SelectKBest(chi2,k=300).fit_transform(X_fsvar,y)  
X_fschi.shape#(42000,300)  
cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()  

(2) F检验 ...

(3) 互信息法 ...

基于序列向前选择:SFS (Sequential Forward Selection)

2.Wrapper包裹法 ...

根据目标函数(通常是预测效果评分)每次选择若干特征,或者排除若干特征。

过程:全部特征 →(获取特征子集⇆算法)(算法完成最佳特征选择)→ 模型评估指标

启发式搜索:LVM (Las Vegas Wrapper)

递归式特征消除:RFE (Recursive Feature Elimination)

3.Embedded嵌入法 ...

使用机器学习的某些算法和模型进行训练,得到各个特征的权值系数,并根据系数从大到小选择特征。

过程:全部特征→(特征子集⇆算法+模型评估)(算法依赖于模型评估完成特征子集选择)

LASSO

五、降维算法

sklearn将降维流程拆成了两部分:一部分是计算特征空间V,由奇异值分解完成,另一部分是映射数据和求解新特征矩阵,由主成分分析完成,实现了用SVD的性质减少计算量,却让信息量的评估指标是方差,具体流程如下图:

1.SVD

奇异值分解Single Value Decomposition

线性代数中另一种非常重要的矩阵分解算法(还有一个是特征值分解,但特征值分解只适用于n阶方阵,并且不是所有的n阶方阵都存在特征分解,而SVD的应用更广,它适用于任意给定的m×n阶实数矩阵A。)除了适用于降维,SVD还能用于很多机器学习的工程领域,如推荐系统、文本主题相关性。

U 和 V 是正交矩阵,Σ是对角矩阵(不一定是方阵)

|-------|---------|------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 矩阵 | 别称 | 维度 | 计算方式 |
| U矩阵 | A的左奇异向量 | m行m列 | 列由的特征向量构成,且特征向量为单位列向量 |
| Σ矩阵 | A的奇异值 | m行n列 | 对角元素来源于的特征值的平方根。 按从大到小的顺序排列的。值越大可以理解为越重要。 |
| V矩阵 | A的右奇异向量 | n行n列 | 列由的特征向量构成,且特征向量为单位列向量 |

2.PCA

主成分分析 Principal Component Analysis

一种线性降维算法,也是一种常用的数据预处理(Pre-Processing)方法。它的目标是是用方差(Variance)来衡量数据的差异性,并将差异性较大的高维数据投影到低维空间中进行表示。方差越大,特征所带的信息量越多。

:一个特征的方差

:样本量

:一个特征中的每个样本取值

:一个特征中的每个样本取值

n 维特征矩阵降维过程中的重要步骤:

1) 输入原数据,结构为 (m,n) 找出原本的n个特征向量构成的n维空间

2) 决定降维后的特征数量:k

3) 通过某种变化,找出n个新的特征向量,以及它们构成的新n维空间

4) 找出原始数据在新特征空间V中的n个新特征向量上对应的值,即"将数据映射到新空间中"

5) 选取前k个信息量最大的特征,删掉没有被选中的特征,成功将n维空间V降为k维

PCA使用方差作为信息量的衡量指标,并且特征值分解来找出空间V。

SVD使用奇异值分解来找出空间V。

python 复制代码
class sklearn.decomposition.PCA (n_components = None
                    , copy = True
                    , whiten = False
                    , svd_solver = 'auto'
                    , tol = 0.0
                    , iterated_power = 'auto'
                    , random_state = None)  

|---------------------------|--------------------------------|
| 属性 | 解释 |
| components_ | 返回主成分系数矩阵 |
| explained_variance_ | 降维后的各主成分的方差值 |
| explained_variance_ratio_ | 降维后的各主成分的方差值占总方差值的比例(主成分方差贡献率) |

相关推荐
戊辰happy1 小时前
arcface
算法
浊酒南街2 小时前
决策树python实现代码1
python·算法·决策树
FreedomLeo13 小时前
Python机器学习笔记(十三、k均值聚类)
python·机器学习·kmeans·聚类
星光樱梦3 小时前
32. 线程、进程与协程
python
阿正的梦工坊3 小时前
深入理解 PyTorch 的 view() 函数:以多头注意力机制(Multi-Head Attention)为例 (中英双语)
人工智能·pytorch·python
冠位观测者3 小时前
【Leetcode 热题 100】208. 实现 Trie (前缀树)
数据结构·算法·leetcode
西猫雷婶3 小时前
python学opencv|读取图像(十九)使用cv2.rectangle()绘制矩形
开发语言·python·opencv
海绵波波1074 小时前
flask后端开发(10):问答平台项目结构搭建
后端·python·flask
赵谨言4 小时前
基于python网络爬虫的搜索引擎设计
爬虫·python·搜索引擎
code04号4 小时前
python脚本:批量提取excel数据
开发语言·python·excel