Python实现特征工程的艺术:特种选择策略详解

机器学习和数据科学领域,特征工程是一门至关重要的技术。它涉及到从原始数据中提取、创建和选择有意义的特征,以便于模型学习和预测。特征工程的目标是提高模型的性能,降低过拟合的风险,并提高模型的解释性。本文将详细介绍几种特征选择策略,并提供Python实现。

1. 删除未使用的列

在数据集中,某些列可能与目标变量没有任何关系,这些列被称为未使用的列。删除这些列可以减少模型的复杂性,提高处理速度。通常,这些列包括但不限于跟踪ID、时间戳或其他对模型无关的元数据。

Python实现:

import pandas as pd

# 假设df是包含数据的DataFrame
# 找出与目标变量无关的列,例如'id'列
unnecessary_columns = ['id', 'timestamp']  # 假设这些列是不必要的
df = df.drop(columns=unnecessary_columns)

2. 删除具有缺失值的列

数据缺失是现实世界数据集的常见问题。如果某个特征的缺失值过多,可能无法有效地利用插值或其他方法进行处理,这时可以考虑删除这些列。

Python实现:

 

# 找出缺失值过多的列
threshold = 0.5  # 假设缺失值超过50%就删除该列
columns_to_drop = df.columns[df.isnull().mean() > threshold]
df = df.drop(columns=columns_to_drop)

3. 不相关的特征

特征与目标变量之间的相关性分析是特征选择的重要部分。可以使用相关系数来衡量特征与目标之间的关系,删除那些相关性低的特征。

Python实现:

 

# 计算特征与目标变量之间的相关系数
correlation_threshold = 0.2  # 设置相关性阈值
correlations = df.corrwith(df['target']).abs()
low_corr_features = correlations[correlations < correlation_threshold].index.tolist()
df = df.drop(columns=low_corr_features)

4. 低方差特征

方差低的特征意味着该特征的值变化不大,对模型的贡献较小。删除这些特征可以减少模型的复杂性。

Python实现:

 

# 找出方差低的特征
variance_threshold = 0.0  # 设置方差阈值
low_variance_features = df.var()[df.var() < variance_threshold].index.tolist()
df = df.drop(columns=low_variance_features)

5. 多重共线性

多重共线性指的是特征之间存在高度相关性。可以使用相关系数矩阵或方差膨胀因子(VIF)来检测共线性。

Python实现:

 

from statsmodels.stats.outliers_influence import variance_inflation_factor

# 计算VIF
vif_data = pd.DataFrame()
vif_data["feature"] = df.columns
vif_data["VIF"] = [variance_inflation_factor(df.values, i) for i in range(df.shape[1])]

# 找出VIF值高的特征
high_vif_features = vif_data[vif_data["VIF"] > 10]["feature"].tolist()
df = df.drop(columns=high_vif_features)

6. 特征系数

在线性模型中,特征系数的大小可以反映特征对目标变量的影响程度。系数接近0的特征对模型的贡献较小。

Python实现:

 

from sklearn.linear_model import LinearRegression

# 训练线性回归模型
model = LinearRegression()
model.fit(df.drop('target', axis=1), df['target'])

# 找出系数小的特征
coefficients = model.coef_
small_coeff_features = [feature for feature, coef in zip(df.columns, coefficients) if abs(coef) < 0.01]
df = df.drop(columns=small_coeff_features)

7. p值

在统计模型中,p值用于判断特征的显著性。p值较大的特征可能对模型的贡献不大。

Python实现:

 

import statsmodels.api as sm

# 构建线性回归模型并计算p值
X = sm.add_constant(df.drop('target', axis=1))  # 添加常数项
model = sm.OLS(df['target'], X).fit()
p_values = model.pvalues

# 找出p值大的特征
high_pvalue_features = p_values[p_values > 0.05].index.tolist()
df = df.drop(columns=high_pvalue_features)

8. 方差膨胀因子 (VIF)

VIF用于检测特征之间的多重共线性。VIF值高于5或10可能表明特征之间存在共线性。

Python实现:

 

# 计算VIF
vif_data = pd.DataFrame()
vif_data["feature"] = df.columns
vif_data["VIF"] = [variance_inflation_factor(df.values, i) for i in range(df.shape[1])]

# 找出VIF值高的特征
high_vif_features = vif_data[vif_data["VIF"] > 10]["feature"].tolist()
df = df.drop(columns=high_vif_features)

9. 基于特征重要性的特征选择

基于模型的特征选择方法,如随机森林,可以提供特征的重要性评分。

Python实现:

 

from sklearn.ensemble import RandomForestClassifier

# 训练随机森林模型
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(df.drop('target', axis=1), df['target'])

# 获取特征重要性
importances = rf.feature_importances_

# 找出重要性低的特征
low_importance_features = [feature for feature, importance in zip(df.columns, importances) if importance < 0.01]
df = df.drop(columns=low_importance_features)

10. 使用scikit-learn进行自动特征选择

scikit-learn提供了多种自动特征选择的方法,如SelectKBest、SelectFromModel等。

Python实现:

 

from sklearn.feature_selection import SelectKBest, chi2

# 使用SelectKBest选择最好的K个特征
k = 10  # 选择的特征数量
selector = SelectKBest(chi2, k=k)
X_new = selector.fit_transform(df.drop('target', axis=1), df['target'])

# 找出被选择的特征
selected_features = pd.DataFrame(X_new, columns=selector.get_support(indices=True))
df = df[selected_features.columns]

11. 主成分分析 (PCA)

PCA是一种常用的降维技术,可以通过线性变换将数据投影到新的空间,以最大化方差。

Python实现:

 

from sklearn.decomposition import PCA

# 训练PCA模型
pca = PCA(n_components=2)  # 选择主成分数量
X_pca = pca.fit_transform(df.drop('target', axis=1))

# 将降维后的数据转换为DataFrame
pca_df = pd.DataFrame(X_pca, columns=['PC1', 'PC2'])

12. 递归特征消除 (RFE)

递归特征消除是一种通过递归地构建模型,逐步删除权重最小的特征来选择最优特征的方法。RFE通过训练模型并反复调整特征集,最终选出对模型最重要的特征。

Python实现:

 

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

# 使用逻辑回归模型进行递归特征消除
model = LogisticRegression()
rfe = RFE(model, n_features_to_select=5)
X_rfe = rfe.fit_transform(df.drop('target', axis=1), df['target'])

# 被选择的特征
selected_features = rfe.get_support(indices=True)
df_rfe = df.iloc[:, selected_features]

13. 基于树模型的特征选择

决策树、随机森林、梯度提升树等树模型可以评估特征的重要性,通过模型训练后特征的贡献程度选择特征。这些模型根据数据的分裂点来评估特征的重要性。

Python实现:

 

from sklearn.ensemble import GradientBoostingClassifier

# 使用梯度提升树训练模型
model = GradientBoostingClassifier()
model.fit(df.drop('target', axis=1), df['target'])

# 获取特征的重要性
feature_importances = model.feature_importances_

# 删除重要性低的特征
low_importance_features = [feature for feature, importance in zip(df.columns, feature_importances) if importance < 0.01]
df = df.drop(columns=low_importance_features)

14. 基于L1正则化的特征选择

L1正则化(Lasso)会对权重较小的特征施加惩罚,使其权重趋于0。这种特性可以用来选择特征,即删除权重为0的特征。

Python实现:

 

from sklearn.linear_model import Lasso

# 使用Lasso进行特征选择
lasso = Lasso(alpha=0.01)
lasso.fit(df.drop('target', axis=1), df['target'])

# 删除系数为0的特征
lasso_coef = lasso.coef_
selected_features = df.columns[lasso_coef != 0]
df = df[selected_features]

15. 互信息特征选择

互信息衡量的是特征和目标变量之间的依赖性。互信息越高,表明该特征提供的关于目标变量的信息越多,可以通过该方法选择与目标变量依赖性强的特征。

Python实现:

 

from sklearn.feature_selection import mutual_info_classif

# 计算特征和目标变量之间的互信息
mutual_info = mutual_info_classif(df.drop('target', axis=1), df['target'])

# 删除互信息低的特征
threshold = 0.01
low_mi_features = [feature for feature, mi in zip(df.columns, mutual_info) if mi < threshold]
df = df.drop(columns=low_mi_features)

16. 主成分回归 (PCR)

主成分回归结合了主成分分析和线性回归,首先对特征进行PCA降维,再在降维后的特征上训练线性模型。适用于高维数据集中特征间高度相关的情况。

Python实现:

 

from sklearn.decomposition import PCA
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

# PCA降维
pca = PCA(n_components=10)
X_pca = pca.fit_transform(df.drop('target', axis=1))

# 线性回归
X_train, X_test, y_train, y_test = train_test_split(X_pca, df['target'], test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(X_train, y_train)

# 在测试集上进行预测
predictions = model.predict(X_test)

17. 稳定性选择

稳定性选择是一种基于模型的特征选择方法,通过多次随机取样、训练模型并评估特征选择的稳定性。它能够减少过拟合并提高模型的泛化能力。

Python实现:

 

from sklearn.linear_model import RandomizedLogisticRegression

# 使用随机逻辑回归进行稳定性选择
model = RandomizedLogisticRegression()
model.fit(df.drop('target', axis=1), df['target'])

# 被选择的特征
selected_features = df.columns[model.get_support()]
df_stability = df[selected_features]

18. F检验

F检验是特征选择的一种统计检验方法,它衡量的是每个特征与目标变量之间的方差比。如果某个特征的F值较大,表示其对目标变量有显著影响。

Python实现:

 

from sklearn.feature_selection import f_classif

# 使用F检验进行特征选择
F_values, p_values = f_classif(df.drop('target', axis=1), df['target'])

# 找出F值低的特征
low_fvalue_features = [feature for feature, f_value in zip(df.columns, F_values) if f_value < 1]
df = df.drop(columns=low_fvalue_features)

19. 基于最大相关最小冗余的特征选择 (MIC)

最大相关最小冗余方法关注特征与目标变量之间的最大相关性,且同时减少冗余特征。该方法在高维数据中特别有效。

Python实现:

 

from minepy import MINE

# 计算MIC
mic = MINE()
mic_values = []

for column in df.drop('target', axis=1).columns:
    mic.compute_score(df[column], df['target'])
    mic_values.append(mic.mic())

# 删除MIC低的特征
mic_threshold = 0.2
low_mic_features = [feature for feature, mic_value in zip(df.columns, mic_values) if mic_value < mic_threshold]
df = df.drop(columns=low_mic_features)

总结

特征工程是机器学习中的一项关键技术,它直接影响模型的性能和解释性。通过删除未使用的列、处理缺失值、选择相关性高的特征、控制共线性、利用模型系数和p值、以及应用自动化特征选择技术,我们可以显著提高模型的预测能力和泛化能力。每种方法都有其适用场景,选择合适的特征选择策略对于构建高效的机器学习模型至关重要。通过不断地实践和优化,特征工程可以帮助我们更好地理解和利用数据,从而在各种预测和分类任务中取得更好的效果。

来源:数据挖掘练习生

THE END