参数调优和特征工程,应该先哪个?
Posted
技术标签:
【中文标题】参数调优和特征工程,应该先哪个?【英文标题】:Parameter tuning and feature engineering, which one should be first? 【发布时间】:2016-08-12 23:22:10 【问题描述】:我正在尝试训练 SVM 分类器,但我对 ML 很陌生。我知道这里有两个步骤:参数调整和特征工程,但哪一个先进行?看来this的回答建议先做特征工程,对吗?如果正确,我是不是随机挑选一组 SVM 参数来做特征工程?
【问题讨论】:
【参考方案1】:您需要在训练模型之前创建特征和训练集,因此特征工程的第一次迭代必须在参数调整之前进行。然而,特征工程和参数调整都是迭代过程。例如,您可以使用您的第一个版本的特征来使用网格搜索(蛮力搜索最佳参数)来训练您的模型,然后您可以使用这些参数来尝试您的特征的不同排列。例如,您可以尝试使用特征 X 的一些变体,例如 log(X)、sqrt(X)、X^2 等,看看这是否能给您带来更好的结果。
我的典型流程是:
-
特色头脑风暴
功能创建
相关性分析
功能选择
特征变换(使它们与目标尽可能线性相关)
特征缩放到 1 均值单位方差
网格搜索以查找算法的初始超参数
测试替代特征转换的迭代过程
测试更精细的超参数的迭代过程
【讨论】:
【参考方案2】:所有机器学习模型的性能取决于我们如何从所有可用数据集中创建独特的特征
-
特征工程
然后检查特征之间的相关性以删除相关特征
参数调整
【讨论】:
【参考方案3】:应该首先完成特征工程。按照以下顺序进行
-
缺失值插补
变量编码
处理异常值
选择特征的线性模型假设
选择与标签最相关的特征
这些是特征工程的一些基本步骤。除此之外,这在很大程度上取决于您正在处理的数据集类型
【讨论】:
【参考方案4】:SVM(以及大多数其他 ML 方法)接受二维数字特征矩阵形式的输入,因此您必须将数据转换为该格式才能使用 SVM。因此,虽然您想在参数调整之前进行一些特征工程以确认您的管道按您认为的方式工作,但您不一定需要将两者完全分开。
如果您使用自动化或参数化的特征工程方法,那么该方法可以成为您的超参数调整过程的一部分。
其中一种方法是使用Featuretools,这是一个 Python 中的开源自动化特征工程库,与 Scikit-Learn 等机器学习库结合使用。
这是一个使用 Featuretools 中的演示数据集的管道,它在同一步骤中进行超参数调整和特征工程:
import featuretools as ft
from featuretools.primitives import (Sum, Max, Mean, Min,
Percentile, Day, Weekend, Weekday)
from featuretools.selection import remove_low_information_features
from itertools import combinations
from sklearn.metrics import f1_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler, Imputer
retail_data = ft.demo.load_retail(nrows=1000)
# predict each customer's country
labels = LabelEncoder().fit_transform(retail_data['customers'].df['Country'])
def score_pipeline(max_depth, agg_primitives, trans_primitives, C):
feature_matrix, feature_defs = ft.dfs(entityset=retail_data,
target_entity='customers',
ignore_variables='customers': ['Country'],
max_depth=max_depth,
agg_primitives=agg_primitives,
trans_primitives=trans_primitives,
verbose=True)
# one-hot encode to transform to numeric
feature_matrix, feature_defs = ft.encode_features(feature_matrix, feature_defs)
# remove feature with all nans or all single value
feature_matrix, feature_defs = remove_low_information_features(feature_matrix, feature_defs)
# impute missing values
imputer = Imputer(missing_values='NaN', strategy='mean', axis=0)
feature_matrix = imputer.fit_transform(feature_matrix)
model = SVC(C=C, verbose=True)
X_train, X_test, y_train, y_test = train_test_split(feature_matrix,
labels, test_size=0.1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
return f1_score(y_test, predictions, average='macro')
poss_agg_primitives = [Sum, Max, Mean, Min]
poss_trans_primitives = [Percentile, Day, Weekend, Weekday]
scores = []
for agg_primitives in combinations(poss_agg_primitives, 2):
for trans_primitives in combinations(poss_trans_primitives, 2):
for max_depth in range(1, 3):
for C in [0.01, 0.1, 1.0]:
score = score_pipeline(max_depth,
agg_primitives,
trans_primitives,
C)
scores.append(score)
print("Best score: :.3f".format(max(scores)))
【讨论】:
【参考方案5】:您必须先执行特征工程/特征选择。在调整值之前,您必须知道将使用哪些变量。
至于如何进行特征选择,这是另一个问题。您可以使用Principal Component Analysis、Singular Value Decomposition 或许多其他技术。这是一个活跃的研究领域,如果您只在 Google 上搜索,您会发现很多描述各种技术的论文。
This 是我最近阅读的一篇论文,它使用基于熵的技术进行特征选择。
【讨论】:
以上是关于参数调优和特征工程,应该先哪个?的主要内容,如果未能解决你的问题,请参考以下文章