前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习:基于scikit-learn进行特征工程

机器学习:基于scikit-learn进行特征工程

原创
作者头像
皮大大
发布2024-07-22 09:18:58
40
发布2024-07-22 09:18:58
举报
文章被收录于专栏:机器学习/数据可视化

公众号:尤而小屋 编辑:Peter 作者:Peter

大家好,我是Peter~

今天给大家分享如何基于机器学习建模全能包scikit-learn进行特征工程feature-engineering。

特征工程

机器学习的特征工程(Feature Engineering)是机器学习项目中一个至关重要的步骤,它涉及从原始数据中提取、选择和转换特征,以便更好地训练机器学习模型。特征工程直接影响到模型的性能,因为机器学习算法的性能很大程度上依赖于输入数据的表示(即特征)。

数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。

基于scikit-learn做特征工程

scikit-learn中主要用于特征的工具包:

代码语言:python
代码运行次数:0
复制
import numpy as np
import pandas as pd

import warnings
warnings.filterwarnings('ignore')

导入数据

使用鸢尾花数据集iris

代码语言:python
代码运行次数:0
复制
from sklearn.datasets import load_iris
代码语言:python
代码运行次数:0
复制
iris = load_iris()

# 特征数据X
X = iris.data
# 目标变量
y = iris.target
代码语言:python
代码运行次数:0
复制
X[:5]
代码语言:python
代码运行次数:0
复制
array([[5.1, 3.5, 1.4, 0.2],
     [4.9, 3. , 1.4, 0.2],
     [4.7, 3.2, 1.3, 0.2],
     [4.6, 3.1, 1.5, 0.2],
     [5. , 3.6, 1.4, 0.2]])
代码语言:python
代码运行次数:0
复制
y[:5]
代码语言:python
代码运行次数:0
复制
array([0, 0, 0, 0, 0])

数据预处理processing-data

数据标准化

标准化是将数据缩放到均值为0,标准差为1的过程。使用preproccessing库的StandardScaler类对数据进行标准化的代码如下:

$$x_{new} = \frac{x-\overline x}{S}$$

  • $\overline x$:x的均值
  • S:x的标准差
代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import StandardScaler
 
# 标准化后的数据
ss_data = StandardScaler().fit_transform(X)
ss_data[:5]
代码语言:python
代码运行次数:0
复制
    array([[-0.90068117,  1.01900435, -1.34022653, -1.3154443 ],
           [-1.14301691, -0.13197948, -1.34022653, -1.3154443 ],
           [-1.38535265,  0.32841405, -1.39706395, -1.3154443 ],
           [-1.50652052,  0.09821729, -1.2833891 , -1.3154443 ],
           [-1.02184904,  1.24920112, -1.34022653, -1.3154443 ]])

用于稀疏数据(比如文本数据)的标准化MaxAbsScaler(最大值缩放到1):

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import MaxAbsScaler  
  
scaler = MaxAbsScaler()  
X_scaled = scaler.fit_transform(X)

数据归一化

方式1:基于最大值最小值的归一化

$$x_{new} = \frac{x-Min}{Max-Min}$$

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import MinMaxScaler 
mm_data = MinMaxScaler().fit_transform(X)
mm_data[:5] 
代码语言:python
代码运行次数:0
复制
    array([[0.22222222, 0.625     , 0.06779661, 0.04166667],
           [0.16666667, 0.41666667, 0.06779661, 0.04166667],
           [0.11111111, 0.5       , 0.05084746, 0.04166667],
           [0.08333333, 0.45833333, 0.08474576, 0.04166667],
           [0.19444444, 0.66666667, 0.06779661, 0.04166667]])

方式2:基于规则l2的归一化处理

$$x{new} = \frac{x}{\sqrt{\sum^m{j}}xj^2}$$

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import Normalizer

#归一化,返回值为归一化后的数据
normal_data = Normalizer().fit_transform(X)
normal_data[:5]
代码语言:python
代码运行次数:0
复制
array([[0.80377277, 0.55160877, 0.22064351, 0.0315205 ],
    [0.82813287, 0.50702013, 0.23660939, 0.03380134], 
    [0.80533308, 0.54831188, 0.2227517 , 0.03426949], 
    [0.80003025, 0.53915082, 0.26087943, 0.03478392],
    [0.790965  , 0.5694948 , 0.2214702 , 0.0316386 ]])

数据二值化处理Binarizer

连续型特征的二值化处理方法:大于设置阈值的赋值为1,其他为0:

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import Binarizer

#二值化处理:阈值设置为3
bin_data = Binarizer(threshold=3).fit_transform(X)
bin_data[:5]
代码语言:python
代码运行次数:0
复制
array([[1., 1., 0., 0.],
       [1., 0., 0., 0.],
       [1., 1., 0., 0.],
       [1., 1., 0., 0.],
       [1., 1., 0., 0.]])

独热码Onehot

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import OneHotEncoder
# 哑编码:对IRIS数据集的目标值进行独热码

OneHotEncoder().fit_transform(y.reshape((-1,1)))
代码语言:python
代码运行次数:0
复制
    <150x3 sparse matrix of type '<class 'numpy.float64'>'
    	with 150 stored elements in Compressed Sparse Row format>

scikit-learn中的OneHotEncoder通常与ColumnTransformer一起使用,特别是在处理混合类型数据时:

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import OneHotEncoder  
from sklearn.compose import ColumnTransformer  
  
# 假设 X_categorical 是包含分类变量的DataFrame  
categorical_features = ['feature1', 'feature2']  
onehot = OneHotEncoder(handle_unknown='ignore')  
col_trans = ColumnTransformer([("onehot", onehot, categorical_features)], remainder='passthrough')  
X_transformed = col_trans.fit_transform(X_categorical)  
  
# 注意:X_transformed 是一个稀疏矩阵,用toarray() 转换为NumPy数组  
X_transformed_array = X_transformed.toarray()

缺失指填充Imputer

模拟存在缺失值的数据

代码语言:python
代码运行次数:0
复制
import pandas as pd
import numpy as np

df = pd.DataFrame({
    "chinese":[100,np.nan,98,90,np.nan],
    "math":[100,np.nan,98,80,94],
})
代码语言:python
代码运行次数:0
复制
impute_data = imputer.transform(df) 
impute_data 
代码语言:python
代码运行次数:0
复制
array([[100., 100.],
       [ 96.,  93.],
       [ 98.,  98.],
       [ 90.,  80.],
       [ 96.,  94.]])
代码语言:python
代码运行次数:0
复制
(100+98+90) / 3  # chinese列 

96.0
代码语言:python
代码运行次数:0
复制
(100+98+80+94) / 4  # math列

93.0

手动计算的结果和自动填充的结果是吻合的。

数据变换

基于多项式、指数、对数、平方根等进行变换;

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import PolynomialFeatures

# 参数degree为度,默认值为2
poly_data = PolynomialFeatures(degree=2).fit_transform(X)  # X = iris.data

可以自定义变换函数:

代码语言:python
代码运行次数:0
复制
from sklearn.preprocessing import FunctionTransformer  
  
# 自定义变换函数  
def custom_transform(X):    
    return X * 2  
  
transformer = FunctionTransformer(custom_transform)  
X_transformed = transformer.fit_transform(X)

还有其他的变换,比如:Box-Cox变换等

代码语言:python
代码运行次数:0
复制
import matplotlib.pyplot as plt
%matplotlib inline

import numpy as np  
from scipy import stats  
  
# 生成一组不符合正态分布的数据(例如,指数分布数据)  
data = np.random.exponential(size=100)  
# 进行Box-Cox变换  
transformed_data, lambda_value = stats.boxcox(data)  

# ----------
plt.scatter(x=range(len(data)),y=data)
plt.scatter(x=range(len(data)),y=transformed_data)
plt.show()

特征选择

根据特征选择的形式又可以将特征选择方法分为3种:

  • Filter:过滤法,不用考虑后续学习器,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。
  • Wrapper:包装法,需考虑后续学习器,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。
  • Embedded:嵌入法,是Filter与Wrapper方法的结合。先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。 我们使用sklearn中的feature_selection库来进行特征选择。

Filter方法

基于方差

使用方差选择法,先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征

代码语言:python
代码运行次数:0
复制
from sklearn.feature_selection import VarianceThreshold

# 方差选择法:threshold为方差的阈值
var_data = VarianceThreshold(threshold=3).fit_transform(X)
var_data[:5]
代码语言:python
代码运行次数:0
复制
array([[1.4],
       [1.4],
       [1.3],
       [1.5],
       [1.4]])
基于卡方检验
代码语言:python
代码运行次数:0
复制
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
代码语言:python
代码运行次数:0
复制
chi_data = SelectKBest(chi2,k=3).fit_transform(X,y)

Wrapper方法

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

递归特征消除(Recursive Feature Elimination,RFE)是一种在机器学习中广泛使用的特征选择方法。它首先使用所有特征训练一个模型,通过迭代地训练模型并剔除不重要的特征,直到达到预设的特征数量或满足其他停止条件为止。

代码语言:python
代码运行次数:0
复制
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

# estimator基模型; n_features_to_select 选择的特征数
rfe_data = RFE(estimator=LogisticRegression(), n_features_to_select=3).fit_transform(iris.data, iris.target)
rfe_data[:5]
代码语言:python
代码运行次数:0
复制
array([[3.5, 1.4, 0.2],
       [3. , 1.4, 0.2],
       [3.2, 1.3, 0.2],
       [3.1, 1.5, 0.2],
       [3.6, 1.4, 0.2]])

Embedded方法

带有惩罚项的特征选择
代码语言:python
代码运行次数:0
复制
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression

# 基模型:带L2惩罚项的逻辑回归
sfm_data1 = SelectFromModel(LogisticRegression(penalty="l2", C=0.1)).fit_transform(X, y)
sfm_data1[:5]
代码语言:python
代码运行次数:0
复制
array([[1.4, 0.2],
       [1.4, 0.2],
       [1.3, 0.2],
       [1.5, 0.2],
       [1.4, 0.2]])
基于树模型的特征选择

树模型比如GBDT可用来作为基模型进行特征选择

代码语言:python
代码运行次数:0
复制
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
 
# GBDT作为基模型的特征选择
sfm_data2 = SelectFromModel(GradientBoostingClassifier()).fit_transform(X, y)
sfm_data2[:5]
代码语言:python
代码运行次数:0
复制
array([[1.4, 0.2],
       [1.4, 0.2],
       [1.3, 0.2],
       [1.5, 0.2],
       [1.4, 0.2]])

数据降维

机器学习建模过程中,当特征数量非常大时,模型的训练时间、预测时间以及所需的计算资源(如内存和CPU/GPU)都会显著增加。通过降维,可以减少特征的数量,从而降低计算成本,使模型更加高效。

基于主成分分析PCA

PCA算法,全称为主成分分析(Principal Component Analysis),是一种无监督学习算法,主要用于数据降维和特征提取。PCA通过线性变换将原始数据映射到一个新的低维空间,以保留数据中的最大方差,即保留数据的主要信息。

代码语言:python
代码运行次数:0
复制
from sklearn.decomposition import PCA
 
# PCA:n_components为主成分数目
pca_data = PCA(n_components=2).fit_transform(X)
pca_data[:5]
代码语言:python
代码运行次数:0
复制
array([[-2.68412563,  0.31939725],
       [-2.71414169, -0.17700123],
       [-2.88899057, -0.14494943],
       [-2.74534286, -0.31829898],
       [-2.72871654,  0.32675451]])

基于线性判别分析(LDA)

代码语言:python
代码运行次数:0
复制
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

#线性判别分析法LDA: n_components为降维后的维数
lda_data = LDA(n_components=2).fit_transform(X, y)
lda_data[:5]
代码语言:python
代码运行次数:0
复制
array([[ 8.06179978, -0.30042062],
       [ 7.12868772,  0.78666043],
       [ 7.48982797,  0.26538449],
       [ 6.81320057,  0.67063107],
       [ 8.13230933, -0.51446253]])

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 特征工程
  • 基于scikit-learn做特征工程
  • 导入数据
  • 数据预处理processing-data
    • 数据标准化
      • 数据归一化
        • 数据二值化处理Binarizer
          • 独热码Onehot
            • 缺失指填充Imputer
              • 数据变换
              • 特征选择
                • Filter方法
                  • 基于方差
                  • 基于卡方检验
                • Wrapper方法
                  • 递归特征消除(Recursive Feature Elimination,RFE)
                • Embedded方法
                  • 带有惩罚项的特征选择
                  • 基于树模型的特征选择
              • 数据降维
                • 基于主成分分析PCA
                  • 基于线性判别分析(LDA)
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档