特征工程
目录
特征工程主要分为三部分:
- 数据预处理
- 特征选择
- 降维
1.数据预处理
1.1数据无量纲化
-
数据归一化:当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到 [0,1]之间
from sklearn.preprocessing import MinMaxScaler#导入包 scaler = MinMaxScaler() #实例化 result_ = scaler.fit_transform(data) #训练和导出结果一步达成 scaler.inverse_transform(result) #将归一化后的结果逆转
-
数据标准化:当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布)
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() #实例化 scaler.fit_transform(data) #使用fit_transform(data)一步达成结果 scaler.inverse_transform(x_std) #使用inverse_transform逆转标准化
1.2缺失值处理
-
缺失值
from sklearn.impute import SimpleImputer #新版将 impute 从preprocessing包转移到impute中了 imp_mean = SimpleImputer() #实例化,默认均值填补 imp_median = SimpleImputer(strategy="median") #用中位数填补 imp_0 = SimpleImputer(strategy="constant",fill_value=0) #用0填补 #Age为列名 imp_mean = imp_mean.fit_transform(Age) #fit_transform一步完成调取结果 imp_median = imp_median.fit_transform(Age) imp_0 = imp_0.fit_transform(Age)
1.3处理分类型特征:编码与哑变量
-
独热编码
from sklearn.preprocessing import OneHotEncoder enc = OneHotEncoder(categories='auto').fit(X) #实例化 OneHotEncoder(categories='auto').fit_transform(X).toarray() #生成结果 sklearn包 pd.get_dummies(df[a]) #pandas提供的方法
-
标签编码:标签专用,能够将分类转换为分类数值
from sklearn.preprocessing import LabelEncoder y = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维 le = LabelEncoder() #实例化 le = le.fit(y) #导入数据 label = le.transform(y) #transform接口调取结果 le.classes_ #属性.classes_查看标签中究竟有多少类别 label #查看获取的结果label le.fit_transform(y) #也可以直接fit_transform一步到位 le.inverse_transform(label) #使用inverse_transform可以逆转
-
特征编码:特征专用,能够将分类特征转换为分类数值
from sklearn.preprocessing import OrdinalEncoder OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_ #查看类别 data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
1.4处理连续型特征:二值化与分段
-
数据二值化:根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈 值的值映射为0。默认阈值为0时,特征中所有的正值都映射到1。
from sklearn.preprocessing import Binarizer bin = Binarizer(threshold=3) #设置阈值 bin.fit_transform(data) #使用fit_transform() 达成结果
-
将连续型变量划分:能够将连续型变量排序后按顺序分箱后编码。
from sklearn.preprocessing import KBinsDiscretizer X = data.iloc[:,0].values.reshape(-1,1) est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform') est.fit_transform(X) #查看转换后分的箱:变成了一列中的三箱 set(est.fit_transform(X).ravel()) est = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform') #查看转换后分的箱:变成了哑变量 est.fit_transform(X).toarray()
参数 含义&输入 n_bins 每个特征中分箱的个数,默认5,一次会被运用到所有导入的特征 encode 编码的方式 默认“onehot” “onehot”:做哑变量,之后返回一个稀疏矩阵,每一列是一个特征中的一个类别,含有该 类别的样本表示为1,不含的表示为0 “ordinal”:每个特征的每个箱都被编码为一个整数,返回每一列是一个特征,每个特征下含 有不同整数编码的箱的矩阵 “onehot-dense”:做哑变量,之后返回一个密集数组。 strategy 用来定义箱宽的方式 ,默认"quantile" “uniform”:表示等宽分箱,即每个特征中的每个箱的最大值之间的差为 (特征.max() - 特征.min())/(n_bins) “quantile”:表示等位分箱,即每个特征中的每个箱内的样本数量都相同 “kmeans”:表示按聚类分箱,每个箱中的值到最近的一维k均值聚类的簇心得距离都相同
1.5数据变换
-
多项式变换(对行向量处理):常见的数据变换有基于多项式的、基于指数函数的、基于对数函数的。
from sklearn.preprocessing import PolynomialFeatures PolynomialFeatures().fit_transform(data)
-
自定义变换:基于单变元函数的数据变换可以使用一个统一的方式完成。
from numpy import loglp from skleran.preprocessing import FunctionTransformer FunctionTransformer(log1p).fit_transform(data) #更换自己的data
总结
类 | 功能 | 说明 |
---|---|---|
MinMaxScaler | 无量纲化 | 区间缩放,基于最大最小值,将特征值转换到[0,1]区间上 |
StandardScaler | 无量纲化 | 标准化,基于特征矩阵的列,将特征值转换至服从标准正态分布 |
Normalizer | 归一化 | 基于特征矩阵的行,将样本向量转换为“单位向量” |
SimpleImputer | 缺失值计算 | 计算缺失值,根据不同策略进行填充 |
OneHotEncoder | 哑编码 | 将定性数据编码为定量数据 |
LabelEncoder | 标签专用 | 标签专用,能够将分类转换为分类数值 |
OrdinalEncoder | 特征专用 | 特征专用,能够将分类特征转换为分类数值 |
Binarizer | 二值化 | 基于给定阈值,将定量特征按阈值划分 |
KBinsDiscretizer | 分段 | 将连续型变量划分为分类变量的类 |
PolynomialFeatures | 多项式数据转换 | 多项式数据转换 |
FunctionTransformer | 自定义单元数据转换 | 使用单变元的函数来转换数据 |
2.特征选择
当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。通常来说,从两个方面考虑来选择特征:
- 特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有作用。
- 特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优先选择。
根据特征选择的形式又可以将特征选择方法分为3种:
- Filter:过滤法,不用考虑后续学习器,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。
- Wrapper:包装法,需考虑后续学习器,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。
- Embedded:嵌入法,是Filter与Wrapper方法的结合。先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小来选择特征。
使用 sklearn.feature_selection来做特征选择
2.1 Filter
2.1.1 方差选择法
使用方差选择法,先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用feature_selection库的VarianceThreshold类来选择特征。
from sklearn.feature_selection import VarianceThreshold
#方式一
var = VarianceThreshold(3)
var.fit_transform(data)
#方式二
VarianceThreshold(threshold=3).fit_transform(data) #更换自己的数据
2.1.2 单变量特征选择
单变量选择能够对每一个特征进行测试,衡量该特征和目标变量之间的关系。根据得分扔掉不好的特征。对于回归和分类问题可以使用卡方检验等方式对特征进行测试。
-
卡方检验
检验特征对变迁的相关性,选择其中k个与标签最相关的特征。使用feature_selection库的SelectKBest类结合卡方检验。
from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 #选择k个最好的特征,返回特征选择后的数据 SelectKBset(chi2,k=2).fit_transform(data,target) #选择变量和标签之间的相关性
2.2 Wrapper(优化算法)
包装法主要思想是:根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。也可以将特征子集的选择看作是一个搜索寻优问题,生成不同的组合,对组合进行评价,再与其他的组合进行比较。这样就将子集的选择看作是一个优化问题,有很多的优化算法可以解决,尤其是一些启发式的优化算法,如GA、PSO、DE、ABC等。
2.2.1 递归特征消除法
递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,在基于新的特征集下进行一轮训练。使用feature_selection库的RFE来进行特征选择。
from sklearn.feature_selection import RFE
#递归特征消除法,返回特征选择后的数据
# 参数为estimator为基模型
RFE(estimator = estimator,n_feature_to_select=2).fit_transform(data,target)
2.3 Embedded
嵌入法主要思想就是:使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。
2.3.1 基于惩罚项的特征选择法
使用带惩罚的基模型,除了筛选除特征外,同时也进行了降维。使用feature_selection库的SelectFromModel。
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
#带l1惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty='l1',c=0.1)).fit_transform(data,target)
2.3.2 基于树模型的特征选择法
树模型中GBDT可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
#带l1惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(GradientBoostingClassifier()).fit_transform(data,target)
3.降维
当特征选择完成后,就可以直接训练模型了。但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因为降低特征维度也是必不可少的。主要有 主成分分析法(PCA)和线性判别分析(LDA)。PCA是为了让映射后的样本具有最大的发散性,LDA是为了让映射后的样本有最好的分类性能。PCA是一种无监督的降维方法,LDA是一种有监督的降维方法。
3.1 主成分分析(PCA)
from sklearn.decomposition import PCA
pca = PCA(n_components=0.9)
data = pca.fit_transform([[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]])