前言
上一篇文章讲述了原始特征分析和处理,保障后续拿到的是干净的特征变量,但实际这些特征对于建模不一定是有效的,所以需要在原始特征的基础上,结合业务场景做特征变量的衍生,提升数据的表达能力。此外,因为特征值的维度、分布、量纲等,真正进入模型训练还需要对特征做对应的变换处理。
特征构建
统计特征构建
参照pandas提供的titanic救生数据,筛选里面有特征变量
|----------|--------|-----|-----|---------|-------|------|----------|-------|------|------------|-------|
| survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | alone |
| 存活 | 票等级 | 性别 | 年龄 | 同行子女/配偶 | 同行父母 | 票价 | 登船港口 | 社会阶层 | 乘客类型 | 是否成年 | 是否独自 |
其中,年龄对应的人群获救概率不同,所以可以对年龄做衍生。按照年龄,将其分为child/yong/middle/old4个等级。
def age_bin(x): if x<=18: return 'child' elif x <=30: return 'yong' elif x<=45: return 'mid' else: return 'old' # 增加age_bin特征 dt['age_bin'] = dt['age'].map(age_bin)
按照家庭维度,可以衍生家庭规模大小特征
dt['family_size'] = dt['sibsp'] +dt['parch'] + 1 print(dt['family_size'].head())
周期值构建
数据有时间维度的,可以结合业务抽取出新特征。比如,用户的电商消费数据,每个时间点是一行记录,可以抽取出仅一周消费频次、近一月消费频次等;
数据分桶
数据分桶通常是对连续性特征的处理方式,常见的分桶有
- 等频分箱:数据平均分成几份
- 等距分箱:数据按照最小值和最大值间距等分
- 自定义分箱:结合业务场景自定义分箱规则
- 卡方/Best-KS分桶: 这种方法侧重于发现目标分类变量和连续变量之间的关系,适用于分类问题中的特征工程。
- 最小熵法分桶:最小熵法的目标是找到一种分箱方式,使得每个桶内的数据分布熵之和最小.适用于追求数据纯净度的场景.
对船票数据分析:
看到数据有很强的长尾效应,如果采用等距切分,容易出现分桶数据不均匀,所以采用等频切分。
设定分桶数量,拿到分桶值
data_cut, bins = pd.qcut(dt['fare'], 10, retbins=True)
查看桶内样本数量
data_cut.value_count()
定义函数,做分桶变量替换
def fare_cut(x): if x <= 7.854: return 0 elif x<= 10.5: return 1 elif x <= 21.679: return 2 elif x<= 39.688: return 3 else: return 4; dt['fare_bin'] = dt['fare'].map(fare_cut)
特征组合
常用的特征组合有:
- 离线+离散:构建笛卡尔积
- 离线+连续:连续特征分桶后基于类别特征group by构建统计特征
- 连续+连续:加减乘除,多项式特征,二阶差分等。
- 多项式特征:针对连续值特征,对几个特征构建多项式特征,以达到特征组合与高阶增强的作用。于一些需要非线性关系建模的问题非常有用。
poly = PolynomialFeatures(degree=2) # 指定二次多项式
X_poly = poly.fit_transform(X)
print("Transformed features:\n", X_poly)
特征变换
连续特征变换
标准化处理
标准化处理是指将特征数值转换成算数平均为0,方差(以及标准差)为1的分布。
from sklearn.preprocessing import StandardScaler X = np.array([[1], [2], [3], [4], [5]]) scaler = StandardScaler() X_scaled = scaler.fit_transform(X)
归一化处理(尺度缩放)
归一化处理是基于向量模长调整数据幅度大小,但并不会改变原始数据的顺序。
L2范数归一化:
L1范数归一化:
scaler = MinMaxScaler()
data_normalized = scaler.fit_transform(data)
归一化和标准化的区别联系
- 归一化是为了消除纲量压缩到[0,1]区间;标准化只是调整特征整体的分布,无大小限制。
- 归一化与最大,最小值有关;标准化与均值,标准差有关。
适用性选择
- 在分类、聚类算法中,需要使用距离来度量相似性的时候,如SVN、KNN、PCA等,标准化表现良好
- 在不涉及到距离、协方差计算、数据不符合正态分布情况下,使用归一化处理,比如图像的RGB色
- 基于树模型(随机森林、GBDT、XGBoost、 LightGBM)等,不需要进行特征的归一化处理;
- 基于参数的模型或者距离的模型,如LR、K-Means、NN等,需要对参数进行归一化处理;
非线性变换
有些场景下,会对数值字段进行分布调整或者校正,利用统计或数学变换来减轻数据分布倾斜的影响。使原本密集的区间的值尽可能的分散,原本分散的区间的值尽量的聚合。
log变换:主要作用为稳定方差,主要针对连续特征的重尾分布调整
box-cox: 主要特点是引入一个参数,通过数据本身估计该参数进而确定应采取的数据变换形式,box-cox 变换可以明显地改善数据的正态性、对称性和方差相等性. 引入参数的最佳取值通常由最大似然或最大对数似然确定。
离散变量处理
对于类别型的字段特征(比如颜色、类型、好坏程度),有很多模型并不能直接处理,我们对其进行编码后能更好地呈现信息和支撑模型学习
标签编码
标签编码值介于0和 n_classes-1 之间的标签。 优点是占用更少的空间,并且支持文本编码。缺点是引入了标签的大小关系。
from sklearn.preprocessing import LabelEncoder le = LabelEncoder() da = le.fit_transform(["超一线", "一线", "二线", "三线"])
one-hot编码
通常用于处理类别间不具有大小关系的特征。
from sklearn.preprocessing import OneHotEncoder # 非负整数表示的标签列表 labels = [0,1,0,2] # 行向量转列向量 labels = np.array(labels).reshape(len(labels), -1) enc = OneHotEncoder() print(enc.fit_transform(labels).toarray())
标签二值化
功能与 OneHotEncoder 一样,但是 OneHotEncoder 只能对数值型变量二值化,无法直接对字符串型的类别变量编码,而 LabelBinarizer 可以直接对字符型变量二值化 。
from sklearn.preprocessing import LabelBinarizer lb=LabelBinarizer() labelList=['yes', 'no', 'no', 'yes','no2'] # 将标签矩阵二值化 dummY=lb.fit_transform(labelList) print("dummY:",dummY)
降维
降维的目的是减少特征属性个数,确保特征变量间相互独立。原因是特征数据可能存在以下几个问题:
- 数据多重共线性:特征与特征之间存在相互关联,多重共线性会导致解空间不稳定,模型鲁棒性差;
- 高维空间样本稀疏性:样本稀疏导致难以分析出特征特性
- 过多变量会妨碍最优解的查找和找解效率;
PCA降维
import numpy as np from sklearn.decomposition import PCA pca = PCA(n_components=2) newX = pca.fit_transform(X) draw_result(newX, y)
SVD 降维
与PCA降维类似,不过PCA求的是协方差矩阵,SVD求解的是A(T)A的特征值分解。
T-SNE
T-SNE(t-distributed stochastic neighbor embedding)是一种非线性降维方法,参考的代码实现如下:
from sklearn.manifold import TSNE tsne = TSNE(n_components=2) iris_2d = tsne.fit_transform(X) draw_result(iris_2d, y)
PCA与T-SNE选择
PCA优点:
- 线性降维:PCA通过线性变换将原始数据映射到低维空间,保留数据的最大方差方向,从而捕获数据的主要变化趋势
- 计算效率高:对于大规模数据集,PCA相对计算成本较低,且易于理解和实现。
- 无监督:不需要标签信息,适用于探索性数据分析和预处理。
- 解释性强:主成分具有实际意义,可以解释为数据变化的主要方向。
缺点:
- 对噪声敏感:PCA假设数据是线性可分的,对异常值和噪声较为敏感。
- 不能很好地处理非线性关系:如果数据中存在复杂的非线性结构,PCA可能无法有效捕捉。
t-SNE优点:
- 非线性降维:t-SNE擅长捕捉高维数据中的复杂非线性结构,能够展示数据的局部结构和簇信息。
- 可视化效果好:特别适合用于二维或三维可视化,能够清晰地展示不同类别的数据点分布,有助于模式识别和探索性分析。
- 保持局部相似性:通过模拟高维空间中样本间的邻近关系,在低维空间中保持样本的局部结构。
缺点:
- 计算成本高:计算复杂度较高,尤其是对于大数据集,可能需要较长时间。
- 参数敏感:对超参数(如 perplexity)非常敏感,选择不当可能得到较差的结果。
- 解释性弱:降维结果难以直接解释,更多用于可视化而非直接建模输入。
如果目标是简化数据以便于后续的线性模型使用,或者需要一种快速且可解释的降维方法 ,PCA 可能是更好的选择。如果数据中包含复杂的非线性关系,且主要目的是进行数据探索或可视化以发现潜在的结构和模式 ,那么t-SNE会更加合适。
特征选择
原始特征经过分析处理、构建和转换后,还需要进行筛选。冗余的特征容易导致资源消耗高、噪声大,并且还可能产生过拟合。特征选取的方向有:
- 特征发散度:如果特征不发散,方差接近1,没什么意义;
- 与目标相关性:相关性越大的越硬蛋保留;
特征选取方法进行归类,有3大类。
Filter过滤法
方差过滤法
通过特征本身的方差来过滤。
from sklearn.feature_selection import VarianceThreshold var = VarianceThreshold() df = var.fit_transform(X) print(var.get_support()==0)
卡方过滤法
专用于分类算法,捕捉相关性,追求p小于显著性水平的特征。卡方过滤是专门针对离散型标签(即分类问题)的相关性过滤。
F校验法
F检验捕捉线性相关性,要求数据服从正态分布,追求p值小于显著性水平特征。
互信息法
是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法
Wrapper选择法
递归特征删除法
递归消除删除法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。
from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression #递归特征消除法,返回特征选择后的数据 #参数 estimator 为基模型 #参数 n_features_to_select 为选择的特征个数 X_ref = RFE(estimator=LogisticRegression(), n_features_to_select=10).fit_transform(X, y)
特征重要性评估法
基于一些模型(如各类树模型)可以得到特征重要度,进而进行筛选 。
排列性重要评估
原理:在训练机器学习模型之后计算置换重要性。这种方法在向模型提出假设,如果在保留目标和所有其他列的同时随机打乱一列验证集特征数据,对预测机器学习模型的准确性的影响程度。对于一个具有高度重要性的特征,random-reshuffle 会对机器学习模型预测的准确性造成更大的损害。
优点:快速计算;易于使用和理解;特征重要性度量的属性;追求特征稳定性。
Embedded方法
基于惩罚项的特征选取
基于树模型的特征选取
特征选取小结
过滤法(Filter):基于统计指标(如皮尔逊相关系数、 mutual information、卡方检验等)对每个特征进行评分,然后根据阈值或排名选择特征。
- 适用场景:处理大规模数据集时特别有效,因为它们通常计算效率高。
- 优点:计算速度快,独立于模型。
- 缺点:可能忽略特征间的相互作用。
包裹法(Wrapper):将特征选择视为搜索问题,通过反复训练模型来评估不同特征子集的表现,如递归特征消除(RFE)、前向选择、后向消除等。
- 适用场景:当特征之间存在较强的相关性,且模型性能是首要考虑因素时。
- 优点:直接考虑特征组合的效果,可能找到最优特征子集。
- 缺点:计算成本高,尤其是对于大数据集和复杂模型。
嵌入法(Embedded):在模型训练过程中自动执行特征选择,如正则化(Lasso、Ridge)、决策树的特征重要性等。
- 适用场景:适合那些内建了特征选择机制的模型,追求效率与效果的平衡。
- 优点:结合了过滤法和包裹法的优点,既高效又能考虑特征间交互。
- 缺点:特征选择的标准和过程依赖于特定模型。
基于模型的特征重要性:直接利用模型提供的特征重要性分数来排序和选择特征。
- 适用场景:当使用像随机森林、梯度提升树等可以自然提供特征重要性的模型时。
- 优点:直观易用,反映了特征对模型预测能力的贡献。
- 缺点:可能受到模型自身偏见的影响。
选择特征选取方法时,还应考虑以下几个因素:
- 数据规模:大规模数据集可能更适合使用过滤法或嵌入法。
- 计算资源:资源有限时避免使用计算密集型的包裹法。
- 问题类型:分类、回归、聚类等问题可能对特征的选择有不同的敏感度。
- 模型复杂度:简单模型可能从特征选择中获益更多,而复杂模型本身已有较好的抗噪能力。
- 领域知识:了解数据背景可以帮助选择更合理的特征评价标准。
参考文档:ShowMeAI知识社区