广告

Python特征工程实战技巧大全:从数据清洗到特征选择,全面提升模型性能

数据清洗与预处理技巧

缺失值处理

Python特征工程实战技巧大全:从数据清洗到特征选择,全面提升模型性能 的第一步是正确处理缺失值。缺失值的处理策略直接影响后续模型的学习效果,常见方法包括数值型的中位数填充、分类型的众数填充,以及基于模型的预测填充。通过系统地清洗缺失值,可以提升特征的一致性和可用性,从而提升模型的稳定性和性能。

在实际项目中,先快速了解缺失的分布与模式,再选择合适的填充策略。对于数值列,常用中位数或均值填充;对存在较多缺失的列,可以先拆分成缺失标记位,然后再填充数值,帮助模型区分缺失信息。本节提供一个简单而实用的实现示例,帮助你在 Python 端快速落地。

import pandas as pd
from sklearn.impute import SimpleImputerdf = pd.read_csv('data.csv')# 针对数值型列用中位数填充,分类变量用众数填充
num_cols = df.select_dtypes(include=['int64', 'float64']).columns
cat_cols = df.select_dtypes(include=['object', 'category']).columnsimp_num = SimpleImputer(strategy='median')
imp_cat = SimpleImputer(strategy='most_frequent')df[num_cols] = imp_num.fit_transform(df[num_cols])
df[cat_cols] = imp_cat.fit_transform(df[cat_cols])print(df.head())

此外,使用 pandas 的 fillna 与目标变量相关的填充策略也常见,例如对时间戳、日期列进行向前/向后填充,或对文本字段填充成空字符串,以维持数据结构的一致性。

重复值与异常值检测

在数据清洗阶段,删除重复样本和检测异常值是提高特征质量的重要步骤。重复值可能导致模型对某些样本过拟合,异常值又可能扭曲统计分布,因此需要谨慎处理。

常用做法包括:先用 drop_duplicates 去除完全重复的数据,再根据关键字段进行局部去重;其次对数值特征应用箱线图法、Z-score 或 IQR 法等进行简单的异常值过滤,以保留对模型有意义的极端样本。

# 删除完全重复的行
df = df.drop_duplicates()# 基于指定列的重复,如id重复
df = df.drop_duplicates(subset=['id'])# 简单的异常值检测(箱线图)示例
import numpy as np
Q1 = df['value'].quantile(0.25)
Q3 = df['value'].quantile(0.75)
IQR = Q3 - Q1
filter = ~((df['value'] < (Q1 - 1.5 * IQR)) | (df['value'] > (Q3 + 1.5 * IQR)))
df = df.loc[filter]

通过清晰的重复值和异常值处理,可以显著降低噪声对模型的干扰,提升模型训练的稳定性和泛化能力。

特征编码与变换

类别编码方法

对于分类变量,编码方式直接决定了模型对类别信息的理解能力。常见做法包括独热编码(One-Hot)和序数编码(Ordinal),以及在一些树模型中自动处理的目标编码与散列编码。One-Hot 编码在大多数线性与非线性模型中表现稳定,而对于高基数类别,使用目标编码或特征哈希可以降低维度。

Python特征工程实战技巧大全:从数据清洗到特征选择,全面提升模型性能

在快速落地场景,pandas 的 get_dummies提供了简单高效的实现;而在管线化场景中,sklearn 的 ColumnTransformer 与 OneHotEncoder更利于交叉验证和自动化训练。

import pandas as pd
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipelinedf = pd.read_csv('data.csv')
cat_cols = df.select_dtypes(include=['object']).columns# 使用 pandas.get_dummies 简单实现
df_dummies = pd.get_dummies(df, columns=cat_cols, drop_first=True)print(df_dummies.shape)

如果需要更灵活的编码策略,可以在管线中使用 OneHotEncoder,同时设置 handle_unknown='ignore',避免在交叉验证或线上数据中出现未知类别导致的错误。

数值特征变换

数值特征的分布往往不是对称的,通过对数、Box-Cox、Yeo-Johnson 等变换可以近似正态分布,有助于线性模型等对分布假设敏感的算法提高表现。

常用做法包括先对数化非负数据,再应用幂变换;或直接使用 PowerTransformer 实现更通用的分布转换。

import numpy as np
from sklearn.preprocessing import PowerTransformernum_cols = df.select_dtypes(include=['int64','float64']).columns
pt = PowerTransformer(method='yeo-johnson', standardize=True)df[num_cols] = pt.fit_transform(df[num_cols])

通过数值特征变换,模型能够更好地处理特征之间的线性关系,从而提升预测能力,尤其是在回归与分类的边际情形下尤为明显。

特征缩放与正则化

标准化与归一化

不同特征的取值范围可能相差很大,缩放是让模型更快收敛、避免某些特征主导权重分配的重要手段。StandardScaler实现标准化,MinMaxScaler实现归一化,二者在不同模型中各有适用场景。

在实际建模中,数值型特征先填充,再进行缩放,通常能获得更稳定的优化路径和更好的泛化性能。

from sklearn.preprocessing import StandardScaler, MinMaxScalerscaler = StandardScaler()
df[num_cols] = scaler.fit_transform(df[num_cols])

对于对尺度敏感的线性模型,缩放效果尤为显著;而对于树模型,缩放往往影响较小,但在包含线性层的混合模型中仍有帮助。

正则化在模型中的作用

正则化有助于抑制模型过拟合,在高维数据或特征多样化场景中尤为重要。常见做法包括 L2(Ridge)和 L1(Lasso)正则化,以及对某些实现选择合适的优化求解器。

下面给出一个简单的管线示例,展示在逻辑回归中应用 L2 与 L1 正则化的对比,以及两种求解器的适用性。

from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler# L2 正则化(默认 penalty='l2',求解器需支持)
model_l2 = Pipeline(steps=[('imputer', SimpleImputer(strategy='median')),('scaler', StandardScaler()),('clf', LogisticRegression(penalty='l2', C=1.0, max_iter=1000))
])# L1 正则化(需要支持的求解器,例如 liblinear)
model_l1 = Pipeline(steps=[('imputer', SimpleImputer(strategy='median')),('scaler', StandardScaler(with_mean=False)),('clf', LogisticRegression(penalty='l1', solver='liblinear', C=1.0, max_iter=1000))
])

通过对比不同正则化形式,可以找到在当前数据集上的最佳折中,提升鲁棒性与泛化能力。

特征交互与组合

交互特征构造

现实世界数据往往存在特征之间的非线性关系,构造交互特征可以帮助模型捕捉这些关系,提升预测能力。例如,两个特征的乘积、比值或对数交互等都可能带来有用的信息。

常用工具包括 PolynomialFeatures,它能够自动产生二阶、三阶的交互项,帮助线性模型学习非线性关系。

from sklearn.preprocessing import PolynomialFeatures
import numpy as npX = df[num_cols].values
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)

需要注意的是,交互特征会显著增加维度,因此要结合特征选择策略,防止维度灾难。

多项式特征与特征工程

在某些场景中,适度的多项式特征能够提升模型对非线性模式的拟合能力,但也要防止过拟合。结合正则化和特征选择,可以在不显著增加计算代价的前提下获得更好的效果。

from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(df[num_cols].values)print(X_poly.shape)

在大型数据集上,建议将多项式特征与管线结合,按需启用,避免无谓的维度膨胀。

降维与特征选择

降维方法

当特征维度过高时,降维可以帮助减小计算成本、降低噪声并改善可解释性。PCA是最常用的线性降维方法,可以在保留大部分方差的同时降低维数。

使用 PCA 时,通常设定目标方差比例(如 0.95)以决定保留的维度数量,或直接固定 n_components。

from sklearn.decomposition import PCAX = df.drop(columns=['target'])
pca = PCA(n_components=0.95)  # 保留95%方差
X_reduced = pca.fit_transform(X)

降维不仅影响训练速度,还可能提高模型的泛化能力,尤其在高维稀疏数据环境中效果显著。

统计与基于模型的特征选择

特征选择旨在保留对预测最具信息量的特征,常见方法包括统计检验和基于模型的重要性排序。SelectKBest结合 F 值/互信息等指标,快速筛选出关键特征。

另外,基于树模型的特征重要性也非常实用,可以直接排序并选取前 N 个特征用于建模。

from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.ensemble import RandomForestClassifier
import numpy as npX = df.drop(columns=['target'])
y = df['target']selector = SelectKBest(score_func=f_classif, k=20)
X_new = selector.fit_transform(X, y)
selected_features = [X.columns[i] for i in selector.get_support(indices=True)]
# 使用基于模型的重要性进行特征选择
RF = RandomForestClassifier(n_estimators=200, random_state=42)
RF.fit(X, y)
importances = RF.feature_importances_
indices = np.argsort(importances)[::-1]
top_features = [X.columns[i] for i in indices[:20]]

结合统计化方法与模型基于的重要性,可在不同场景下灵活选择最具信息量的特征集合。

流程化与自动化

构建特征工程管线

为实现可重复、高效的建模流程,将数据清洗、编码、缩放、特征构造以及建模步骤整合到一个管线中非常重要。Pipeline 与 ColumnTransformer的组合可以确保在交叉验证和实际预测时特征处理保持一致性。

通过管线化,可以实现一处修改、全局生效,方便协同开发与版本控制,降低上线风险。

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegressionX = df.drop(columns=['target'])
y = df['target']num_cols = X.select_dtypes(include=['int64','float64']).columns
cat_cols = X.select_dtypes(include=['object', 'category']).columnsnumeric_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='median')),('scaler', StandardScaler())
])categorical_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='most_frequent')),('onehot', OneHotEncoder(handle_unknown='ignore'))
])preprocessor = ColumnTransformer(transformers=[('num', numeric_transformer, num_cols),('cat', categorical_transformer, cat_cols)])clf = Pipeline(steps=[('preprocessor', preprocessor),('model', LogisticRegression(max_iter=1000))])

上述管线可以直接用于交叉验证、网格搜索和线上预测,提升工作流的鲁棒性与可维护性。

自动化特征工程工具与实践

在大型数据工程或重复任务中,利用自动化特征工程工具可以提高产出效率,常见做法包括特征工具(FeatureTools)自动化生成特征,以及基于规则的特征生成脚本。

下面给出一个简单的自动化特征生成示例,结合特征工具对数据进行深度特征构造的思路,帮助你在复杂场景中快速原型化。

import featuretools as ft
import pandas as pd# 假设 df 已包含需要的列,并且存在主键 customer_id
entity = ft.EntitySet(id='customers')
entity = entity.add_dataframe(dataframe_name='customers', dataframe=df, index='customer_id', time_index=None)# 自动生成特征(示例,实际数据结构需按需调整)
features, feature_names = ft.dfs(entityset=entity, target_dataframe_name='customers', max_depth=2)print(features.head())

请在实际使用中结合数据结构和建模目标,合理控制深度与特征数量,避免过拟合与计算瓶颈。

> 注:本文围绕 Python 特征工程实战技巧大全:从数据清洗到特征选择,全面提升模型性能展开,覆盖了从数据清洗到特征选择的全生命周期技巧。通过系统化的步骤、实用的代码示例以及管线化的思路,帮助你在实际项目中快速提升模型性能与工程化水平。

广告

后端开发标签