机器学习特征构建&变换处理

前言

上一篇文章讲述了原始特征分析和处理,保障后续拿到的是干净的特征变量,但实际这些特征对于建模不一定是有效的,所以需要在原始特征的基础上,结合业务场景做特征变量的衍生,提升数据的表达能力。此外,因为特征值的维度、分布、量纲等,真正进入模型训练还需要对特征做对应的变换处理。

特征构建

统计特征构建

参照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知识社区

相关推荐
DogDaoDao1 小时前
【第 04 篇】列表与元组 —— 序列类型核心详解
人工智能·python·深度学习·神经网络·机器学习·conda·numpy
阿文的代码库1 小时前
机器学习之精确率和召回率的关系
人工智能·算法·机器学习
wubba lubba dub dub75014 小时前
第四十九周学习周报
人工智能·算法·机器学习
装不满的克莱因瓶15 小时前
学习使用 Python 机器学习工具 sklearn
人工智能·python·学习·机器学习·ai·agent·智能体
Omics Pro16 小时前
3种蛋白结构输入方式!已申报欧洲发明专利
数据库·人工智能·python·机器学习·plotly
Omics Pro17 小时前
「自兹以往」动物肠道微生物组
数据库·人工智能·机器学习·语言模型·自然语言处理
oddsand117 小时前
pgvector 三大相似度算法
人工智能·算法·机器学习
落羽的落羽19 小时前
【项目】JsonRpc框架——开发实现1(细节功能、字段定义、抽象层、具象层)
linux·服务器·网络·c++·人工智能·算法·机器学习
keykey6.19 小时前
卷积神经网络(CNN):让AI学会“看“
开发语言·人工智能·深度学习·机器学习
升鲜宝供应链及收银系统源代码服务20 小时前
升鲜宝AI助手 E-R 图与操作说明书(三)---升鲜宝生鲜配送供应链管理系统源代码服务
大数据·人工智能·机器学习·生鲜供应链源代码·供应链源代码出售·生鲜配送源代码服务·门店连锁系统源代码