6.3 特征构建与转换
Scikit-learn教程:特征构建与转换详解
本教程详解Scikit-learn中的特征构建与转换,包括基于业务知识的手动特征构建(如特征交叉、聚合)、自动特征构建(使用FeatureUnion融合多特征提取器),以及特征变换(对数变换、幂变换)以改善数据分布。适合新手学习Scikit-learn特征工程。
特征构建与转换
引言
在机器学习中,特征构建与转换是提升模型性能的关键步骤。通过设计新特征或调整现有特征,可以使模型更好地捕捉数据中的模式。本章将介绍手动和自动的特征构建方法,以及用于改善数据分布的特征变换技巧。这些内容旨在帮助新手快速掌握Scikit-learn中的特征工程基础。
手动特征构建
手动特征构建依赖于业务知识来创建新特征,通常涉及特征交叉和聚合。
特征交叉
特征交叉是通过组合多个现有特征来生成新特征,例如创建交互项以捕捉特征间的关系。这常用于线性模型或基于树的模型。
示例: 在电商数据中,可以创建“价格×销量”的新特征来反映收入潜力。
Scikit-learn代码示例:
使用PolynomialFeatures进行特征交叉。
import pandas as pd
from sklearn.preprocessing import PolynomialFeatures
# 创建示例数据
data = pd.DataFrame({'price': [10, 20, 30], 'sales': [100, 200, 150]})
# 使用多项式特征提取器,设置degree=2仅生成交互项(不包括平方项),不包含偏置项
poly = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)
X_poly = poly.fit_transform(data[['price', 'sales']])
print("交叉后特征矩阵:", X_poly)
解释:这里生成了原始特征和它们的交互项(如price*sales),帮助模型捕捉非线性关系。
特征聚合
特征聚合是将多个特征总结为单个值,例如计算总和、平均值或最大值。这常用于时间序列或多维数据。
示例: 对多个月的销售数据进行聚合,生成“月平均销售额”或“年销售总额”。
代码示例: 使用Pandas进行简单聚合。
# 假设数据包含多列
# 这里以示例数据演示
import pandas as pd
data = pd.DataFrame({
'month1_sales': [50, 60, 70],
'month2_sales': [80, 90, 100]
})
# 创建聚合特征:总销售额
data['total_sales'] = data[['month1_sales', 'month2_sales']].sum(axis=1)
# 创建聚合特征:平均销售额
data['avg_sales'] = data[['month1_sales', 'month2_sales']].mean(axis=1)
print(data)
解释:聚合可以减少特征维度,同时保留关键信息。
自动特征构建:FeatureUnion
Scikit-learn的FeatureUnion类允许并行应用多个特征提取器,并将它们的输出连接起来,实现自动化特征构建。这对于处理不同类型的特征非常有用。
示例: 结合文本特征的向量化和转换。
代码示例:
使用FeatureUnion融合多个提取器。
from sklearn.pipeline import FeatureUnion
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
# 假设有两个特征提取器
vectorizer1 = CountVectorizer() # 词频统计
vectorizer2 = TfidfTransformer() # TF-IDF转换
# 创建FeatureUnion组合器
combined = FeatureUnion([('count', vectorizer1), ('tfidf', vectorizer2)])
# 示例数据
X_text = ["example text for vectorization", "another example text"]
# 拟合和变换
X_transformed = combined.fit_transform(X_text)
print("组合后特征矩阵形状:", X_transformed.shape)
解释:FeatureUnion适合处理多源特征,例如文本、数值或分类特征,将它们融合成一个特征矩阵。
特征变换:改善数据分布
特征变换用于处理数据分布,使其更接近正态分布,从而提升模型性能。对数变换和幂变换是常见方法。
对数变换
对数变换适用于右偏数据(如计数值、收入数据),通过压缩高值区域,减少异常值的影响。
代码示例:
使用FunctionTransformer应用对数变换。
import numpy as np
from sklearn.preprocessing import FunctionTransformer
# 假设数据X是数值数组
X = np.array([[1, 10], [100, 1000], [0, 5]])
# 创建对数变换器,使用log1p避免处理零或负值
log_transformer = FunctionTransformer(np.log1p)
X_log = log_transformer.fit_transform(X)
print("对数变换后:", X_log)
解释:log1p先加1再取对数,防止零值错误,适用于有零值的数据。
幂变换
幂变换如Box-Cox或Yeo-Johnson可以处理更广泛的分布,包括左偏或右偏数据。Box-Cox要求数据为正,Yeo-Johnson适用于任何实数。
代码示例:
使用PowerTransformer。
from sklearn.preprocessing import PowerTransformer
# 使用Yeo-Johnson方法,适用于所有数值
power = PowerTransformer(method='yeo-johnson')
X_power = power.fit_transform(X)
print("幂变换后:", X_power)
解释:幂变换使数据更对称,减少模型假设的偏差。
总结
特征构建与转换是机器学习流程中的重要环节。手动方法基于业务知识,如特征交叉和聚合,可以提升模型解释性;自动方法如FeatureUnion,提供灵活的多特征融合;特征变换如对数变换和幂变换,有助于改善数据分布,提高模型鲁棒性。实践中,建议结合具体数据和模型需求,实验不同方法来优化特征。通过本章学习,您已掌握Scikit-learn中特征工程的基础,下一步可以探索更多高级技术如特征选择或编码。