什么是降维?
大数据时代,随着数据的喷涌式生成以及数据收集量的不断增加,可视化数据变得越来越困难,提取关键信息的难度也在不断上升。而通过把高维的数据转变为低维数据,使其能够通过可视化工具直观的展示或者变成易处理的模型特征的过程叫作降维。
举个例子,描述一个人的各项特征里包括身高体重,在我们想要解释这个人的身体状况或者体质时,就可以通过身高体重来计算得到这个人的体质指数,那么二维的身高体重转换成一维的体质指数的过程就是降维。
为什么要降维?
- 随着数据维度的减少,数据存储所需要的空间也将会减少。
- 更少维度的数据在用来进行计算时会减少计算量及计算时间。
- 降维可以解决冗余特征带来的多重共线性问题。
- 降维处理过的数据可以方便的使用可视化工具来直观查看数据的内在联系。
- 某些算法在高维度特征上的表现一般,通过降维可以提高算法可用性。
降维的方法
从大的方面看,对数据进行降维处理主要有两种:
- 人工选择或通过算法筛选重要性高的特征(特征选择)
- 组合变量来生成新的变量,而所包含的信息基本不变(降维)
1.缺失值比率(Missing Value Ratio)
我们在对数据进行预处理时,首先会进行探索性分析,如果发现少量的缺失值数据,我们通常选择填补缺失值或者删除这一特征;那么缺失值过多呢?
我们可以通过以下代码来查看缺失值数据在整个数据集中的缺失占比,如果超过我们设定的阈值,则删除缺失值所在列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
train_data = pd.read_csv('data.csv')
# 保存各特征缺失值占比(Missing Value Ratio)
mvr = train_data.isnull().sum() / len(train_data) * 100
# 设定阈值为20,并保存缺失值比例小于20的特征
feas = train_data.columns
fea = []
for i in range(train_data.shape[1]):
if mvr[i] <= 20: # 设定threshold为20%
fea.append(feas[i])
2.低方差滤波(Low Variance Filter)
如果我们在查看数据集的某一列特征时发现,该列特征的所有值基本一致,即数据范围波动不大,方差很低,那么基本可以判定该列特征可提供的信息量也会特别少或者没有,此时则应该删除此类特征。
需要注意,由于方差是和数据范围相关的,所以我们在进行特征选择前需要先进行归一化处理。
feas = train_data.columns # 获取各特征的列名
fea = [] # 用来保存高方差的列
# 得到各特征的方差
vars = train_data.var()
for i in range(0, train_data.shape[1]):
if vars[i] >= 10: # 将方差阈值设置为10%
fea.append(feas[i])
上述代码最终选择出了所有方差大于10%的特征列。
3.高相关滤波(High Correlation Filter)
在处理数据集的时候,如果两个特征变量是高度相关的,也就是说二者之间具有相似的趋势或者携带的信息量基本相同,那么不仅会造成计算量的开销增大,也会降低某些模型的性能(比如线性和LR)。
因此我们需要计算独立数值变量之间的相关性,如果超过我们设定的阈值,则需要考虑删除该变量中的一个。
# 计算train_data中各列的相关系数
corr = train_data.corr()
corr
通常情况下,如果一对变量之间的相关系数大于0.5-0.6,我们需要考虑删除其中的一列了。
4.随机森林(Random Forest)
随机森林在作为特征选择使用的算法时,效果较为良好,也是现在广泛使用的一种特征选择办法。随机森林会自动帮我们选择出重要性高的特征。随机森林回归的输入只接受数值型数据,因此需先将数据转换成数字格式。
# 导入集成模型中的随机森林回归模型
from sklearn.ensemble import RandomForestRegressor
# 转换成矩阵(独热编码)
data = pd.get_dummies(train_data)
rfr = RandomForestRegressor(random_state = 1, max_depth = 10)
rfr.fit(data, y_train_data)
# 根据特征的重要性,绘制成图表
features = train_data.columns
importances = rfr.feature_importances_
# 前10个重要的特征
indices = np.argsort(importances[0:9])
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()
得到绘制出的图表后,我们可以根据图表中的特征来手动进行选择,从而达到降维的目的。
如果使用sklearn提供的特征选择类的话,我们可以使用SelectFromModel类,它会自动帮我们根据特征的权重选择重要的特征。代码如下:
# 从feature_selection中导入SelectFromModel类
from sklearn.feature_selection import SelectFromModel
feature = SelectFromModel(rfr) # 模型为随机森林回归
5.反向特征消除(Backward Feature Elimination)
反向特征的基本步骤:
- 先使用数据集中的全部特征变量,去训练一个模型;
- 计算模型性能;
- 每次删除一次特征变量后,重新计算模型性能;
- 确定对模型性能影响最小的特征,删除该特征;
- 重复此过程,直到不能再删除任何特征;
很明显可以看出来,该方法计算成本高、耗时久,因此只适用于特征变量较少的数据集。一般在构建线性回归和逻辑回归模型时选择使用此方法。
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import RFE
# 线性回归模型
lreg = LinearRegression()
rfe = RFE(lreg, 10)
rfe = rfe.fit_transform(train_data, y_train_data)
6.PCA
PCA(Principal Component Analysis)主成分分析法,即通过正交变换将原始的n维数据,变换到一个新的被称为主成分的数据集中,将从现有的大量特征中提取一组新的变量特征。下面是PCA的一些要点:
- 主成分是原始变量的线性组合;
- 第一个主成分具有最大的方差值;
- 第二个主成分试图解释数据集中的剩余方差,且与第一主成分不相关(正交);
- 第三个主成分试图解释前两个主成分没有解释的方差。
from sklearn.decomposition import PCA
# n_components 为将要转换数据中的主成分个数
pca = PCA(n_components = 4)
# 分量解释的方差
plt.plot(range(4), pca.explained_variance_ratio_)
# 累计解释的方差
plt.plot(range(4), np.cumsum(pca.explained_variance_ratio_))
plt.title("Component-wise and Cumulative Explained Variance")
总结
降维其实是一个非常重要的特征工程之一,降维的方法也多达十余种,最常见使用的有随机森林
、PCA主成分分析法
和ICA
等等。
原文地址:www.analyticsvidhya.com/blog/2018/08/dimensionality-reduction-techniques-python/